📄 main.c
字号:
voidHoldSignals(void){#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) sigset_t newmask; /* New POSIX signal mask */#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ holdcount ++; if (holdcount > 1) return;#ifdef HAVE_SIGSET sighold(SIGTERM); sighold(SIGCHLD);#elif defined(HAVE_SIGACTION) sigemptyset(&newmask); sigaddset(&newmask, SIGTERM); sigaddset(&newmask, SIGCHLD); sigprocmask(SIG_BLOCK, &newmask, &holdmask);#endif /* HAVE_SIGSET */}/* * 'IgnoreChildSignals()' - Ignore SIGCHLD signals... * * We don't really ignore them, we set the signal handler to SIG_DFL, * since some OS's rely on signals for the wait4() function to work. */voidIgnoreChildSignals(void){#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) struct sigaction action; /* Actions for POSIX signals */#endif /* HAVE_SIGACTION && !HAVE_SIGSET */#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ sigset(SIGCHLD, SIG_DFL);#elif defined(HAVE_SIGACTION) memset(&action, 0, sizeof(action)); sigemptyset(&action.sa_mask); sigaddset(&action.sa_mask, SIGCHLD); action.sa_handler = SIG_DFL; sigaction(SIGCHLD, &action, NULL);#else signal(SIGCLD, SIG_DFL); /* No, SIGCLD isn't a typo... */#endif /* HAVE_SIGSET */}/* * 'ReleaseSignals()' - Release signals for delivery. */voidReleaseSignals(void){ holdcount --; if (holdcount > 0) return;#ifdef HAVE_SIGSET sigrelse(SIGTERM); sigrelse(SIGCHLD);#elif defined(HAVE_SIGACTION) sigprocmask(SIG_SETMASK, &holdmask, NULL);#endif /* HAVE_SIGSET */}/* * 'SetString()' - Set a string value. */voidSetString(char **s, /* O - New string */ const char *v) /* I - String value */{ if (!s || *s == v) return; if (*s) free(*s); if (v) *s = strdup(v); else *s = NULL;}/* * 'SetStringf()' - Set a formatted string value. */voidSetStringf(char **s, /* O - New string */ const char *f, /* I - Printf-style format string */ ...) /* I - Additional args as needed */{ char v[1024]; /* Formatting string value */ va_list ap; /* Argument pointer */ char *olds; /* Old string */ if (!s) return; olds = *s; if (f) { va_start(ap, f); vsnprintf(v, sizeof(v), f, ap); va_end(ap); *s = strdup(v); } else *s = NULL; if (olds) free(olds);}/* * 'parent_handler()' - Catch USR1/CHLD signals... */static voidparent_handler(int sig) /* I - Signal */{ /* * Store the signal we got from the OS and return... */ parent_signal = sig;}#if 0/* * 'process_children()' - Process all dead children... */static voidprocess_children(void){ int status; /* Exit status of child */ int pid; /* Process ID of child */ job_t *job; /* Current job */ int i; /* Looping var */ /* * Reset the dead_children flag... */ dead_children = 0; /* * Collect the exit status of some children... */#ifdef HAVE_WAITPID while ((pid = waitpid(-1, &status, WNOHANG)) > 0)#elif defined(HAVE_WAIT3) while ((pid = wait3(&status, WNOHANG, NULL)) > 0)#else if ((pid = wait(&status)) > 0)#endif /* HAVE_WAITPID */ { DEBUG_printf(("process_children: pid = %d, status = %d\n", pid, status)); /* * Ignore SIGTERM errors - that comes when a job is cancelled... */ if (status == SIGTERM) status = 0; if (status) { if (WIFSTOPPED(status)) LogMessage(L_ERROR, "PID %d crashed on signal %d!", pid, WSTOPSIG(status)); else LogMessage(L_ERROR, "PID %d stopped with status %d!", pid, WEXITSTATUS(status)); if (LogLevel < L_DEBUG) LogMessage(L_INFO, "Hint: Try setting the LogLevel to \"debug\" to find out more."); } else LogMessage(L_DEBUG2, "PID %d exited with no errors.", pid); /* * Delete certificates for CGI processes... */ if (pid) DeleteCert(pid); /* * Lookup the PID in the jobs list... */ for (job = Jobs; job != NULL; job = job->next) if (job->state != NULL && job->state->values[0].integer == IPP_JOB_PROCESSING) { for (i = 0; job->procs[i]; i ++) if (job->procs[i] == pid) break; if (job->procs[i]) { /* * OK, this process has gone away; what's left? */ job->procs[i] = -pid; if (status && job->status >= 0) { /* * An error occurred; save the exit status so we know to stop * the printer or cancel the job when all of the filters finish... * * A negative status indicates that the backend failed and the * printer needs to be stopped. */ if (!job->procs[i + 1]) job->status = -status; /* Backend failed */ else job->status = status; /* Filter failed */ } break; } } }}#endif/* * 'sigchld_handler()' - Handle 'child' signals from old processes. */static voidsigchld_handler(int sig) /* I - Signal number */{ (void)sig; /* * Flag that we have dead children... */ dead_children = 1; /* * Reset the signal handler as needed... */#if !defined(HAVE_SIGSET) && !defined(HAVE_SIGACTION) signal(SIGCLD, sigchld_handler);#endif /* !HAVE_SIGSET && !HAVE_SIGACTION */}/* * 'sighup_handler()' - Handle 'hangup' signals to reconfigure the scheduler. */static voidsighup_handler(int sig) /* I - Signal number */{ (void)sig; NeedReload = RELOAD_ALL; ReloadTime = time(NULL);#if !defined(HAVE_SIGSET) && !defined(HAVE_SIGACTION) signal(SIGHUP, sighup_handler);#endif /* !HAVE_SIGSET && !HAVE_SIGACTION */}/* * 'sigterm_handler()' - Handle 'terminate' signals that stop the scheduler. */static voidsigterm_handler(int sig) /* I - Signal */{ (void)sig; /* remove compiler warnings... */ /* * Flag that we should stop and return... */ stop_scheduler = 1;}/* * 'select_timeout()' - Calculate the select timeout value. * */static long /* O - Number of seconds */select_timeout(int fds) /* I - Number of ready descriptors select returned */{ int i; /* Looping var */ long timeout; /* Timeout for select */ time_t now; /* Current time */ client_t *con; /* Client information */ const char *why; /* Debugging aid */#if 0 printer_t *p; /* Printer information */ job_t *job; /* Job information */#endif /* * Check to see if any of the clients have pending data to be * processed; if so, the timeout should be 0... */ for (i = NumClients, con = Clients; i > 0; i --, con ++) if (con->http.used > 0) return (0); /* * If select has been active in the last second (fds != 0) or we have * many resources in use then don't bother trying to optimize the * timeout, just make it 1 second. */ if (fds || NumClients > 50) return (1); /* * Otherwise, check all of the possible events that we need to wake for... */ now = time(NULL); timeout = now + 86400; /* 86400 == 1 day */ why = "do nothing"; /* * Check the activity and close old clients... */ for (i = NumClients, con = Clients; i > 0; i --, con ++) if ((con->http.activity + Timeout) < timeout) { timeout = con->http.activity + Timeout; why = "timeout a client connection"; } #if 0 /* * Update the browse list as needed... */ if (Browsing && BrowseProtocols) {#ifdef HAVE_LIBSLP if ((BrowseProtocols & BROWSE_SLP) && (BrowseSLPRefresh < timeout)) { timeout = BrowseSLPRefresh; why = "update SLP browsing"; }#endif /* HAVE_LIBSLP */ if (BrowseProtocols & BROWSE_CUPS) { for (p = Printers; p != NULL; p = p->next) { if (p->type & CUPS_PRINTER_REMOTE) { if ((p->browse_time + BrowseTimeout) < timeout) { timeout = p->browse_time + BrowseTimeout; why = "browse timeout a printer"; } } else if (!(p->type & CUPS_PRINTER_IMPLICIT)) { if (BrowseInterval && (p->browse_time + BrowseInterval) < timeout) { timeout = p->browse_time + BrowseInterval; why = "send browse update"; } } } } } /* * Check for any active jobs... */ if (timeout > (now + 10)) { for (job = Jobs; job != NULL; job = job->next) if (job->state->values[0].integer <= IPP_JOB_PROCESSING) { timeout = now + 10; why = "process active jobs"; break; } }#ifdef HAVE_MALLINFO /* * Log memory usage every minute... */ if (LogLevel >= L_DEBUG && (mallinfo_time + 60) < timeout) { timeout = mallinfo_time + 60; why = "display memory usage"; }#endif /* HAVE_MALLINFO */ /* * Update the root certificate when needed... */ if (RootCertDuration && (RootCertTime + RootCertDuration) < timeout) { timeout = RootCertTime + RootCertDuration; why = "update root certificate"; }#endif /* * Adjust from absolute to relative time. If p->browse_time above * was 0 then we can end up with a negative value here, so check. * We add 1 second to the timeout since events occur after the * timeout expires, and limit the timeout to 86400 seconds (1 day) * to avoid select() timeout limits present on some operating * systems... */ timeout = timeout - now + 1; if (timeout < 1) timeout = 1; else if (timeout > 86400) timeout = 86400; /* * Log and return the timeout value... */ LogMessage(L_DEBUG2, "select_timeout: %ld seconds to %s", timeout, why); return (timeout);}/* * 'usage()' - Show scheduler usage. */static voidusage(void){ fputs("Usage: cupsd [-c config-file] [-f] [-F]\n", stderr); exit(1);}/* * End of "$Id: main.c,v 1.128 2005/01/03 19:29:59 mike Exp $". */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -