From: Zoran V. <vas...@us...> - 2005-10-22 08:26:33
|
Update of /cvsroot/naviserver/naviserver/nsd In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21111/nsd Modified Files: nsmain.c Log Message: Initialize Tcl library in the server process only. Fix the broken SIGINT hadling which allowed us to CTRL-C the booting process at any time. Index: nsmain.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/nsmain.c,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** nsmain.c 16 Oct 2005 08:52:48 -0000 1.24 --- nsmain.c 22 Oct 2005 08:26:25 -0000 1.25 *************** *** 158,166 **** /* * When run as a Win32 service, Ns_Main will be re-entered ! * in the service main thread. In this case, jump past ! * the point where the initial thread blocked when ! * connected to the service control manager. */ ! #ifdef _WIN32 if (mode == 'S') { --- 158,166 ---- /* * When run as a Win32 service, Ns_Main will be re-entered ! * in the service main thread. In this case, jump past the ! * point where the initial thread blocked when connected to ! * the service control manager. */ ! #ifdef _WIN32 if (mode == 'S') { *************** *** 169,195 **** #endif - /* - * Set up configuration defaults and initial values. - */ - nsconf.argv0 = argv[0]; - /* - * File descriptors 1 and 2 may not be open if the server - * is starting from /etc/init. If so, open them on /dev/null - * as well because the server will assume they're open during - * initialization. In particular, the log file will be duped - * to fd's 1 and 2. - */ - - fd = open(DEVNULL, O_WRONLY); - if (fd > 0 && fd != 1) { - close(fd); - } - fd = open(DEVNULL, O_WRONLY); - if (fd > 0 && fd != 2) { - close(fd); - } - /* * Parse the command line arguments. --- 169,174 ---- *************** *** 305,314 **** UsageError("required -t <config> option not specified"); } - if (mode != 'c') { - /* - * The server requires file descriptor 0 be open on /dev/null to - * ensure the server never blocks reading stdin. - */ fd = open(DEVNULL, O_RDONLY); if (fd > 0) { --- 284,295 ---- UsageError("required -t <config> option not specified"); } + /* + * For the non-interactive operation, the server requires file + * descriptor 0 be open on NUL device to ensure it never blocks + * while reading stdin. + */ + + if (mode != 'c') { fd = open(DEVNULL, O_RDONLY); if (fd > 0) { *************** *** 318,335 **** } /* ! * Find the absolute config pathname and read the config data ! * before a possible chroot(). The call to Tcl_FindExecutable() ! * must be done first in order to setup Tcl library, otherwise ! * the FindConfig() which uses TclVFS wrappers will fail. */ Tcl_FindExecutable(argv[0]); - nsconf.nsd = (char *) Tcl_GetNameOfExecutable(); nsconf.config = FindConfig(nsconf.config); config = NsConfigRead(nsconf.config); ! ! #ifndef _WIN32 /* --- 299,338 ---- } + /* + * File descriptors 1 and 2 may not be open if the server is + * starting from /etc/init. If so, open them on NUL device + * as well, because the server will assume they're open during + * initialization. In particular, the log file will be duped + * to fd's 1 and 2. + */ + + fd = open(DEVNULL, O_WRONLY); + if (fd > 0 && fd != 1) { + close(fd); + } + fd = open(DEVNULL, O_WRONLY); + if (fd > 0 && fd != 2) { + close(fd); + } + + #ifdef _WIN32 + /* ! * The call to Tcl_FindExecutable() must be done before we ever ! * attempt any file-related operation, because it is initializing ! * the Tcl library and virtual filesystem interface. */ Tcl_FindExecutable(argv[0]); nsconf.nsd = (char *) Tcl_GetNameOfExecutable(); + + /* + * Locate and read the configuration file for later evaluation. + */ + nsconf.config = FindConfig(nsconf.config); config = NsConfigRead(nsconf.config); ! ! #else /* *************** *** 389,395 **** * he/she should have used "-u" to give the actual user * to run as (may be root as well) and optionally "-g" ! * to set the process group. We're picky about the group ! * though. If we were not able to figure out to which ! * group the user belongs to, we will abort, no mercy. */ --- 392,396 ---- * he/she should have used "-u" to give the actual user * to run as (may be root as well) and optionally "-g" ! * to set the process group. */ *************** *** 403,406 **** --- 404,448 ---- } } + + /* + * Fork into the background + */ + + if (mode == 0 || mode == 'w') { + i = ns_fork(); + if (i == -1) { + Ns_Fatal("nsmain: fork() failed: '%s'", strerror(errno)); + } + if (i > 0) { + return 0; + } + setsid(); /* Detach from the controlling terminal device */ + } + + /* + * For watchdog mode, start the watchdog/server process pair. + * The watchdog will monitor and restart the server unless the + * server exits gracefully, either by calling exit(0) or get + * signalled by the SIGTERM signal. + * The watchdog itself will exit when the server exits gracefully, + * or, when get signalled by the SIGTERM signal. In the latter + * case, watchdog will pass the SIGTERM to the server, so both of + * them will gracefully exit. + */ + + if (mode == 'w') { + if (StartWatchedServer() == 0) { + return 0; + } + } else { + nsconf.pid = getpid(); + } + + /* + * Block all signals for the duration of startup to ensure any new + * threads inherit the blocked state. + */ + + NsBlockSignals(debug); /* *************** *** 427,469 **** } } ! /* ! * Fork us into the background */ ! ! if (mode == 0 || mode == 'w') { ! i = ns_fork(); ! if (i == -1) { ! Ns_Fatal("nsmain: fork() failed: '%s'", strerror(errno)); ! } ! if (i > 0) { ! return 0; ! } ! setsid(); /* Detach from the controlling terminal device */ ! } ! /* ! * Optionally, start the watchdog/server process pair. ! * The watchdog process will monitor and restart the server unless ! * the server exits gracefully, either by calling exit(0) or get ! * signalled by the SIGTERM signal. ! * The watchdog process itself will exit when the server process ! * exits gracefully, or, when get signalled by the SIGTERM signal. ! * In the latter case, watchdog will pass the SIGTERM to the server ! * process, so both of them will gracefully terminate. */ ! if (mode == 'w') { ! if (StartWatchedServer() == 0) { ! return 0; ! } ! } else { ! nsconf.pid = getpid(); ! } ! /* * Pre-bind any sockets now, before a possible setuid from root ! * or chroot which may hide /etc/resolv.conf required to ! * resolve name-based addresses. */ --- 469,493 ---- } } ! /* ! * The call to Tcl_FindExecutable() must be done before we ever ! * attempt any file-related operation, because it is initializing ! * the Tcl library and virtual filesystem interface. */ ! ! Tcl_FindExecutable(argv[0]); ! nsconf.nsd = (char *) Tcl_GetNameOfExecutable(); ! /* ! * Locate and read the configuration file for later evaluation. */ ! nsconf.config = FindConfig(nsconf.config); ! config = NsConfigRead(nsconf.config); ! /* * Pre-bind any sockets now, before a possible setuid from root ! * or chroot which may hide /etc/resolv.conf required to resolve ! * name-based addresses. */ *************** *** 520,541 **** * get core files. */ ! if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) { Ns_Fatal("nsmain: prctl(PR_SET_DUMPABLE) failed: '%s'", strerror(errno)); } - #endif - - /* - * Finally, block all signals for the duration of startup to ensure any - * new threads inherit the blocked state. - */ ! NsBlockSignals(debug); #endif /* _WIN32 */ /* ! * Initialize Tcl and eval the config file. */ --- 544,559 ---- * get core files. */ ! if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) { Ns_Fatal("nsmain: prctl(PR_SET_DUMPABLE) failed: '%s'", strerror(errno)); } ! #endif /* __linux */ #endif /* _WIN32 */ /* ! * Evaluate the config file. */ *************** *** 717,720 **** --- 735,739 ---- if (mode == 'c') { + /* * Initialize Tcl and start interpreting commands. |