aboutsummaryrefslogtreecommitdiff
path: root/src/exec.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2007-08-22 13:23:03 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2007-08-22 13:23:03 +0000
commit180ca1d87d2bf69d9dbb0acb76422e9ae15f930c (patch)
treeb14651206aaec8e03fdfdce9e04433068fa62648 /src/exec.c
parent708a28a2f5bd2384e4c254a47d069ec4d9ef697e (diff)
downloadwydawca-180ca1d87d2bf69d9dbb0acb76422e9ae15f930c.tar.gz
wydawca-180ca1d87d2bf69d9dbb0acb76422e9ae15f930c.tar.bz2
Implement all directives
git-svn-id: file:///svnroot/wydawca/trunk@284 6bb4bd81-ecc2-4fd4-a2d4-9571d19c0d33
Diffstat (limited to 'src/exec.c')
-rw-r--r--src/exec.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/src/exec.c b/src/exec.c
new file mode 100644
index 0000000..1f9e27a
--- /dev/null
+++ b/src/exec.c
@@ -0,0 +1,155 @@
+/* wydawca - FTP release synchronisation daemon
+ Copyright (C) 2007 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
+ Free Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "wydawca.h"
+#include "save-cwd.h"
+#include <gpgme.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+
+static FILE *
+start_prog (int argc, const char **argv, pid_t *ppid)
+{
+ int p[2];
+ FILE *fp;
+ pid_t pid;
+ int i;
+
+ pipe (p);
+ switch (pid = fork ())
+ {
+ case 0:
+ /* Child process */
+
+ if (p[1] != 1)
+ dup2 (p[1], 1);
+ if (p[1] != 1)
+ dup2 (p[1], 2);
+ close (p[0]);
+
+ /* Close unneded descripitors */
+ for (i = getmaxfd (); i > 2; i--)
+ close (i);
+
+ execvp (argv[0], (char**) argv);
+ logmsg (LOG_CRIT, "cannot run %s: %s", argv[0], strerror (errno));
+ exit (1);
+
+ 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;
+}
+
+void
+log_output (int prio, const char *prog, FILE *fp)
+{
+ size_t size = 0;
+ char *buf = NULL;
+
+ logmsg (prio, "%s output follows:", prog);
+ while (getline (&buf, &size, fp) > 0)
+ logmsg (prio, "%s", buf);
+ logmsg (prio, "end of %s output", prog);
+ free (buf);
+}
+
+enum exec_result
+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);
+ }
+ 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.