diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-01-01 13:25:55 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-01-01 13:33:04 +0200 |
commit | 24e6dfa7cffceea0cac0f3cc349192788f040939 (patch) | |
tree | c2bd53e9bc58873c8187e6bd622ae152b35d1d51 /src/job.c | |
parent | 2bdd70d698c63d32f25b4f1142e09f5eaef4812a (diff) | |
download | wydawca-24e6dfa7cffceea0cac0f3cc349192788f040939.tar.gz wydawca-24e6dfa7cffceea0cac0f3cc349192788f040939.tar.bz2 |
Update copyright years. Switch to a familiar style.
Diffstat (limited to 'src/job.c')
-rw-r--r-- | src/job.c | 572 |
1 files changed, 272 insertions, 300 deletions
@@ -1,5 +1,5 @@ /* wydawca - automatic release submission daemon - Copyright (C) 2009-2011 Sergey Poznyakoff + Copyright (C) 2009-2013 Sergey Poznyakoff This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -20,363 +20,335 @@ #define STATE_FINISHED 0x01 #define STATE_QUEUED 0x02 #define STATE_ACTIVE 0x04 - -struct job -{ - struct job *next, *prev; - int state; - struct spool *spool; - uid_t uid; - pid_t pid; - time_t timestamp; - int exit_status; + +struct job { + struct job *next, *prev; + int state; + struct spool *spool; + uid_t uid; + pid_t pid; + time_t timestamp; + int exit_status; }; struct job *queue; size_t jobmax; size_t jobcnt; -struct spool fake_spool = { "all spools" }, - inotify_spool = { "inotify" } ; +struct spool fake_spool = { "all spools" }, inotify_spool = { "inotify"}; static int wakeup; RETSIGTYPE -queue_signal (int sig) +queue_signal(int sig) { - wakeup = 1; - signal (sig, queue_signal); + wakeup = 1; + signal(sig, queue_signal); } void -set_timer (time_t interval) +set_timer(time_t interval) { - wakeup = 0; - if (interval) - alarm (interval); + wakeup = 0; + if (interval) + alarm(interval); } struct job * -job_locate (const struct spool *spool, uid_t uid) +job_locate(const struct spool *spool, uid_t uid) { - struct job *p; - for (p = queue; p; p = p->next) - if (p->spool == spool && p->uid == uid) - break; - return p; + struct job *p; + for (p = queue; p; p = p->next) + if (p->spool == spool && p->uid == uid) + break; + return p; } size_t -job_active_count () +job_active_count() { - struct job *job; - size_t count = 0; - for (job = queue; job; job = job->next) - if (job->state & STATE_ACTIVE) - count++; - return count; + struct job *job; + size_t count = 0; + for (job = queue; job; job = job->next) + if (job->state & STATE_ACTIVE) + count++; + return count; } static int -procspool (struct spool *spool, void *data) +procspool(struct spool *spool, void *data) { - spool_commit_triplets (spool); - return 0; + spool_commit_triplets(spool); + return 0; } int -wydawca_scanner (struct job *job) +wydawca_scanner(struct job *job) { - int rc; - initstats(); - timer_start ("wydawca"); - if (job->spool == &inotify_spool) - rc = for_each_spool (procspool, NULL); - else if (job->spool == &fake_spool) - rc = scan_all_spools (1, &job->uid); - else - { - spool_create_timers (); - rc = scan_spool (job->spool, 1, &job->uid); - } - timer_stop ("wydawca"); - logstats (); - mail_finish (); - return rc; + int rc; + initstats(); + timer_start("wydawca"); + if (job->spool == &inotify_spool) + rc = for_each_spool(procspool, NULL); + else if (job->spool == &fake_spool) + rc = scan_all_spools(1, &job->uid); + else { + spool_create_timers(); + rc = scan_spool(job->spool, 1, &job->uid); + } + timer_stop("wydawca"); + logstats(); + mail_finish(); + return rc; } -int -job_start (struct job *job) +int +job_start(struct job *job) { - pid_t pid; - - if (jobmax && jobcnt == jobmax) - { - logmsg (LOG_NOTICE, "maximum number of processes active"); - return 1; - } - - if (debug_level) - logmsg (LOG_DEBUG, _("starting job: %s, %lu"), - job->spool->tag, (unsigned long)job->uid); - - if (single_process) - { - if (wydawca_scanner (job)) - job->state = STATE_QUEUED; - else - job->state = STATE_FINISHED; - wakeup = 1; - return 0; - } - - pid = fork (); - if (pid == 0) - { - int i; - signal (SIGHUP, SIG_DFL); - signal (SIGTERM, SIG_DFL); - signal (SIGQUIT, SIG_DFL); - signal (SIGINT, SIG_DFL); - signal (SIGCHLD, SIG_DFL); - signal (SIGALRM, SIG_DFL); - alarm (0); - for (i = getdtablesize (); i > 2; i--) - close (i); - exit (wydawca_scanner (job) ? WYDAWCA_EX_AGAIN : 0); - } - else if (pid == -1) - { - logmsg (LOG_CRIT, "fork: %s", strerror (errno)); - return -1; - } - else - { - job->state = STATE_ACTIVE; - job->pid = pid; - jobcnt++; - } - return 0; -} + pid_t pid; + + if (jobmax && jobcnt == jobmax) { + logmsg(LOG_NOTICE, "maximum number of processes active"); + return 1; + } + + if (debug_level) + logmsg(LOG_DEBUG, _("starting job: %s, %lu"), + job->spool->tag, (unsigned long)job->uid); + + if (single_process) { + if (wydawca_scanner(job)) + job->state = STATE_QUEUED; + else + job->state = STATE_FINISHED; + wakeup = 1; + return 0; + } + + pid = fork(); + if (pid == 0) { + int i; + signal(SIGHUP, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGINT, SIG_DFL); + signal(SIGCHLD, SIG_DFL); + signal(SIGALRM, SIG_DFL); + alarm(0); + for (i = getdtablesize(); i > 2; i--) + close(i); + exit(wydawca_scanner(job) ? WYDAWCA_EX_AGAIN : 0); + } else if (pid == -1) { + logmsg(LOG_CRIT, "fork: %s", strerror(errno)); + return -1; + } else { + job->state = STATE_ACTIVE; + job->pid = pid; + jobcnt++; + } + return 0; +} void -job_remove (struct job *job) +job_remove(struct job *job) { - struct job *p; - - if (debug_level) - logmsg (LOG_DEBUG, _("removing job: %s, %lu"), - job->spool->tag, (unsigned long)job->uid); - p = job->prev; - if (p) - p->next = job->next; - else - queue = job->next; - - p = job->next; - if (p) - p->prev = job->prev; + struct job *p; + + if (debug_level) + logmsg(LOG_DEBUG, _("removing job: %s, %lu"), + job->spool->tag, (unsigned long)job->uid); + p = job->prev; + if (p) + p->next = job->next; + else + queue = job->next; + + p = job->next; + if (p) + p->prev = job->prev; } void -job_insert (struct job *job, struct job *elt) +job_insert(struct job *job, struct job *elt) { - struct job *p; - - job->prev = elt; - if (!elt) - { - if (queue) - queue->prev = job; - job->next = queue; - queue = job; - return; - } - - p = elt->next; - elt->next = job; - - if (p) - p->prev = job; + struct job *p; + + job->prev = elt; + if (!elt) { + if (queue) + queue->prev = job; + job->next = queue; + queue = job; + return; + } + + p = elt->next; + elt->next = job; + + if (p) + p->prev = job; } - + void -schedule_job (struct spool *spool, uid_t uid) +schedule_job(struct spool *spool, uid_t uid) { - struct job *job; - - if (!spool) - spool = &fake_spool; - - if (debug_level) - logmsg (LOG_DEBUG, _("scheduling job: %s, %lu"), - spool->tag, (unsigned long)uid); - - job = job_locate (spool, uid); - if (!job) - { - job = grecs_zalloc (sizeof (*job)); - job->spool = spool; - job->uid = uid; - job->pid = -1; - time (&job->timestamp); - job_insert (job, NULL); - } - - job->state |= STATE_QUEUED; - job_start (job); -} + struct job *job; + + if (!spool) + spool = &fake_spool; + + if (debug_level) + logmsg(LOG_DEBUG, _("scheduling job: %s, %lu"), + spool->tag, (unsigned long)uid); + + job = job_locate(spool, uid); + if (!job) { + job = grecs_zalloc(sizeof(*job)); + job->spool = spool; + job->uid = uid; + job->pid = -1; + time(&job->timestamp); + job_insert(job, NULL); + } + + job->state |= STATE_QUEUED; + job_start(job); +} static void -print_status (struct job *job, int expect_term) +print_status(struct job *job, int expect_term) { - struct passwd *pw = getpwuid (job->uid); - int status = job->exit_status; - - if (WIFEXITED (status)) - { - int exit_code = WEXITSTATUS (status); - if (exit_code == 0) - { - if (debug_level) - logmsg (LOG_DEBUG, - _("%lu (%s, %s) exited successfully"), - (unsigned long) job->pid, job->spool->tag, pw->pw_name); - } - else if (exit_code == WYDAWCA_EX_AGAIN) - { - if (debug_level) - logmsg (LOG_DEBUG, - _("%lu (%s, %s) reported tempfail"), - (unsigned long) job->pid, job->spool->tag, pw->pw_name); - } - else - logmsg (LOG_ERR, - _("%lu (%s, %s) failed with status %d"), - (unsigned long) job->pid, job->spool->tag, pw->pw_name, - exit_code); - } - else if (WIFSIGNALED (status)) - { - int prio; - if (expect_term && WTERMSIG (status) == SIGTERM) - { - if (!debug_level) - return; - prio = LOG_DEBUG; - } - else - prio = LOG_ERR; - - logmsg (prio, - _("%lu (%s, %s) terminated on signal %d"), - (unsigned long)job->pid, job->spool->tag, - pw->pw_name, WTERMSIG (status)); - } - else if (WIFSTOPPED (status)) - logmsg (LOG_NOTICE, - _("%lu (%s, %s) stopped on signal %d"), - (unsigned long)job->pid, job->spool->tag, - pw->pw_name, WSTOPSIG (status)); + struct passwd *pw = getpwuid(job->uid); + int status = job->exit_status; + + if (WIFEXITED(status)) { + int exit_code = WEXITSTATUS(status); + if (exit_code == 0) { + if (debug_level) + logmsg(LOG_DEBUG, + _("%lu (%s, %s) exited successfully"), + (unsigned long)job->pid, + job->spool->tag, + pw->pw_name); + } else if (exit_code == WYDAWCA_EX_AGAIN) { + if (debug_level) + logmsg(LOG_DEBUG, + _("%lu (%s, %s) reported tempfail"), + (unsigned long)job->pid, + job->spool->tag, + pw->pw_name); + } else + logmsg(LOG_ERR, + _("%lu (%s, %s) failed with status %d"), + (unsigned long)job->pid, job->spool->tag, + pw->pw_name, exit_code); + } else if (WIFSIGNALED(status)) { + int prio; + if (expect_term && WTERMSIG(status) == SIGTERM) { + if (!debug_level) + return; + prio = LOG_DEBUG; + } else + prio = LOG_ERR; + + logmsg(prio, + _("%lu (%s, %s) terminated on signal %d"), + (unsigned long)job->pid, job->spool->tag, + pw->pw_name, WTERMSIG(status)); + } else if (WIFSTOPPED(status)) + logmsg(LOG_NOTICE, + _("%lu (%s, %s) stopped on signal %d"), + (unsigned long)job->pid, job->spool->tag, + pw->pw_name, WSTOPSIG(status)); #ifdef WCOREDUMP - else if (WCOREDUMP (status)) - logmsg (LOG_NOTICE, - _("%lu (%s, %s) dumped core"), - (unsigned long)job->pid, job->spool->tag, pw->pw_name); + else if (WCOREDUMP(status)) + logmsg(LOG_NOTICE, + _("%lu (%s, %s) dumped core"), + (unsigned long)job->pid, job->spool->tag, pw->pw_name); #endif - else - logmsg (LOG_ERR, - _("%lu (%s, %s) terminated with unrecognized status"), - (unsigned long)job->pid, job->spool->tag, pw->pw_name); + else + logmsg(LOG_ERR, + _("%lu (%s, %s) terminated with unrecognized status"), + (unsigned long)job->pid, job->spool->tag, pw->pw_name); } void -job_queue_runner (time_t min_interval) +job_queue_runner(time_t min_interval) { - int status; - struct job *job; - time_t now = time (NULL); - - if (wakeup) - { - wakeup = 0; - - for (;;) - { - pid_t pid = waitpid ((pid_t)-1, &status, WNOHANG); - if (pid <= 0) - break; - for (job = queue; job; job = job->next) - { - if ((job->state & STATE_ACTIVE) && job->pid == pid) - { - job->state &= ~STATE_ACTIVE; - job->state |= STATE_FINISHED; - job->exit_status = status; - jobcnt--; - } - } - } - - for (job = queue; job;) - { - struct job *next = job->next; - if (job->state & STATE_FINISHED) - { - print_status (job, 0); - if ((job->state &= ~STATE_FINISHED) == 0) - { - if (WIFEXITED (job->exit_status) - && WEXITSTATUS (job->exit_status) == WYDAWCA_EX_AGAIN) - { - time_t interval = lock_timeout; - if (interval == 0) - interval = lock_expire_time; - /* Re-queue the job */ - job->state = STATE_QUEUED; - job->timestamp = now + interval; - } - else - { - job_remove (job); - free (job); - job = next; - continue; - } - } - } - - if (job->state == STATE_QUEUED) - { - if (job->timestamp >= now) - { - if (job_start (job)) - pause (); /* FIXME */ - now = time (NULL); + int status; + struct job *job; + time_t now = time(NULL); + + if (wakeup) { + wakeup = 0; + + for (;;) { + pid_t pid = waitpid((pid_t) - 1, &status, WNOHANG); + if (pid <= 0) + break; + for (job = queue; job; job = job->next) { + if ((job->state & STATE_ACTIVE) && + job->pid == pid) { + job->state &= ~STATE_ACTIVE; + job->state |= STATE_FINISHED; + job->exit_status = status; + jobcnt--; + } + } } - else - { - time_t interval = job->timestamp - now; - if (min_interval == 0 || interval < min_interval) - min_interval = interval; + + for (job = queue; job;) { + struct job *next = job->next; + if (job->state & STATE_FINISHED) { + print_status(job, 0); + if ((job->state &= ~STATE_FINISHED) == 0) { + if (WIFEXITED(job->exit_status) && + WEXITSTATUS(job->exit_status) == + WYDAWCA_EX_AGAIN) { + time_t interval = lock_timeout; + if (interval == 0) + interval = + lock_expire_time; + /* Re-queue the job */ + job->state = STATE_QUEUED; + job->timestamp = now + interval; + } else { + job_remove(job); + free(job); + job = next; + continue; + } + } + } + + if (job->state == STATE_QUEUED) { + if (job->timestamp >= now) { + if (job_start(job)) + pause(); /* FIXME */ + now = time(NULL); + } else { + time_t interval = job->timestamp - now; + if (min_interval == 0 + || interval < min_interval) + min_interval = interval; + } + } + + job = next; } - } - - job = next; } - } - - if (min_interval) - { - if (debug_level > 1) - logmsg (LOG_DEBUG, _("computed interval: %lu"), min_interval); - set_timer (min_interval); - } + + if (min_interval) { + if (debug_level > 1) + logmsg(LOG_DEBUG, _("computed interval: %lu"), + min_interval); + set_timer(min_interval); + } } void -job_init () +job_init() { - signal (SIGCHLD, queue_signal); - signal (SIGALRM, queue_signal); + signal(SIGCHLD, queue_signal); + signal(SIGALRM, queue_signal); } |