Skip to content

Commit 3779c04

Browse files
author
ptc
committed
Create a pid file if running in daemon mode - casantos
1 parent 1ec7e18 commit 3779c04

File tree

4 files changed

+76
-12
lines changed

4 files changed

+76
-12
lines changed

crond.8

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
crond - dillon's lightweight cron daemon
55
.SH SYNOPSIS
66
.PP
7-
\f[B]crond [-s dir] [-c dir] [-t dir] [-m user\@host] [-M mailhandler] [-S|-L file] [-l loglevel] [-b|-f|-d]\f[]
7+
\f[B]crond [-s dir] [-c dir] [-t dir] [-m user\@host] [-M mailhandler] [-S|-L file] [-P|-p file] [-l loglevel] [-b|-f|-d]\f[]
88
.SH OPTIONS
99
.PP
1010
\f[B]crond\f[] is a background daemon that parses individual
@@ -69,6 +69,16 @@ log to specified file instead of syslog.
6969
.RS
7070
.RE
7171
.TP
72+
.B -P
73+
do not create a process-id file.
74+
.RS
75+
.RE
76+
.TP
77+
.B -L file
78+
Write process-id to specified file instead of /var/run/crond.pi
79+
.RS
80+
.RE
81+
.TP
7282
.B -l loglevel
7383
log events at the specified, or more important, loglevels.
7484
The default is `notice'.

defs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@
5454
#ifndef CRONTABS
5555
#define CRONTABS "/var/spool/cron/crontabs"
5656
#endif
57+
#ifndef PIDFILE
58+
#define PIDFILE "/var/run/crond.pid"
59+
#endif
5760
#ifndef CRONSTAMPS
5861
#define CRONSTAMPS "/var/spool/cron/cronstamps"
5962
#endif

main.c

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,13 @@ short DebugOpt = 0;
3232
short LogLevel = LOG_LEVEL;
3333
short ForegroundOpt = 0;
3434
short SyslogOpt = 1;
35+
short PidFileOpt = 1;
3536
const char *CDir = CRONTABS;
3637
const char *SCDir = SCRONTABS;
3738
const char *TSDir = CRONSTAMPS;
3839
const char *LogFile = NULL; /* opened with mode 0600 */
3940
const char *LogHeader = LOGHEADER;
41+
const char *PidFile = PIDFILE;
4042
const char *SendMail = NULL;
4143
const char *Mailto = NULL;
4244
char *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

subs.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
Prototype void printlogf(int level, const char *ctl, ...);
1313
Prototype void fdprintlogf(int level, int fd, const char *ctl, ...);
14-
Prototype void fdprintf(int fd, const char *ctl, ...);
14+
Prototype int fdprintf(int fd, const char *ctl, ...);
1515
Prototype void initsignals(void);
1616
Prototype char Hostname[SMALL_BUFFER];
1717

@@ -40,16 +40,19 @@ fdprintlogf(int level, int fd, const char *ctl, ...)
4040
va_end(va);
4141
}
4242

43-
void
43+
int
4444
fdprintf(int fd, const char *ctl, ...)
4545
{
4646
va_list va;
4747
char buf[LOG_BUFFER];
48+
int n;
4849

4950
va_start(va, ctl);
5051
vsnprintf(buf, sizeof(buf), ctl, va);
51-
write(fd, buf, strlen(buf));
52+
n = write(fd, buf, strlen(buf));
5253
va_end(va);
54+
55+
return n;
5356
}
5457

5558
void

0 commit comments

Comments
 (0)