aboutsummaryrefslogtreecommitdiff
path: root/src/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/exec.c')
-rw-r--r--src/exec.c253
1 files changed, 122 insertions, 131 deletions
diff --git a/src/exec.c b/src/exec.c
index 9af6de2..bb3307d 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -1,5 +1,5 @@
/* wydawca - automatic release submission daemon
- Copyright (C) 2007, 2009-2011 Sergey Poznyakoff
+ Copyright (C) 2007, 2009-2013 Sergey Poznyakoff
Wydawca is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@@ -23,150 +23,141 @@
/* Execute a program from ARGC/ARGV. Return PID in PPID.
Return FILE connected to the program's stdout and stderr. */
static FILE *
-start_prog (int argc, const char **argv, pid_t *ppid)
+start_prog(int argc, const char **argv, pid_t * ppid)
{
- int p[2];
- FILE *fp;
- pid_t pid;
- int i;
-
- if (pipe (p))
- {
- logmsg (LOG_CRIT, "pipe: %s", strerror (errno));
- return NULL;
- }
-
- switch (pid = fork ())
- {
- case 0:
- /* Child process */
-
- if (p[1] != 1 && dup2 (p[1], 1) == -1)
- {
- logmsg (LOG_CRIT, "dup2: %s", strerror (errno));
- _exit (EX_UNAVAILABLE);
+ int p[2];
+ FILE *fp;
+ pid_t pid;
+ int i;
+
+ if (pipe(p)) {
+ logmsg(LOG_CRIT, "pipe: %s", strerror(errno));
+ return NULL;
}
-
- if (p[1] != 1 && dup2 (p[1], 2) == -1)
- {
- logmsg (LOG_CRIT, "dup2: %s", strerror (errno));
- _exit (EX_UNAVAILABLE);
+
+ switch (pid = fork()) {
+ case 0:
+ /* Child process */
+
+ if (p[1] != 1 && dup2(p[1], 1) == -1) {
+ logmsg(LOG_CRIT, "dup2: %s", strerror(errno));
+ _exit(EX_UNAVAILABLE);
+ }
+
+ if (p[1] != 1 && dup2(p[1], 2) == -1) {
+ logmsg(LOG_CRIT, "dup2: %s", strerror(errno));
+ _exit(EX_UNAVAILABLE);
+ }
+
+ close(p[0]);
+
+ /* Close unneded descripitors */
+ for (i = getdtablesize(); i > 2; i--)
+ close(i);
+
+ execvp(argv[0], (char **)argv);
+ logmsg(LOG_CRIT, _("cannot run %s: %s"), argv[0],
+ strerror(errno));
+ exit(EX_UNAVAILABLE);
+
+ case -1:
+ logmsg(LOG_CRIT, _("cannot run `%s': fork failed: %s"),
+ argv[0], strerror(errno));
+ return NULL;
+
+ default:
+ /* Master process */
+ close(p[1]);
+ fp = fdopen(p[0], "r");
+ if (!fp)
+ logmsg(LOG_ERR, _("cannot fdopen: %s"),
+ strerror(errno));
+ *ppid = pid;
}
-
- close (p[0]);
-
- /* Close unneded descripitors */
- for (i = getdtablesize (); i > 2; i--)
- close (i);
-
- execvp (argv[0], (char**) argv);
- logmsg (LOG_CRIT, _("cannot run %s: %s"), argv[0], strerror (errno));
- exit (EX_UNAVAILABLE);
-
- case -1:
- logmsg (LOG_CRIT, _("cannot run `%s': fork failed: %s"),
- argv[0], strerror (errno));
- return NULL;
-
- default:
- /* Master process */
- close (p[1]);
- fp = fdopen (p[0], "r");
- if (!fp)
- logmsg (LOG_ERR, _("cannot fdopen: %s"), strerror (errno));
- *ppid = pid;
- }
- return fp;
+ return fp;
}
/* Log everything read from FP as the output from the program PROG, using
syslog priority PRIO. */
void
-log_output (int prio, const char *prog, FILE *fp)
+log_output(int prio, const char *prog, FILE * fp)
{
- size_t size = 0;
- char *buf = NULL;
-
- logmsg (prio, _("%s output follows:"), prog);
- while (grecs_getline (&buf, &size, fp) > 0)
- logmsg (prio, "%s", buf);
- logmsg (prio, _("end of %s output"), prog);
- free (buf);
+ size_t size = 0;
+ char *buf = NULL;
+
+ logmsg(prio, _("%s output follows:"), prog);
+ while (grecs_getline(&buf, &size, fp) > 0)
+ logmsg(prio, "%s", buf);
+ logmsg(prio, _("end of %s output"), prog);
+ free(buf);
}
/* Execute ARGC/ARGV. Return the exit code in RETCODE. */
enum exec_result
-wydawca_exec (int argc, const char **argv, int *retcode)
+wydawca_exec(int argc, const char **argv, int *retcode)
{
- FILE *fp;
- pid_t pid, npid;
- int status;
- int i;
- enum exec_result res;
-
- fp = start_prog (5, argv, &pid);
- if (!fp)
- {
- logmsg (LOG_CRIT, _("cannot start %s"), argv[0]);
- return exec_error;
- }
-
- for (i = 0; i < 5 && (npid = waitpid (pid, &status, WNOHANG)) == 0; i++)
- sleep (1);
-
- switch (npid)
- {
- case -1:
- logmsg (LOG_CRIT, _("cannot execute %s: waitpid failed: %s"),
- argv[0], strerror (errno));
- fclose (fp);
- return exec_error;
-
- case 0:
- logmsg (LOG_CRIT,
- _("cannot execute %s: the process did not respond "
- "within 5 seconds: %s"),
- argv[0], strerror (errno));
- kill (pid, SIGKILL);
- fclose (fp);
- return exec_error;
-
- default:
- break;
- }
-
- if (WIFEXITED (status))
- {
- int rc = WEXITSTATUS (status);
- if (rc)
- {
- res = exec_fail;
- logmsg (LOG_ERR, _("command %s returned %d"), argv[0], rc);
- log_output (LOG_ERR, argv[0], fp);
+ FILE *fp;
+ pid_t pid, npid;
+ int status;
+ int i;
+ enum exec_result res;
+
+ fp = start_prog(5, argv, &pid);
+ if (!fp) {
+ logmsg(LOG_CRIT, _("cannot start %s"), argv[0]);
+ return exec_error;
}
- else
- {
- res = exec_success;
- if (debug_level > 1)
- log_output (LOG_DEBUG, argv[0], fp);
+
+ for (i = 0; i < 5 && (npid = waitpid(pid, &status, WNOHANG)) == 0; i++)
+ sleep(1);
+
+ switch (npid) {
+ case -1:
+ logmsg(LOG_CRIT, _("cannot execute %s: waitpid failed: %s"),
+ argv[0], strerror(errno));
+ fclose(fp);
+ return exec_error;
+
+ case 0:
+ logmsg(LOG_CRIT,
+ _("cannot execute %s: the process did not respond "
+ "within 5 seconds: %s"), argv[0], strerror(errno));
+ kill(pid, SIGKILL);
+ fclose(fp);
+ return exec_error;
+
+ default:
+ break;
}
- if (retcode)
- *retcode = rc;
- }
- else
- {
- res = exec_error;
- if (WIFSIGNALED (status))
- logmsg (LOG_ERR, _("%s terminated on signal %d"),
- argv[0], WTERMSIG (status));
- else if (WIFSTOPPED (status))
- logmsg (LOG_ERR, _("%s stopped on signal %d"),
- argv[0], WTERMSIG (status));
- else
- logmsg (LOG_ERR, _("%s terminated with unrecognized status"),
- argv[0]);
- }
- fclose (fp);
-
- return res;
+
+ if (WIFEXITED(status)) {
+ int rc = WEXITSTATUS(status);
+ if (rc) {
+ res = exec_fail;
+ logmsg(LOG_ERR, _("command %s returned %d"), argv[0],
+ rc);
+ log_output(LOG_ERR, argv[0], fp);
+ } else {
+ res = exec_success;
+ if (debug_level > 1)
+ log_output(LOG_DEBUG, argv[0], fp);
+ }
+ if (retcode)
+ *retcode = rc;
+ } else {
+ res = exec_error;
+ if (WIFSIGNALED(status))
+ logmsg(LOG_ERR, _("%s terminated on signal %d"),
+ argv[0], WTERMSIG(status));
+ else if (WIFSTOPPED(status))
+ logmsg(LOG_ERR, _("%s stopped on signal %d"),
+ argv[0], WTERMSIG(status));
+ else
+ logmsg(LOG_ERR,
+ _("%s terminated with unrecognized status"),
+ argv[0]);
+ }
+ fclose(fp);
+
+ return res;
}

Return to:

Send suggestions and report system problems to the System administrator.