"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "xinetd/main.c" between
xinetd-2.3.15.tar.gz and xinetd-2.3.15.4.tar.xz

About: xinetd is a secure replacement for inetd, the internet services daemon (openSUSE fork).

main.c  (xinetd-2.3.15):main.c  (xinetd-2.3.15.4.tar.xz)
skipping to change at line 26 skipping to change at line 26
#include "main.h" #include "main.h"
#include "init.h" #include "init.h"
#include "msg.h" #include "msg.h"
#include "internals.h" #include "internals.h"
#include "signals.h" #include "signals.h"
#include "service.h" #include "service.h"
#include "sconf.h" #include "sconf.h"
#include "xtimer.h" #include "xtimer.h"
#include "sensor.h" #include "sensor.h"
#include "xmdns.h" #ifdef HAVE_POLL
#include "xpoll.h"
#endif
#ifdef __GNUC__ #ifdef __GNUC__
__attribute__ ((noreturn)) __attribute__ ((noreturn))
#endif #endif
static void main_loop(void); static void main_loop(void);
static void find_bad_fd(void) ; static void find_bad_fd(void) ;
/* /*
* The following are the only global variables of this program * The following are the only global variables of this program
*/ */
struct program_state ps ; struct program_state ps ;
struct debug debug ; struct debug debug ;
char program_version[] = XINETD_VERSION ; char program_version[] = VERSION ;
int signals_pending[2] = {-1, -1} ; int signals_pending[2] = {-1, -1} ;
/* /*
* This is where the story starts... * This is where the story starts...
*/ */
int main( int argc, char *argv[] ) int main( int argc, char *argv[] )
{ {
const char *func = "main" ; const char *func = "main" ;
init_daemon( argc, argv ) ; init_daemon( argc, argv ) ;
#ifdef HAVE_MDNS
xinetd_mdns_init();
#endif
init_services() ; init_services() ;
/* Do the chdir after reading the config file. Relative path names /* Do the chdir after reading the config file. Relative path names
* will work better. * will work better.
*/ */
if (chdir("/") < 0) { if (chdir("/") < 0) {
msg(LOG_ERR, func, "Can't chdir to /: %m"); msg(LOG_ERR, func, "Can't chdir to /: %m");
} }
/* Print out all the options we're compiled with. Makes support /* Print out all the options we're compiled with. Makes support
* a tad easier. * a tad easier.
* Also, try to get them all into one syslog message for atomicity * Also, try to get them all into one syslog message for atomicity
*/ */
msg( LOG_NOTICE, func, "%s started with " msg( LOG_NOTICE, func, "%s started with "
#ifdef LIBWRAP #ifdef LIBWRAP
"libwrap " "libwrap "
#endif #endif
#ifdef HAVE_LOADAVG #ifdef HAVE_LOADAVG
"loadavg " "loadavg "
#endif #endif
#ifdef HAVE_MDNS
"mdns "
#endif
#ifdef HAVE_HOWL
"howl "
#endif
#ifdef HAVE_DNSREGISTRATION
"rendezvous "
#endif
#ifdef LABELED_NET #ifdef LABELED_NET
"labeled-networking " "labeled-networking "
#endif #endif
#if !defined(LIBWRAP) && !defined(HAVE_LOADAVG) && !defined(HAVE_MDNS) && !defin ed(HAVE_HOWL) && !defined(HAVE_DNSREGISTRATION) && !defined(LABELED_NET) #if !defined(LIBWRAP) && !defined(HAVE_LOADAVG) && !defined(LABELED_NET)
"no " "no "
#endif #endif
"options compiled in." "options compiled in."
, XINETD_VERSION ); , VERSION );
msg( LOG_NOTICE, func, "Started working: %d available service%s", msg( LOG_NOTICE, func, "Started working: %d available service%s",
ps.rws.available_services, ps.rws.available_services,
( ps.rws.available_services != 1 ) ? "s" : "" ) ; ( ps.rws.available_services != 1 ) ? "s" : "" ) ;
/* /*
* The reason for doing the setjmp here instead of in main_loop is * The reason for doing the setjmp here instead of in main_loop is
* that setjmp is not guaranteed to restore register values which * that setjmp is not guaranteed to restore register values which
* can cause a problem for register variables * can cause a problem for register variables
*/ */
skipping to change at line 120 skipping to change at line 110
* What main_loop does: * What main_loop does:
* *
* select on all active services * select on all active services
* for each socket where a request is pending * for each socket where a request is pending
* try to start a server * try to start a server
*/ */
static void main_loop(void) static void main_loop(void)
{ {
const char *func = "main_loop" ; const char *func = "main_loop" ;
struct timeval tv, *tvptr = NULL; struct timeval tv, *tvptr = NULL;
#ifdef HAVE_POLL
struct pollfd *signal_pfd;
FD_SET(signals_pending[0], &ps.rws.socket_mask); ps.rws.pfd_array[ps.rws.pfds_last].fd = signals_pending[0] ;
ps.rws.pfd_array[ps.rws.pfds_last].events = POLLIN ;
signal_pfd = &ps.rws.pfd_array[ps.rws.pfds_last] ;
ps.rws.pfds_last++;
#else
FD_SET(signals_pending[0], &ps.rws.socket_mask) ;
if ( signals_pending[0] > ps.rws.mask_max ) if ( signals_pending[0] > ps.rws.mask_max )
ps.rws.mask_max = signals_pending[0] ; ps.rws.mask_max = signals_pending[0] ;
if ( signals_pending[1] > ps.rws.mask_max ) #endif /* HAVE_POLL */
ps.rws.mask_max = signals_pending[1] ;
for ( ;; ) for ( ;; )
{ {
#ifndef HAVE_POLL
fd_set read_mask ; fd_set read_mask ;
#endif
int n_active ; int n_active ;
unsigned u ; unsigned u ;
if ( debug.on ) if ( debug.on )
msg( LOG_DEBUG, func, msg( LOG_DEBUG, func,
"active_services = %d", ps.rws.active_services ) ; "active_services = %d", ps.rws.active_services ) ;
/* get the next timer value, if there is one, and select for that time */ /* get the next timer value, if there is one, and select for that time */
if( (tv.tv_sec = xtimer_nexttime()) >= 0 ) { if( (tv.tv_sec = xtimer_nexttime()) >= 0 ) {
tv.tv_usec = 0; tv.tv_usec = 0;
tvptr = &tv; tvptr = &tv;
} else { } else {
tvptr = NULL; tvptr = NULL;
} }
#ifdef HAVE_POLL
n_active = poll( ps.rws.pfd_array, ps.rws.pfds_last,
tvptr == NULL ? -1 : tvptr->tv_sec*1000 ) ;
#else
read_mask = ps.rws.socket_mask ; read_mask = ps.rws.socket_mask ;
n_active = select( ps.rws.mask_max+1, &read_mask, n_active = select( ps.rws.mask_max+1, &read_mask,
FD_SET_NULL, FD_SET_NULL, tvptr ) ; FD_SET_NULL, FD_SET_NULL, tvptr ) ;
#endif
if ( n_active == -1 ) if ( n_active == -1 )
{ {
if ( errno == EINTR ) { if ( errno == EINTR ) {
continue ; continue ;
} else if ( errno == EBADF ) } else if ( errno == EBADF )
find_bad_fd() ; find_bad_fd() ;
continue ; continue ;
} }
else if ( n_active == 0 ) { else if ( n_active == 0 ) {
xtimer_poll(); xtimer_poll();
continue ; continue ;
} }
if ( debug.on ) if ( debug.on )
msg( LOG_DEBUG, func, "select returned %d", n_active ) ; msg( LOG_DEBUG, func, "select returned %d", n_active ) ;
xtimer_poll(); xtimer_poll();
if( FD_ISSET(signals_pending[0], &read_mask) ) { #ifdef HAVE_POLL
if ( POLLFD_REVENTS( signal_pfd ) )
{
if ( POLLFD_REVENTS( signal_pfd ) & (POLLERR | POLLHUP |
POLLNVAL) )
find_bad_fd();
else
{
check_pipe();
if ( --n_active == 0 )
continue ;
}
}
#else
if( FD_ISSET(signals_pending[0], &read_mask) )
{
check_pipe(); check_pipe();
if ( --n_active == 0 ) if ( --n_active == 0 )
continue ; continue ;
} }
#ifdef HAVE_MDNS
if( xinetd_mdns_poll() == 0 )
if ( --n_active == 0 )
continue ;
#endif #endif
for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ ) for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ )
{ {
struct service *sp ; struct service *sp ;
sp = SP( pset_pointer( SERVICES( ps ), u ) ) ; sp = SP( pset_pointer( SERVICES( ps ), u ) ) ;
if ( ! SVC_IS_ACTIVE( sp ) ) if ( ! SVC_IS_ACTIVE( sp ) )
continue ; continue ;
#ifdef HAVE_POLL
if ( SVC_REVENTS( sp ) )
{
if ( SVC_REVENTS( sp ) & (POLLERR | POLLHUP |
POLLNVAL) )
find_bad_fd();
else
{
svc_request( sp ) ;
if ( --n_active == 0 )
break ;
}
}
#else
if ( FD_ISSET( SVC_FD( sp ), &read_mask ) ) if ( FD_ISSET( SVC_FD( sp ), &read_mask ) )
{ {
svc_request( sp ) ; svc_request( sp ) ;
if ( --n_active == 0 ) if ( --n_active == 0 )
break ; break ;
} }
#endif
} }
if ( n_active > 0 ) if ( n_active > 0 )
msg( LOG_ERR, func, "%d descriptors still set", n_active ) ; msg( LOG_ERR, func, "%d descriptors still set", n_active ) ;
} }
} }
/* /*
* This function identifies if any of the fd's in the socket mask * This function identifies if any of the fd's in the socket mask
* is bad. We use it in case select(2) returns EBADF * is bad. We use it in case select(2) returns EBADF
* When we identify such a bad fd, we remove it from the mask * When we identify such a bad fd, we remove it from the mask
* and deactivate the service. * and deactivate the service.
*/ */
static void find_bad_fd(void) static void find_bad_fd(void)
{ {
int fd ; int fd ;
#ifndef HAVE_POLL
struct stat st ; struct stat st ;
#endif
unsigned bad_fd_count = 0 ; unsigned bad_fd_count = 0 ;
const char *func = "find_bad_fd" ; const char *func = "find_bad_fd" ;
#ifdef HAVE_POLL
for ( fd = 0 ; fd < ps.rws.pfds_last ; fd++ )
if ( ps.rws.pfd_array[fd].revents & ( POLLHUP|POLLNVAL|POLLERR ) )
{
#else
for ( fd = 0 ; (unsigned)fd < ps.ros.max_descriptors ; fd++ ) for ( fd = 0 ; (unsigned)fd < ps.ros.max_descriptors ; fd++ )
if ( FD_ISSET( fd, &ps.rws.socket_mask ) && fstat( fd, &st ) == -1 ) if ( FD_ISSET( fd, &ps.rws.socket_mask ) && fstat( fd, &st ) == -1 )
{ {
#endif
int found = FALSE ; int found = FALSE ;
unsigned u ; unsigned u ;
for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ ) for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ )
{ {
register struct service *sp ; register struct service *sp ;
sp = SP( pset_pointer( SERVICES( ps ), u ) ) ; sp = SP( pset_pointer( SERVICES( ps ), u ) ) ;
if ( ! SVC_IS_AVAILABLE( sp ) ) if ( ! SVC_IS_AVAILABLE( sp ) )
continue ; continue ;
if ( SVC_FD( sp ) == fd ) if ( SVC_FD( sp ) == fd )
{ {
msg( LOG_ERR, func, msg( LOG_ERR, func,
"file descriptor of service %s has been closed", "file descriptor of service %s has been closed",
SVC_ID( sp ) ) ; SVC_ID( sp ) ) ;
svc_deactivate( sp ) ; svc_deactivate( sp ) ;
found = TRUE ; found = TRUE ;
bad_fd_count++ ;
break ; break ;
} }
} }
if ( ! found ) if ( ! found )
{ {
#ifdef HAVE_POLL
ps.rws.pfd_array[fd].events = 0;
ps.rws.pfd_array[fd].fd = -1;
#else
FD_CLR( fd, &ps.rws.socket_mask ) ; FD_CLR( fd, &ps.rws.socket_mask ) ;
#endif
msg( LOG_ERR, func, msg( LOG_ERR, func,
"No active service for file descriptor %d\n", fd ) ; "No active service for file descriptor %d\n", fd ) ;
bad_fd_count++ ; bad_fd_count++ ;
} }
} }
if ( bad_fd_count == 0 ) if ( bad_fd_count == 0 )
msg( LOG_NOTICE, func, msg( LOG_NOTICE, func,
"select reported EBADF but no bad file descriptors were found" ) ; "select reported EBADF but no bad file descriptors were found" ) ;
} }
 End of changes. 24 change blocks. 
25 lines changed or deleted 67 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)