aboutsummaryrefslogtreecommitdiff
path: root/src/job.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-01-01 13:25:55 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2013-01-01 13:33:04 +0200
commit24e6dfa7cffceea0cac0f3cc349192788f040939 (patch)
treec2bd53e9bc58873c8187e6bd622ae152b35d1d51 /src/job.c
parent2bdd70d698c63d32f25b4f1142e09f5eaef4812a (diff)
downloadwydawca-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.c572
1 files changed, 272 insertions, 300 deletions
diff --git a/src/job.c b/src/job.c
index ea1085e..01b7ae8 100644
--- a/src/job.c
+++ b/src/job.c
@@ -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);
}

Return to:

Send suggestions and report system problems to the System administrator.