]>
git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/main.c
2 * "$Id: main.c,v 1.19 1999/06/09 20:07:04 mike Exp $"
4 * Scheduler main loop for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-1999 by Easy Software Products, all rights reserved.
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44145 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636-3111 USA
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
26 * main() - Main entry for the CUPS scheduler.
27 * sigchld_handler() - Handle 'child' signals from old processes.
28 * sighup_handler() - Handle 'hangup' signals to reconfigure the scheduler.
29 * usage() - Show scheduler usage.
33 * Include necessary headers...
38 #include <sys/resource.h>
45 static void sigchld_handler(int sig
);
46 static void sighup_handler(int sig
);
47 static void usage(void);
51 * 'main()' - Main entry for the CUPS scheduler.
54 int /* O - Exit status */
55 main(int argc
, /* I - Number of command-line arguments */
56 char *argv
[]) /* I - Command-line arguments */
58 int i
; /* Looping var */
59 char *opt
; /* Option character */
60 fd_set input
, /* Input set for select() */
61 output
; /* Output set for select() */
62 client_t
*con
; /* Current client */
63 job_t
*job
, /* Current job */
65 listener_t
*lis
; /* Current listener */
66 time_t activity
; /* Activity timer */
67 struct timeval timeout
; /* select() timeout */
68 struct rlimit limit
; /* Runtime limit */
70 struct sigaction action
; /* Actions for POSIX signals */
71 #endif /* HAVE_SIGACTION */
75 * Check for command-line arguments...
78 for (i
= 1; i
< argc
; i
++)
79 if (argv
[i
][0] == '-')
80 for (opt
= argv
[i
] + 1; *opt
!= '\0'; opt
++)
83 case 'c' : /* Configuration file */
88 strncpy(ConfigurationFile
, argv
[i
], sizeof(ConfigurationFile
) - 1);
89 ConfigurationFile
[sizeof(ConfigurationFile
) - 1] = '\0';
92 default : /* Unknown option */
93 fprintf(stderr
, "cupsd: Unknown option \'%c\' - aborting!\n", *opt
);
99 fprintf(stderr
, "cupsd: Unknown argument \'%s\' - aborting!\n", argv
[i
]);
104 * Set the timezone to GMT...
112 * Disable core dumps...
115 getrlimit(RLIMIT_CORE
, &limit
);
117 setrlimit(RLIMIT_CORE
, &limit
);
121 * Set the maximum number of files...
124 getrlimit(RLIMIT_NOFILE
, &limit
);
125 limit
.rlim_cur
= limit
.rlim_max
;
126 setrlimit(RLIMIT_NOFILE
, &limit
);
129 * Catch hangup and child signals and ignore broken pipes...
132 #ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
133 sigset(SIGHUP
, sighup_handler
);
134 sigset(SIGCHLD
, sigchld_handler
);
135 sigset(SIGPIPE
, SIG_IGN
);
136 #elif defined(HAVE_SIGACTION)
137 memset(&action
, 0, sizeof(action
));
139 sigemptyset(&action
.sa_mask
);
140 sigaddset(&action
.sa_mask
, SIGHUP
);
141 action
.sa_handler
= sighup_handler
;
142 sigaction(SIGHUP
, &action
, NULL
);
144 sigemptyset(&action
.sa_mask
);
145 sigaddset(&action
.sa_mask
, SIGCHLD
);
146 action
.sa_handler
= sigchld_handler
;
147 sigaction(SIGCHLD
, &action
, NULL
);
149 sigemptyset(&action
.sa_mask
);
150 action
.sa_handler
= SIG_IGN
;
151 sigaction(SIGPIPE
, &action
, NULL
);
153 signal(SIGHUP
, sighup_handler
);
154 signal(SIGCLD
, sigchld_handler
); /* No, SIGCLD isn't a typo... */
155 signal(SIGPIPE
, SIG_IGN
);
156 #endif /* HAVE_SIGSET */
165 * Check if we need to load the server configuration file...
172 for (i
= NumClients
, con
= Clients
; i
> 0; i
--, con
++)
173 if (con
->http
.state
== HTTP_WAITING
)
179 con
->http
.keep_alive
= HTTP_KEEPALIVE_OFF
;
181 for (i
= 0; i
< NumListeners
; i
++)
182 FD_CLR(Listeners
[i
].fd
, &InputSet
);
184 else if (!ReadConfiguration())
186 fprintf(stderr
, "cupsd: Unable to read configuration file \'%s\' - exiting!\n",
193 * Check for available input or ready output. If select() returns
194 * 0 or -1, something bad happened and we should exit immediately.
196 * Note that we at least have one listening socket open at all
206 for (i
= NumClients
, con
= Clients
; i
> 0; i
--, con
++)
207 if (con
->http
.used
> 0)
213 if ((i
= select(100, &input
, &output
, NULL
, &timeout
)) < 0)
218 perror("cupsd: select() failed");
221 printf("cupsd: InputSet =");
222 for (i
= 0; i
< 100; i
++)
223 if (FD_ISSET(i
, &input
))
227 printf("cupsd: OutputSet =");
228 for (i
= 0; i
< 100; i
++)
229 if (FD_ISSET(i
, &output
))
237 for (i
= NumListeners
, lis
= Listeners
; i
> 0; i
--, lis
++)
238 if (FD_ISSET(lis
->fd
, &input
))
241 for (i
= NumClients
, con
= Clients
; i
> 0; i
--, con
++)
244 * Process the input buffer...
247 if (FD_ISSET(con
->http
.fd
, &input
) || con
->http
.used
)
248 if (!ReadClient(con
))
255 * Write data as needed...
258 if (FD_ISSET(con
->http
.fd
, &output
) &&
259 (!con
->pipe_pid
|| FD_ISSET(con
->file
, &input
)))
260 if (!WriteClient(con
))
267 * Check the activity and close old clients...
270 activity
= time(NULL
) - 30;
271 if (con
->http
.activity
< activity
)
280 * Check for status info from job filters...
283 for (job
= Jobs
; job
!= NULL
; job
= next
)
287 if (job
->pipe
&& FD_ISSET(job
->pipe
, &input
))
292 * Update the browse list as needed...
295 if (BrowseSocket
>= 0)
297 if (FD_ISSET(BrowseSocket
, &input
))
305 * If we get here something very bad happened and we need to exit
317 * 'sigchld_handler()' - Handle 'child' signals from old processes.
321 sigchld_handler(int sig
) /* I - Signal number */
323 int status
; /* Exit status of child */
324 int pid
; /* Process ID of child */
325 job_t
*job
; /* Current job */
326 int i
; /* Looping var */
332 while ((pid
= waitpid(-1, &status
, WNOHANG
)) > 0)
333 #elif defined(HAVE_WAIT3)
334 while ((pid
= wait3(&status
, WNOHANG
, NULL
)) > 0)
336 if ((pid
= wait(&status
)) > 0)
337 #endif /* HAVE_WAITPID */
339 DEBUG_printf(("sigcld_handler: pid = %d, status = %d\n", pid
, status
));
341 for (job
= Jobs
; job
!= NULL
; job
= job
->next
)
342 if (job
->state
== IPP_JOB_PROCESSING
)
344 for (i
= 0; job
->procs
[i
]; i
++)
345 if (job
->procs
[i
] == pid
)
351 * OK, this process has gone away; what's left?
354 job
->procs
[i
] = -pid
;
359 * A fatal error occurred; save the exit status so we know to stop
360 * the printer when all of the filters finish...
363 job
->status
= status
;
371 sigset(SIGCHLD
, sigchld_handler
);
372 #elif !defined(HAVE_SIGACTION)
373 signal(SIGCLD
, sigchld_handler
);
374 #endif /* HAVE_SIGSET */
379 * 'sighup_handler()' - Handle 'hangup' signals to reconfigure the scheduler.
383 sighup_handler(int sig
) /* I - Signal number */
392 * 'usage()' - Show scheduler usage.
398 fputs("Usage: cupsd [-c config-file]\n", stderr
);
404 * End of "$Id: main.c,v 1.19 1999/06/09 20:07:04 mike Exp $".