@@ -32,11 +32,13 @@ short DebugOpt = 0;
3232short LogLevel = LOG_LEVEL ;
3333short ForegroundOpt = 0 ;
3434short SyslogOpt = 1 ;
35+ short PidFileOpt = 1 ;
3536const char * CDir = CRONTABS ;
3637const char * SCDir = SCRONTABS ;
3738const char * TSDir = CRONSTAMPS ;
3839const char * LogFile = NULL ; /* opened with mode 0600 */
3940const char * LogHeader = LOGHEADER ;
41+ const char * PidFile = PIDFILE ;
4042const char * SendMail = NULL ;
4143const char * Mailto = NULL ;
4244char * TempDir ;
@@ -72,7 +74,7 @@ main(int ac, char **av)
7274
7375 opterr = 0 ;
7476
75- while ((i = getopt (ac ,av ,"dl:L:fbSc:s:m:M:t:" )) != -1 ) {
77+ while ((i = getopt (ac ,av ,"dl:L:fbSc:s:m:M:t:Pp: " )) != -1 ) {
7678 switch (i ) {
7779 case 'l' :
7880 {
@@ -161,19 +163,28 @@ main(int ac, char **av)
161163 case 'm' :
162164 if (* optarg != 0 ) Mailto = optarg ;
163165 break ;
166+ case 'P' :
167+ PidFileOpt = 0 ;
168+ break ;
169+ case 'p' :
170+ PidFileOpt = 1 ;
171+ PidFile = optarg ;
172+ break ;
164173 default :
165174 /*
166175 * check for parse error
167176 */
168177 printf ("dillon's cron daemon " VERSION "\n" );
169- printf ("crond [-s dir] [-c dir] [-t dir] [-m user@host] [-M mailer] [-S|-L [file]] [-l level] [-b|-f|-d]\n" );
178+ printf ("crond [-s dir] [-c dir] [-t dir] [-m user@host] [-M mailer] [-S|-L [file]] [-P|-p [file]] [- l level] [-b|-f|-d]\n" );
170179 printf ("-s directory of system crontabs (defaults to %s)\n" , SCRONTABS );
171180 printf ("-c directory of per-user crontabs (defaults to %s)\n" , CRONTABS );
172181 printf ("-t directory of timestamps (defaults to %s)\n" , CRONSTAMPS );
173182 printf ("-m user@host where should cron output be directed? (defaults to local user)\n" );
174183 printf ("-M mailer (defaults to %s)\n" , SENDMAIL );
175184 printf ("-S log to syslog using identity '%s' (default)\n" , LOG_IDENT );
176185 printf ("-L file log to specified file instead of syslog\n" );
186+ printf ("-P do not create process-id file\n" );
187+ printf ("-p file write pid to specified file instead of %s\n" , PIDFILE );
177188 printf ("-l loglevel log events <= this level (defaults to %s (level %d))\n" , LevelAry [LOG_LEVEL ], LOG_LEVEL );
178189 printf ("-b run in background (default)\n" );
179190 printf ("-f run in foreground\n" );
@@ -219,16 +230,48 @@ main(int ac, char **av)
219230
220231 int fd ;
221232 int pid ;
233+ int pipe_fd [2 ];
234+ int status ;
235+
236+ if (pipe (pipe_fd ) < 0 ) {
237+ //pipe failed
238+ perror ("pipe" );
239+ exit (1 );
240+ }
222241
223242 if ((pid = fork ()) < 0 ) {
224243 /* fork failed */
225244 perror ("fork" );
226245 exit (1 );
227246 } else if (pid > 0 ) {
228- /* parent */
229- exit (0 );
230- }
247+ /* parent, reads from pipe */
248+ close (pipe_fd [1 ]);
249+ if (read (pipe_fd [0 ], & status , sizeof (status )) > 0 ) {
250+ exit (status );
251+ }
252+ /* error: got zero bytes, so child just closed the write end */
253+ exit (1 );
254+ }
255+
231256 /* child continues */
257+ close (pipe_fd [0 ]);
258+ status = 0 ;
259+
260+ /* write pid file or exit */
261+
262+ if (PidFileOpt ) {
263+ if ((fd = open (PidFile , O_WRONLY |O_CREAT |O_TRUNC , 0644 )) < 0 ) {
264+ status = errno ;
265+ fprintf (stderr , "failed to open PID file '%s', reason: %s\n" , PidFile , strerror (status ));
266+ goto daemon_error ;
267+ }
268+ if (fdprintf (fd , "%d\n" , getpid ()) < 0 ) {
269+ status = errno ;
270+ fprintf (stderr , "failed to write PID file '%s', reason: %s\n" , PidFile , strerror (status ));
271+ goto daemon_error ;
272+ }
273+ close (fd );
274+ }
232275
233276 /* become session leader, detach from terminal */
234277
@@ -260,11 +303,16 @@ main(int ac, char **av)
260303 fclose (stderr );
261304 dup2 (fd , 2 );
262305 } else {
263- int n = errno ;
264- fdprintf (2 , "failed to open logfile '%s', reason: %s\n" , LogFile , strerror (n ));
265- exit ( n ) ;
306+ status = errno ;
307+ fdprintf (2 , "failed to open logfile '%s', reason: %s\n" , LogFile , strerror (errno ));
308+ goto daemon_error ;
266309 }
267310 }
311+ daemon_error :
312+ write (pipe_fd [1 ], & status , sizeof (status ));
313+ if (status != 0 ) {
314+ exit (status );
315+ }
268316 } else {
269317 /* daemon in foreground */
270318
0 commit comments