diff options
Diffstat (limited to 'scheduler/main.c')
-rw-r--r-- | scheduler/main.c | 640 |
1 files changed, 217 insertions, 423 deletions
diff --git a/scheduler/main.c b/scheduler/main.c index 434cacf89..8591cc0f3 100644 --- a/scheduler/main.c +++ b/scheduler/main.c @@ -1,9 +1,9 @@ /* - * "$Id: main.c 6090 2006-11-14 16:35:27Z mike $" + * "$Id: main.c 6326 2007-03-11 17:50:18Z mike $" * * Scheduler main loop for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -32,10 +32,9 @@ * cupsdSetStringf() - Set a formatted string value. * launchd_checkin() - Check-in with launchd and collect the * listening fds. + * launchd_checkout() - Check-out with launchd. * launchd_create_dict() - Create a dictionary representing the launchd * config file org.cups.cupsd.plist. - * launchd_reload() - Tell launchd to reload the configuration - * file to pick up the new listening directives. * launchd_sync_conf() - Re-write the launchd config file * org.cups.cupsd.plist based on cupsd.conf. * parent_handler() - Catch USR1/CHLD signals... @@ -62,6 +61,17 @@ #ifdef HAVE_LAUNCH_H # include <launch.h> # include <libgen.h> +# define CUPS_KEEPALIVE CUPS_STATEDIR "/org.cups.cupsd" + /* Name of the launchd KeepAlive file */ +# ifndef LAUNCH_JOBKEY_KEEPALIVE +# define LAUNCH_JOBKEY_KEEPALIVE "KeepAlive" +# endif /* !LAUNCH_JOBKEY_KEEPALIVE */ +# ifndef LAUNCH_JOBKEY_PATHSTATE +# define LAUNCH_JOBKEY_PATHSTATE "PathState" +# endif /* !LAUNCH_JOBKEY_PATHSTATE */ +# ifndef LAUNCH_JOBKEY_SERVICEIPC +# define LAUNCH_JOBKEY_SERVICEIPC "ServiceIPC" +# endif /* !LAUNCH_JOBKEY_SERVICEIPC */ #endif /* HAVE_LAUNCH_H */ #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO) @@ -78,8 +88,8 @@ #ifdef HAVE_LAUNCHD static void launchd_checkin(void); +static void launchd_checkout(void); static CFDictionaryRef launchd_create_dict(void); -static void launchd_reload(void); static int launchd_sync_conf(void); #endif /* HAVE_LAUNCHD */ static void parent_handler(int sig); @@ -126,8 +136,6 @@ main(int argc, /* I - Number of command-line args */ char *opt; /* Option character */ int fg; /* Run in the foreground */ int fds; /* Number of ready descriptors */ - fd_set *input, /* Input set for select() */ - *output; /* Output set for select() */ cupsd_client_t *con; /* Current client */ cupsd_job_t *job; /* Current job */ cupsd_listener_t *lis; /* Current listener */ @@ -136,14 +144,11 @@ main(int argc, /* I - Number of command-line args */ browse_time, /* Next browse send time */ senddoc_time, /* Send-Document time */ expire_time, /* Subscription expire time */ -#ifndef __APPLE__ - netif_time, /* Network interface poll time */ -#endif /* !__APPLE__ */ mallinfo_time; /* Malloc information time */ size_t string_count, /* String count */ alloc_bytes, /* Allocated string bytes */ total_bytes; /* Total string bytes */ - struct timeval timeout; /* select() timeout */ + long timeout; /* Timeout for cupsdDoSelect() */ struct rlimit limit; /* Runtime limit */ #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) struct sigaction action; /* Actions for POSIX signals */ @@ -372,33 +377,23 @@ main(int argc, /* I - Number of command-line args */ getrlimit(RLIMIT_NOFILE, &limit); +#if !defined(HAVE_POLL) && !defined(HAVE_EPOLL) && !defined(HAVE_KQUEUE) if (limit.rlim_max > FD_SETSIZE) MaxFDs = FD_SETSIZE; else +#endif /* !HAVE_POLL && !HAVE_EPOLL && !HAVE_KQUEUE */ +#ifdef RLIM_INFINITY + if (limit.rlim_max == RLIM_INFINITY) + MaxFDs = 16384; + else +#endif /* RLIM_INFINITY */ MaxFDs = limit.rlim_max; limit.rlim_cur = MaxFDs; setrlimit(RLIMIT_NOFILE, &limit); - /* - * Allocate memory for the input and output sets... - */ - - SetSize = (MaxFDs + 31) / 8 + 4; - if (SetSize < sizeof(fd_set)) - SetSize = sizeof(fd_set); - - InputSet = (fd_set *)calloc(1, SetSize); - OutputSet = (fd_set *)calloc(1, SetSize); - input = (fd_set *)calloc(1, SetSize); - output = (fd_set *)calloc(1, SetSize); - - if (InputSet == NULL || OutputSet == NULL || input == NULL || output == NULL) - { - syslog(LOG_LPR, "Unable to allocate memory for select() sets - exiting!"); - return (1); - } + cupsdStartSelect(); /* * Read configuration... @@ -415,22 +410,15 @@ main(int argc, /* I - Number of command-line args */ if (Launchd) { /* - * If we were started by launchd make sure the cupsd plist file contains the - * same listeners as cupsd.conf; If it didn't then reload it before getting - * the list of listening file descriptors... + * If we were started by launchd, make sure the cupsd plist file contains + * the same listeners as cupsd.conf. */ - if (launchd_sync_conf()) - { - launchd_reload(); - - /* - * Until rdar://3854821 is fixed we have to exit after the reload... - */ + launchd_sync_conf(); - cupsdLogMessage(CUPSD_LOG_DEBUG2, "Exiting on launchd_reload"); - exit(0); - } + /* + * Then get the file descriptors from launchd... + */ launchd_checkin(); } @@ -551,9 +539,6 @@ main(int argc, /* I - Number of command-line args */ senddoc_time = time(NULL); expire_time = time(NULL); fds = 1; -#ifndef __APPLE__ - netif_time = 0; -#endif /* !__APPLE__ */ while (!stop_scheduler) { @@ -632,19 +617,7 @@ main(int argc, /* I - Number of command-line args */ #if HAVE_LAUNCHD if (Launchd) { - if (launchd_sync_conf()) - { - launchd_reload(); - - /* - * Until rdar://3854821 is fixed we have to exit after the reload... - */ - - cupsdLogMessage(CUPSD_LOG_DEBUG2, "Exiting on launchd_reload"); - stop_scheduler = 1; - break; - } - + launchd_sync_conf(); launchd_checkin(); } #endif /* HAVE_LAUNCHD */ @@ -658,18 +631,15 @@ main(int argc, /* I - Number of command-line args */ } /* - * Check for available input or ready output. If select() returns - * 0 or -1, something bad happened and we should exit immediately. + * Check for available input or ready output. If cupsdDoSelect() + * 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; + timeout = select_timeout(fds); #if HAVE_LAUNCHD /* @@ -678,71 +648,40 @@ main(int argc, /* I - Number of command-line args */ * inactivity... */ - if (timeout.tv_sec == 86400 && Launchd && LaunchdTimeout && !NumPolled && - (!Browsing || !(BrowseLocalProtocols & BROWSE_DNSSD) || - cupsArrayCount(Printers) == 0)) + if (timeout == 86400 && Launchd && LaunchdTimeout && !NumPolled && + (!Browsing || + (!BrowseRemoteProtocols && + (!NumBrowsers || !BrowseLocalProtocols || + cupsArrayCount(Printers) == 0)))) { - timeout.tv_sec = LaunchdTimeout; + timeout = LaunchdTimeout; launchd_idle_exit = 1; } else launchd_idle_exit = 0; #endif /* HAVE_LAUNCHD */ - if (timeout.tv_sec < 86400) /* Only use timeout for < 1 day */ - fds = select(MaxFDs, input, output, NULL, &timeout); - else - fds = select(MaxFDs, input, output, NULL, NULL); - - if (fds < 0) + if ((fds = cupsdDoSelect(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 */ +#ifdef HAVE_DNSSD + cupsd_printer_t *p; /* Current printer */ +#endif /* HAVE_DNSSD */ + + + if (errno == EINTR) /* Just interrupted by a signal */ continue; /* * Log all sorts of debug info to help track down the problem. */ - cupsdLogMessage(CUPSD_LOG_EMERG, "select() failed - %s!", + cupsdLogMessage(CUPSD_LOG_EMERG, "cupsdDoSelect() 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); - } - - cupsdLogMessage(CUPSD_LOG_EMERG, "%s", 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); - } - - cupsdLogMessage(CUPSD_LOG_EMERG, "%s", s); - for (i = 0, con = (cupsd_client_t *)cupsArrayFirst(Clients); con; i ++, con = (cupsd_client_t *)cupsArrayNext(Clients)) @@ -772,6 +711,15 @@ main(int argc, /* I - Number of command-line args */ job->status_buffer ? job->status_buffer->fd : -1, job->print_pipes[0], job->print_pipes[1], job->back_pipes[0], job->back_pipes[1]); + +#ifdef HAVE_DNSSD + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + cupsdLogMessage(CUPSD_LOG_EMERG, "printer[%s] %d", p->name, + p->dnssd_ipp_fd); +#endif /* HAVE_DNSSD */ + break; } @@ -794,67 +742,6 @@ main(int argc, /* I - Number of command-line args */ #endif /* HAVE_LAUNCHD */ /* - * Check for status info from job filters... - */ - - for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs); - job; - job = (cupsd_job_t *)cupsArrayNext(ActiveJobs)) - if (job->status_buffer && FD_ISSET(job->status_buffer->fd, input)) - { - /* - * Clear the input bit to avoid updating the next job - * using the same status pipe file descriptor... - */ - - FD_CLR(job->status_buffer->fd, input); - - /* - * Read any status messages from the filters... - */ - - cupsdUpdateJob(job); - } - - /* - * Update CGI messages as needed... - */ - - if (CGIPipes[0] >= 0 && FD_ISSET(CGIPipes[0], input)) - cupsdUpdateCGI(); - - /* - * Handle system management events as needed... - */ - -#ifdef __APPLE__ - /* - * Mac OS X provides the SystemConfiguration framework for system - * configuration change events... - */ - - if (SysEventPipes[0] >= 0 && FD_ISSET(SysEventPipes[0], input)) - cupsdUpdateSystemMonitor(); -#else - /* - * All other operating systems need to poll for changes... - */ - - if ((current_time - netif_time) >= 60) - { - NetIFUpdate = 1; - netif_time = current_time; - } -#endif /* __APPLE__ */ - - /* - * Update notifier messages as needed... - */ - - if (NotifierPipes[0] >= 0 && FD_ISSET(NotifierPipes[0], input)) - cupsdUpdateNotifierStatus(); - - /* * Expire subscriptions and unload completed jobs as needed... */ @@ -872,14 +759,8 @@ main(int argc, /* I - Number of command-line args */ * Update the browse list as needed... */ - if (Browsing && BrowseRemoteProtocols) + if (Browsing) { - if (BrowseSocket >= 0 && FD_ISSET(BrowseSocket, input)) - cupsdUpdateCUPSBrowse(); - - if (PollPipe >= 0 && FD_ISSET(PollPipe, input)) - cupsdUpdatePolling(); - #ifdef HAVE_LIBSLP if ((BrowseRemoteProtocols & BROWSE_SLP) && BrowseSLPRefresh <= current_time) @@ -900,17 +781,20 @@ main(int argc, /* I - Number of command-line args */ } /* - * Check for new connections on the "listen" sockets... + * Update the root certificate once every 5 minutes if we have client + * connections... */ - for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); - lis; - lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) - if (lis->fd >= 0 && FD_ISSET(lis->fd, input)) - { - FD_CLR(lis->fd, input); - cupsdAcceptClient(lis); - } + if ((current_time - RootCertTime) >= RootCertDuration && RootCertDuration && + !RunUser && cupsArrayCount(Clients)) + { + /* + * Update the root certificate... + */ + + cupsdDeleteCert(0); + cupsdAddCert(0, "root"); + } /* * Check for new data on the client sockets... @@ -921,61 +805,13 @@ main(int argc, /* I - Number of command-line args */ con = (cupsd_client_t *)cupsArrayNext(Clients)) { /* - * Process the input buffer... - */ - - if (FD_ISSET(con->http.fd, input) || con->http.used) - { - int fd = con->file; - - - FD_CLR(con->http.fd, input); - - if (!cupsdReadClient(con)) - { - if (fd >= 0) - FD_CLR(fd, input); - - continue; - } - } - - /* - * Write data as needed... + * Process pending data in the input buffer... */ - 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... - */ - - FD_CLR(con->file, input); - con->file_ready = 1; - -#ifdef DEBUG - cupsdLogMessage(CUPSD_LOG_DEBUG2, "main: Data ready file %d!", - con->file); -#endif /* DEBUG */ - - if (!FD_ISSET(con->http.fd, output)) - { - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "main: Removing fd %d from InputSet...", con->file); - FD_CLR(con->file, input); - FD_CLR(con->file, InputSet); - } - } - - if (FD_ISSET(con->http.fd, output)) + if (con->http.used) { - FD_CLR(con->http.fd, output); - - if (!con->pipe_pid || con->file_ready) - if (!cupsdWriteClient(con)) - continue; + cupsdReadClient(con); + continue; } /* @@ -1032,22 +868,6 @@ main(int argc, /* I - Number of command-line args */ } /* - * Update the root certificate once every 5 minutes if we have client - * connections... - */ - - if ((current_time - RootCertTime) >= RootCertDuration && RootCertDuration && - !RunUser && cupsArrayCount(Clients)) - { - /* - * Update the root certificate... - */ - - cupsdDeleteCert(0); - cupsdAddCert(0, "root"); - } - - /* * Handle OS-specific event notification for any events that have * accumulated. Don't send these more than once a second... */ @@ -1114,13 +934,17 @@ main(int argc, /* I - Number of command-line args */ * Update the launchd config file as needed... */ - launchd_sync_conf(); + if (Launchd) + { + launchd_checkout(); + launchd_sync_conf(); - if (launchd_conf_url) - CFRelease(launchd_conf_url); + if (launchd_conf_url) + CFRelease(launchd_conf_url); - if (launchd_conf_dict) - CFRelease(launchd_conf_dict); + if (launchd_conf_dict) + CFRelease(launchd_conf_dict); + } #endif /* HAVE_LAUNCHD */ #ifdef __sgi @@ -1135,14 +959,7 @@ main(int argc, /* I - Number of command-line args */ unlink("/var/spool/lp/SCHEDLOCK"); #endif /* __sgi */ - /* - * Free memory used by FD sets and return... - */ - - free(InputSet); - free(OutputSet); - free(input); - free(output); + cupsdStopSelect(); return (!stop_scheduler); } @@ -1364,6 +1181,8 @@ launchd_checkin(void) cupsd_listener_t *lis; /* Listeners array */ http_addr_t addr; /* Address variable */ socklen_t addrlen; /* Length of address */ + int fd; /* File descriptor */ + char s[256]; /* String addresss */ cupsdLogMessage(CUPSD_LOG_DEBUG, "launchd_checkin: pid=%d", (int)getpid()); @@ -1417,56 +1236,77 @@ launchd_checkin(void) if (launch_data_get_type(ld_array) == LAUNCH_DATA_ARRAY) { - /* - * Free the listeners array built from cupsd.conf... - */ - - cupsdDeleteAllListeners(); - - /* - * Create a new array of listeners from the launchd data... - */ - - Listeners = cupsArrayNew(NULL, NULL); - count = launch_data_array_get_count(ld_array); + count = launch_data_array_get_count(ld_array); for (i = 0; i < count; i ++) { /* - * Copy the current address and log it... + * Get the launchd file descriptor and address... */ - if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL) + tmp = launch_data_array_get_index(ld_array, i); + fd = launch_data_get_fd(tmp); + addrlen = sizeof(addr); + + if (getsockname(fd, (struct sockaddr *)&addr, &addrlen)) { cupsdLogMessage(CUPSD_LOG_ERROR, - "launchd_checkin: Unable to allocate listener - %s.", - strerror(errno)); - exit(EXIT_FAILURE); + "launchd_checkin: Unable to get local address - %s", + strerror(errno)); + continue; } - cupsArrayAdd(Listeners, lis); + /* + * Try to match the launchd socket address to one of the listeners... + */ - tmp = launch_data_array_get_index(ld_array, i); - lis->fd = launch_data_get_fd(tmp); - addrlen = sizeof(lis->address); + for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); + lis; + lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) + if (httpAddrEqual(&lis->address, &addr)) + break; + + /* + * Add a new listener If there's no match... + */ - if (getsockname(lis->fd, (struct sockaddr *)&(lis->address), &addrlen)) + if (lis) { - cupsdLogMessage(CUPSD_LOG_ERROR, - "launchd_checkin: Unable to get local address - %s", - strerror(errno)); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "launchd_checkin: Matched existing listener %s with fd %d...", + httpAddrString(&(lis->address), s, sizeof(s)), fd); + } + else + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "launchd_checkin: Adding new listener %s with fd %d...", + httpAddrString(&addr, s, sizeof(s)), fd); + + if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "launchd_checkin: Unable to allocate listener - %s.", + strerror(errno)); + exit(EXIT_FAILURE); + } + + cupsArrayAdd(Listeners, lis); + + memcpy(&lis->address, &addr, sizeof(lis->address)); } + lis->fd = fd; + # ifdef HAVE_SSL portnum = 0; # ifdef AF_INET6 - if (addr.addr.sa_family == AF_INET6) - portnum = ntohs(addr.ipv6.sin6_port); + if (lis->address.addr.sa_family == AF_INET6) + portnum = ntohs(lis->address.ipv6.sin6_port); else # endif /* AF_INET6 */ - if (addr.addr.sa_family == AF_INET) - portnum = ntohs(addr.ipv4.sin_port); + if (lis->address.addr.sa_family == AF_INET) + portnum = ntohs(lis->address.ipv4.sin_port); if (portnum == 443) lis->encryption = HTTP_ENCRYPT_ALWAYS; @@ -1512,6 +1352,43 @@ launchd_checkin(void) /* + * 'launchd_checkout()' - Update the launchd KeepAlive file as needed. + */ + +static void +launchd_checkout(void) +{ + int fd; /* File descriptor */ + + + /* + * Create or remove the launchd KeepAlive file based on whether + * there are active jobs, polling, browsing for remote printers or + * shared printers to advertise... + */ + + if ((cupsArrayCount(ActiveJobs) || NumPolled || + (Browsing && + (BrowseRemoteProtocols || + (BrowseLocalProtocols && NumBrowsers && cupsArrayCount(Printers)))))) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Creating launchd keepalive file \"" CUPS_KEEPALIVE "\"..."); + + if ((fd = open(CUPS_KEEPALIVE, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR)) >= 0) + close(fd); + } + else + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Removing launchd keepalive file \"" CUPS_KEEPALIVE "\"..."); + + unlink(CUPS_KEEPALIVE); + } +} + + +/* * 'launchd_create_dict()' - Create a dictionary representing the launchd * config file org.cups.cupsd.plist. */ @@ -1519,24 +1396,26 @@ launchd_checkin(void) static CFDictionaryRef /* O - CFDictionary */ launchd_create_dict(void) { - int portnum; /* Port number */ - bool runatload; /* Run at load? */ - CFMutableDictionaryRef cupsd_dict, /* org.cups.cupsd.plist dictionary */ - sockets, /* Sockets dictionary */ - listener; /* Listener dictionary */ - CFMutableArrayRef array; /* Array */ - CFNumberRef socket_mode; /* Domain socket mode bits */ - CFStringRef socket_path; /* Domain socket path */ - CFTypeRef value; /* CF values */ - cupsd_listener_t *lis; /* Current listening socket */ - struct servent *service; /* Services data base entry */ - char temp[1024]; /* Temporary buffer for value */ + int portnum; /* Port number */ + bool runatload; /* Run at load? */ + CFMutableDictionaryRef cupsd_dict, /* org.cups.cupsd.plist dictionary */ + keepalive, /* KeepAlive dictionary */ + pathstate, /* PathState dictionary */ + sockets, /* Sockets dictionary */ + listener; /* Listener dictionary */ + CFMutableArrayRef array; /* Array */ + CFNumberRef socket_mode; /* Domain socket mode bits */ + CFStringRef socket_path; /* Domain socket path */ + CFTypeRef value; /* CF values */ + cupsd_listener_t *lis; /* Current listening socket */ + struct servent *service; /* Services data base entry */ + char temp[1024]; /* Temporary buffer for value */ if ((cupsd_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)) == NULL) - return NULL; + return (NULL); CFDictionaryAddValue(cupsd_dict, CFSTR(LAUNCH_JOBKEY_LABEL), CFSTR("org.cups.cupsd")); @@ -1544,20 +1423,35 @@ launchd_create_dict(void) kCFBooleanTrue); /* - * Run-at-load if there are active jobs, polling or shared printers - * to advertise... + * Use run-at-load and/or KeepAlive if there are active jobs, polling or + * shared printers to advertise... */ - + + if ((keepalive = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)) != NULL) + { + if ((pathstate = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)) != NULL) + { + CFDictionaryAddValue(pathstate, CFSTR(CUPS_KEEPALIVE), kCFBooleanTrue); + CFDictionaryAddValue(keepalive, CFSTR(LAUNCH_JOBKEY_PATHSTATE), + pathstate); + } + + CFDictionaryAddValue(cupsd_dict, CFSTR(LAUNCH_JOBKEY_KEEPALIVE), + keepalive); + } + runatload = (cupsArrayCount(ActiveJobs) || NumPolled || (Browsing && BrowseLocalProtocols && NumBrowsers && cupsArrayCount(Printers))) ? true : false; CFDictionaryAddValue(cupsd_dict, CFSTR(LAUNCH_JOBKEY_RUNATLOAD), runatload ? kCFBooleanTrue : kCFBooleanFalse); -# ifdef LAUNCH_JOBKEY_SERVICEIPC CFDictionaryAddValue(cupsd_dict, CFSTR(LAUNCH_JOBKEY_SERVICEIPC), kCFBooleanTrue); -# endif /* LAUNCH_JOBKEY_SERVICEIPC */ if ((array = CFArrayCreateMutable(kCFAllocatorDefault, 2, &kCFTypeArrayCallBacks)) != NULL) @@ -1728,106 +1622,6 @@ launchd_create_dict(void) /* - * 'launchd_reload()' - Tell launchd to reload the configuration file to pick - * up the new listening directives. - */ - -static void -launchd_reload(void) -{ - int child_status; /* Exit status of child process */ - pid_t child_pid, /* Child PID */ - waitpid_status; /* Child process exit status */ - char *argv[4]; /* Argument strings */ - - - /* - * The current launchd doesn't support a reload option (rdar://3854821). - * Until this is fixed we need to reload the config file by execing launchctl - * twice (to unload then load). NOTE: This will cause us to exit on SIGTERM - * which will cancel all client & job activity. - * - * After this is fixed we'll be able to tell launchd to reload the file - * and pick up the new listening descriptors without disrupting current - * activity. - */ - - /* - * Unloading the current configuration will cause launchd to send us a SIGTERM; - * block it for now so we can get our work done... - */ - - cupsdHoldSignals(); - - /* - * Set up the unload arguments to launchctl... - */ - - argv[0] = "/bin/launchctl"; - argv[1] = "unload"; - argv[2] = LaunchdConf; - argv[3] = NULL; - - if (cupsdStartProcess(argv[0], argv, NULL, -1, -1, -1, -1, 1, &child_pid) < 0) - cupsdLogMessage(CUPSD_LOG_ERROR, - "launchd_reload: Unable to execute %s - %s", argv[0], - strerror(errno)); - else - { - do - { - waitpid_status = waitpid(child_pid, &child_status, 0); - } - while (waitpid_status == (pid_t)-1 && errno == EINTR); - - if (WIFSIGNALED(child_status)) - cupsdLogMessage(CUPSD_LOG_DEBUG, - "launchd_reload: %s pid %d crashed on signal %d!", - basename(argv[0]), child_pid, WTERMSIG(child_status)); - else - cupsdLogMessage(CUPSD_LOG_DEBUG, - "launchd_reload: %s pid %d stopped with status %d!", - basename(argv[0]), child_pid, WEXITSTATUS(child_status)); - - /* - * Do it again with the load command... - */ - - argv[1] = "load"; - - if (cupsdStartProcess(argv[0], argv, NULL, -1, -1, -1, -1, 1, - &child_pid) < 0) - { - cupsdLogMessage(CUPSD_LOG_ERROR, - "launchd_reload: Unable to fork for %s - %s", argv[0], - strerror(errno)); - } - else - { - do - { - waitpid_status = waitpid(child_pid, &child_status, 0); - } while (waitpid_status == (pid_t)-1 && errno == EINTR); - - if (WIFSIGNALED(child_status)) - cupsdLogMessage(CUPSD_LOG_DEBUG, - "launchd_reload: %s pid %d crashed on signal %d!", - basename(argv[0]), child_pid, WTERMSIG(child_status)); - else - cupsdLogMessage(CUPSD_LOG_DEBUG, - "launchd_reload: %s pid %d stopped with status %d", - basename(argv[0]), child_pid, - WEXITSTATUS(child_status)); - } - } - - /* - * Leave signals blocked since exit() will be called momentarily anyways... - */ -} - - -/* * 'launchd_sync_conf()' - Rewrite the launchd config file * org.cups.cupsd.plist based on cupsd.conf. */ @@ -1890,7 +1684,7 @@ launchd_sync_conf(void) if (!CFEqual(cupsd_dict, launchd_conf_dict)) { if ((resourceData = CFPropertyListCreateXMLData(kCFAllocatorDefault, - cupsd_dict))) + cupsd_dict))) { if (CFURLWriteDataAndPropertiesToResource(launchd_conf_url, resourceData, NULL, &errorCode)) @@ -2174,12 +1968,12 @@ select_timeout(int fds) /* I - Number of descriptors returned */ return (0); /* - * If select has been active in the last second (fds != 0) or we have + * 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 || cupsArrayCount(Clients) > 50) + if (fds > 0 || cupsArrayCount(Clients) > 50) return (1); /* @@ -2225,7 +2019,7 @@ select_timeout(int fds) /* I - Number of descriptors returned */ } #endif /* HAVE_LDAP */ - if (BrowseLocalProtocols & BROWSE_CUPS) + if ((BrowseLocalProtocols & BROWSE_CUPS) && NumBrowsers) { for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; @@ -2239,7 +2033,7 @@ select_timeout(int fds) /* I - Number of descriptors returned */ why = "browse timeout a printer"; } } - else if (!(p->type & CUPS_PRINTER_IMPLICIT)) + else if (p->shared && !(p->type & CUPS_PRINTER_IMPLICIT)) { if (BrowseInterval && (p->browse_time + BrowseInterval) < timeout) { @@ -2313,8 +2107,8 @@ select_timeout(int fds) /* I - Number of descriptors returned */ * Log and return the timeout value... */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "select_timeout: %ld seconds to %s", - timeout, why); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "select_timeout(%d): %ld seconds to %s", + fds, timeout, why); return (timeout); } @@ -2340,5 +2134,5 @@ usage(int status) /* O - Exit status */ /* - * End of "$Id: main.c 6090 2006-11-14 16:35:27Z mike $". + * End of "$Id: main.c 6326 2007-03-11 17:50:18Z mike $". */ |