static int daemon_mode(void) { int bgpid; #ifdef HAVE_SIGACTION struct sigaction sa, osa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = parent_exit; sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGQUIT); sigaction(SIGQUIT, &sa, &osa); #else /* not HAVE_SIGACTION */ signal(SIGQUIT, parent_exit); #endif /* not HAVE_SIGACTION */ bgpid = background(); if (bgpid != 0) { /* * Now wait for the automount points to * complete. */ for (;;) pause(); /* should never reach here */ } #ifdef HAVE_SIGACTION sigaction(SIGQUIT, &osa, NULL); #else /* not HAVE_SIGACTION */ signal(SIGQUIT, SIG_DFL); #endif /* not HAVE_SIGACTION */ /* * Record our pid to make it easier to kill the correct amd. */ if (gopt.flags & CFM_PRINT_PID) { if (STREQ(gopt.pid_file, "/dev/stdout")) { printf("%ld\n", (long) am_mypid); /* flush stdout, just in case */ fflush(stdout); } else { FILE *f; mode_t prev_umask = umask(0022); /* set secure temporary umask */ f = fopen(gopt.pid_file, "w"); if (f) { fprintf(f, "%ld\n", (long) am_mypid); (void) fclose(f); } else { fprintf(stderr, "cannot open %s (errno=%d)\n", gopt.pid_file, errno); } umask(prev_umask); /* restore umask */ } } /* * Pretend we are in the foreground again */ foreground = 1; /* * Dissociate from the controlling terminal */ amu_release_controlling_tty(); return getppid(); }
static void hlfsd_init(void) { int child = 0; #ifdef HAVE_SIGACTION struct sigaction sa; #endif /* HAVE_SIGACTION */ /* * Initialize file handles. */ plog(XLOG_INFO, "initializing hlfsd file handles"); hlfsd_init_filehandles(); /* * If -D daemon then we must fork. */ if (amuDebug(D_DAEMON)) child = fork(); if (child < 0) fatal("fork: %m"); if (child != 0) { /* parent process - save child pid */ masterpid = child; am_set_mypid(); /* for logging routines */ return; } /* * CHILD CODE: * initialize server */ plog(XLOG_INFO, "initializing home directory database"); plt_init(); /* initialize database */ plog(XLOG_INFO, "home directory database initialized"); masterpid = serverpid = am_set_mypid(); /* for logging routines */ /* * SIGALRM/SIGHUP: reload password database if timer expired * or user sent HUP signal. */ #ifdef HAVE_SIGACTION sa.sa_handler = reload; sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGALRM); sigaddset(&(sa.sa_mask), SIGHUP); sigaction(SIGALRM, &sa, NULL); sigaction(SIGHUP, &sa, NULL); #else /* not HAVE_SIGACTION */ signal(SIGALRM, reload); signal(SIGHUP, reload); #endif /* not HAVE_SIGACTION */ /* * SIGTERM: cleanup and exit. */ #ifdef HAVE_SIGACTION sa.sa_handler = cleanup; sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGTERM); sigaction(SIGTERM, &sa, NULL); #else /* not HAVE_SIGACTION */ signal(SIGTERM, cleanup); #endif /* not HAVE_SIGACTION */ /* * SIGCHLD: interlock synchronization and testing */ #ifdef HAVE_SIGACTION sa.sa_handler = interlock; sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGCHLD); sigaction(SIGCHLD, &sa, NULL); #else /* not HAVE_SIGACTION */ signal(SIGCHLD, interlock); #endif /* not HAVE_SIGACTION */ /* * SIGUSR1: dump internal hlfsd maps/cache to file */ #ifdef HAVE_SIGACTION # if defined(DEBUG) || defined(DEBUG_PRINT) sa.sa_handler = plt_print; # else /* not defined(DEBUG) || defined(DEBUG_PRINT) */ sa.sa_handler = SIG_IGN; # endif /* not defined(DEBUG) || defined(DEBUG_PRINT) */ sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGUSR1); sigaction(SIGUSR1, &sa, NULL); #else /* not HAVE_SIGACTION */ # if defined(DEBUG) || defined(DEBUG_PRINT) signal(SIGUSR1, plt_print); # else /* not defined(DEBUG) || defined(DEBUG_PRINT) */ signal(SIGUSR1, SIG_IGN); # endif /* not defined(DEBUG) || defined(DEBUG_PRINT) */ #endif /* not HAVE_SIGACTION */ if (setitimer(ITIMER_REAL, &reloadinterval, (struct itimerval *) NULL) < 0) fatal("setitimer: %m"); clocktime(&startup); /* * If -D daemon, then start serving here in the child, * and the parent will exit. But if -D nodaemon, then * skip this code and make sure svc_run is entered elsewhere. */ if (amuDebug(D_DAEMON)) { /* * Dissociate from the controlling terminal */ amu_release_controlling_tty(); /* * signal parent we are ready. parent should * mount(2) and die. */ if (kill(getppid(), SIGUSR2) < 0) fatal("kill: %m"); plog(XLOG_INFO, "starting svc_run"); svc_run(); cleanup(0); /* should never happen, just in case */ } }