scron

simple cron daemon
git clone git://git.2f30.org/scron
Log | Files | Refs | README | LICENSE

commit 6751d1278c6945a6da4023460e0f19cab4449264
parent 98655a174a04e8ccd8c3c2f83fd8338d2ef50a60
Author: Ari Malinen <ari.malinen@gmail.com>
Date:   Thu, 26 Jun 2014 14:32:03 +0300

dont suspend while waiting for jobs to finish

Diffstat:
MMakefile | 2+-
Mcrond.c | 125+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
2 files changed, 72 insertions(+), 55 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,4 +1,4 @@ -CFLAGS=-std=c99 -Wall -pedantic -Wextra +CFLAGS+=-std=c99 -Wall -Wextra -pedantic all: crond diff --git a/crond.c b/crond.c @@ -8,40 +8,33 @@ #include <sys/types.h> #include <syslog.h> -#define LEN 100 +#define LEN 256 -int main(int argc, char *argv[]) { - char *ep, *col, line[LEN+1], config[LEN+1] = "/etc/crontab"; - int status, i, j; - time_t t; - struct tm *tm; - pid_t pid; - FILE *fp; +char config[LEN+1] = "/etc/crontab"; - openlog(argv[0], LOG_CONS | LOG_PID, LOG_LOCAL1); +void arg(int argc, char *argv[]) { + int i; + pid_t pid; for (i = 1; i < argc; i++) { if (!strcmp("-d", argv[i])) { - switch (fork()) { - case -1: - fprintf(stderr, "error: failed to daemonize\n"); - syslog(LOG_NOTICE, "error: failed to daemonize"); - break; - case 0: - setsid(); - fclose(stdin); - fclose(stdout); - fclose(stderr); - break; - default: - return 0; - + pid = fork(); + if (pid < 0) { + fprintf(stderr, "error: failed to fork daemon\n"); + syslog(LOG_NOTICE, "error: failed to fork daemon"); + } else if (pid == 0) { + setsid(); + fclose(stdin); + fclose(stdout); + fclose(stderr); + } else { + exit(EXIT_SUCCESS); } } else if (!strcmp("-f", argv[i])) { if (argv[i+1] == NULL || argv[i+1][0] == '-') { fprintf(stderr, "error: -f needs parameter\n"); syslog(LOG_NOTICE, "error: -f needs parameter"); - return 1; + exit(EXIT_FAILURE); } strncpy(config, argv[++i], LEN); } else { @@ -49,9 +42,24 @@ int main(int argc, char *argv[]) { fprintf(stderr, "-h help\n"); fprintf(stderr, "-d daemon\n"); fprintf(stderr, "-f <file> config file\n"); - return 1; + exit(EXIT_FAILURE); } } +} + +int main(int argc, char *argv[]) { + char line[LEN+1]; + char *endptr, *col; + int y, x; + int status, entry; + time_t t; + struct tm *tm; + pid_t pid; + FILE *fp; + + openlog(argv[0], LOG_CONS | LOG_PID, LOG_LOCAL1); + + arg(argc, argv); while (1) { t = time(NULL); @@ -65,37 +73,45 @@ int main(int argc, char *argv[]) { continue; } - for (i = 0; fgets(line, LEN+1, fp); i++) { + for (y = 0; fgets(line, LEN+1, fp); y++) { if (line[0] == '#' || line[0] == '\n') continue; - for (j = 0, col = strtok(line,"\t"); col; j++, col = strtok(NULL, "\t")) { - ep = ""; - - if ((j == 0 && (col[0] == '*' || strtol(col, &ep, 0) == tm->tm_min) && *ep == '\0') || - (j == 1 && (col[0] == '*' || strtol(col, &ep, 0) == tm->tm_hour) && *ep == '\0') || - (j == 2 && (col[0] == '*' || strtol(col, &ep, 0) == tm->tm_mday) && *ep == '\0') || - (j == 3 && (col[0] == '*' || strtol(col, &ep, 0) == tm->tm_mon) && *ep == '\0') || - (j == 4 && (col[0] == '*' || strtol(col, &ep, 0) == tm->tm_wday) && *ep == '\0')) { - continue; - } else if (j == 5) { - printf("run: %s", col); - syslog(LOG_NOTICE, "run: %s", col); - switch (pid = fork()) { - case -1: - fprintf(stderr, "error: job failed: %s", col); - syslog(LOG_NOTICE, "error: job failed: %s", col); - break; - case 0: - execl("/bin/sh", "/bin/sh", "-c", col, (char *) NULL); - fprintf(stderr, "error: job failed: %s", col); - syslog(LOG_NOTICE, "error: job failed: %s", col); - return 1; - break; + strtok(line, "\n"); + + for (x = 0, col = strtok(line,"\t"); col; x++, col = strtok(NULL, "\t")) { + if (x >= 0 && x <= 4) { + endptr = ""; + entry = strtol(col, &endptr, 0); + if (!strcmp("*", col)) + continue; + else if (!strcmp("", col) || !isdigit(col[0]) || + *col < 0 || *col > 59 || *endptr != '\0') { + fprintf(stderr, "error: %s line %d column %d\n", config, y+1, x+1); + syslog(LOG_NOTICE, "error: %s line %d column %d", config, y+1, x+1); + } else if ((x == 0 && entry == tm->tm_min) || + (x == 1 && entry == tm->tm_hour) || + (x == 2 && entry == tm->tm_mday) || + (x == 3 && entry == tm->tm_mon) || + (x == 4 && entry == tm->tm_wday)) + continue; + } + + if (x == 5) { + pid = fork(); + if (pid < 0) { + fprintf(stderr, "error: failed to fork job: %s", col); + syslog(LOG_NOTICE, "error: failed to fork job: %s", col); + } else if (pid == 0) { + printf("run: %s pid: %d time: %s", col, (int) getpid(), ctime(&t)); + syslog(LOG_NOTICE, "run: %s pid: %d", col, (int) getpid()); + + execl("/bin/sh", "/bin/sh", "-c", col, (char *) NULL); + + fprintf(stderr, "error: job failed: %s", col); + syslog(LOG_NOTICE, "error: job failed: %s", col); + return 1; } - } else if (!isdigit(col[0]) || *col < 0 || *col > 59 || *ep != '\0') { - fprintf(stderr, "error: %s line %d column %d\n", config, i+1, j+1); - syslog(LOG_NOTICE, "error: %s line %d column %d", config, i+1, j+1); } break; @@ -104,8 +120,9 @@ int main(int argc, char *argv[]) { fclose(fp); - while ((pid = wait(&status)) > 0) { - syslog(LOG_NOTICE, "job complete pid: %d return: %d", (int) pid, status); + while ((pid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) { + printf("complete: pid %d, return: %d time: %s", (int) pid, status, ctime(&t)); + syslog(LOG_NOTICE, "complete: pid: %d return: %d", (int) pid, status); } }