📄 main.c
字号:
{ for (i = NumClients, con = Clients; i > 0; i --, con ++) if (con->http.state == HTTP_WAITING) { CloseClient(con); con --; } else con->http.keep_alive = HTTP_KEEPALIVE_OFF; PauseListening(); } /* * Check for any active jobs... */ for (job = Jobs; job; job = job->next) if (job->state->values[0].integer == IPP_JOB_PROCESSING) break; /* * Restart if all clients are closed and all jobs finished, or * if the reload timeout has elapsed... */ if ((NumClients == 0 && (!job || NeedReload != RELOAD_ALL) ) || (time(NULL) - ReloadTime) >= ReloadTimeout) { if (!ReadConfiguration()) { syslog(LOG_LPR, "Unable to read configuration file \'%s\' - exiting!", ConfigurationFile); break; } } }#endif /* * Check for available input or ready output. If select() returns * 0 or -1, something bad happened and we should exit immediately. * * Note that we at least have one listening socket open at all * times. */ memcpy(input, InputSet, SetSize); memcpy(output, OutputSet, SetSize); timeout.tv_sec = select_timeout(fds); timeout.tv_usec = 0; if ((fds = select(MaxFDs, input, output, NULL, &timeout)) < 0) { char s[16384], /* String buffer */ *sptr; /* Pointer into buffer */ int slen; /* Length of string buffer */ /* * Got an error from select! */ if (errno == EINTR) /* Just interrupted by a signal */ continue; /* * Log all sorts of debug info to help track down the problem. */ LogMessage(L_EMERG, "select() failed - %s!", strerror(errno)); strcpy(s, "InputSet ="); slen = 10; sptr = s + 10; for (i = 0; i < MaxFDs; i ++) if (FD_ISSET(i, InputSet)) { snprintf(sptr, sizeof(s) - slen, " %d", i); slen += strlen(sptr); sptr += strlen(sptr); } LogMessage(L_EMERG, s); strcpy(s, "OutputSet ="); slen = 11; sptr = s + 11; for (i = 0; i < MaxFDs; i ++) if (FD_ISSET(i, OutputSet)) { snprintf(sptr, sizeof(s) - slen, " %d", i); slen += strlen(sptr); sptr += strlen(sptr); } LogMessage(L_EMERG, s); for (i = 0, con = Clients; i < NumClients; i ++, con ++) LogMessage(L_EMERG, "Clients[%d] = %d, file = %d, state = %d", i, con->http.fd, con->file, con->http.state); for (i = 0, lis = Listeners; i < NumListeners; i ++, lis ++) LogMessage(L_EMERG, "Listeners[%d] = %d", i, lis->fd);#if 0 LogMessage(L_EMERG, "BrowseSocket = %d", BrowseSocket); for (job = Jobs; job != NULL; job = job->next) LogMessage(L_EMERG, "Jobs[%d] = %d", job->id, job->pipe);#endif break; }#if 1 for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++) if (FD_ISSET(lis->fd, input)) AcceptClient(lis); for (i = NumClients, con = Clients; i > 0; i --, con ++) { /* * Process the input buffer... */ if (FD_ISSET(con->http.fd, input) || con->http.used) if (!ReadClient(con)) { con --; continue; } /* * Write data as needed... */ if (con->pipe_pid && FD_ISSET(con->file, input)) { /* * Keep track of pending input from the file/pipe separately * so that we don't needlessly spin on select() when the web * client is not ready to receive data... */ con->file_ready = 1;#ifdef DEBUG LogMessage(L_DEBUG2, "main: Data ready file %d!", con->file);#endif /* DEBUG */ if (!FD_ISSET(con->http.fd, output)) { LogMessage(L_DEBUG2, "main: Removing fd %d from InputSet...", con->file); FD_CLR(con->file, InputSet); } } if (FD_ISSET(con->http.fd, output) && (!con->pipe_pid || con->file_ready)) if (!WriteClient(con)) { con --; continue; } /* * Check the activity and close old clients... */ activity = time(NULL) - Timeout; if (con->http.activity < activity && !con->pipe_pid) { LogMessage(L_DEBUG, "Closing client %d after %d seconds of inactivity...", con->http.fd, Timeout); CloseClient(con); con --; continue; } }#else DEBUG_printf(("test\n")); if (FD_ISSET(lis->fd, input)) AcceptClient(lis); DEBUG_printf(("test [0]\n")); if (FD_ISSET(con->http.fd, input) || con->http.used) if (!ReadClient(con)) { con --; continue; } DEBUG_printf(("test[1]\n")); if (FD_ISSET(con->http.fd, output) && (!con->pipe_pid || con->file_ready)) if (!WriteClient(con)) { con --; continue; } /* * Check the activity and close old clients... */ activity = time(NULL) - Timeout; if (con->http.activity < activity && !con->pipe_pid) { LogMessage(L_DEBUG, "Closing client %d after %d seconds of inactivity...", con->http.fd, Timeout); CloseClient(con); con --; continue; }#endif#if 0 /* * Check for status info from job filters... */ for (job = Jobs; job != NULL; job = next) { next = job->next; if (job->pipe >= 0 && FD_ISSET(job->pipe, input)) { /* * Clear the input bit to avoid updating the next job * using the same status pipe file descriptor... */ FD_CLR(job->pipe, input); /* * Read any status messages from the filters... */ UpdateJob(job); } } /* * Update CGI messages as needed... */ if (CGIPipes[0] >= 0 && FD_ISSET(CGIPipes[0], input)) UpdateCGI(); /* * Update the browse list as needed... */ if (Browsing && BrowseProtocols) { if (BrowseSocket >= 0 && FD_ISSET(BrowseSocket, input)) UpdateCUPSBrowse(); if (PollPipe >= 0 && FD_ISSET(PollPipe, input)) UpdatePolling();#ifdef HAVE_LIBSLP if ((BrowseProtocols & BROWSE_SLP) && BrowseSLPRefresh <= time(NULL)) UpdateSLPBrowse();#endif /* HAVE_LIBSLP */ if (time(NULL) > browse_time) { SendBrowseList(); browse_time = time(NULL); } } /* * Update any pending multi-file documents... */ if ((time(NULL) - senddoc_time) >= 10) { CheckJobs(); senddoc_time = time(NULL); }#ifdef HAVE_MALLINFO /* * Log memory usage every minute... */ if ((time(NULL) - mallinfo_time) >= 60 && LogLevel >= L_DEBUG) { struct mallinfo mem; /* Malloc information */ mem = mallinfo(); LogMessage(L_DEBUG, "mallinfo: arena = %d, used = %d, free = %d\n", mem.arena, mem.usmblks + mem.uordblks, mem.fsmblks + mem.fordblks); mallinfo_time = time(NULL); }#endif /* HAVE_MALLINFO */ /* * Update the root certificate once every 5 minutes... */ if ((time(NULL) - RootCertTime) >= RootCertDuration && RootCertDuration) { /* * Update the root certificate... */ DeleteCert(0); AddCert(0, "root"); }#endif } /* * Log a message based on what happened... */ if (stop_scheduler) LogMessage(L_INFO, "Scheduler shutting down normally."); else LogMessage(L_ERROR, "Scheduler shutting down due to program error."); /* * Close all network clients and stop all jobs... */ StopServer();#if 0 StopAllJobs();#endif#ifdef __sgi /* * Remove the fake IRIX lpsched lock file, but only if the existing * file is not a FIFO which indicates that the real IRIX lpsched is * running... */ if (!stat("/var/spool/lp/FIFO", &statbuf)) if (!S_ISFIFO(statbuf.st_mode)) unlink("/var/spool/lp/SCHEDLOCK");#endif /* __sgi */ /* * Free memory used by FD sets and return... */ free(InputSet); free(OutputSet); free(input); free(output); return (!stop_scheduler);}/* * 'cupsdClosePipe()' - Close a pipe as necessary. */voidcupsdClosePipe(int *fds) /* I - Pipe file descriptors (2) */{ /* * Close file descriptors as needed... */ if (fds[0] >= 0) { close(fds[0]); fds[0] = -1; } if (fds[1] >= 0) { close(fds[1]); fds[1] = -1; }}/* * 'cupsdOpenPipe()' - Create a pipe which is closed on exec. */int /* O - 0 on success, -1 on error */cupsdOpenPipe(int *fds) /* O - Pipe file descriptors (2) */{ /* * Create the pipe... */ if (pipe(fds)) return (-1); /* * Set the "close on exec" flag on each end of the pipe... */ if (fcntl(fds[0], F_SETFD, fcntl(fds[0], F_GETFD) | FD_CLOEXEC)) { close(fds[0]); close(fds[1]); return (-1); } if (fcntl(fds[1], F_SETFD, fcntl(fds[1], F_GETFD) | FD_CLOEXEC)) { close(fds[0]); close(fds[1]); return (-1); } /* * Return 0 indicating success... */ return (0);}/* * 'CatchChildSignals()' - Catch SIGCHLD signals... */voidCatchChildSignals(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, sigchld_handler);#elif defined(HAVE_SIGACTION) memset(&action, 0, sizeof(action)); sigemptyset(&action.sa_mask); sigaddset(&action.sa_mask, SIGTERM); sigaddset(&action.sa_mask, SIGCHLD); action.sa_handler = sigchld_handler; sigaction(SIGCHLD, &action, NULL);#else signal(SIGCLD, sigchld_handler); /* No, SIGCLD isn't a typo... */#endif /* HAVE_SIGSET */}/* * 'ClearString()' - Clear a string. */voidClearString(char **s) /* O - String value */{ if (s && *s) { free(*s); *s = NULL; }}/* * 'HoldSignals()' - Hold child and termination signals. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -