summaryrefslogtreecommitdiffstats
path: root/src/global/mail_run.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/global/mail_run.c')
-rw-r--r--src/global/mail_run.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/src/global/mail_run.c b/src/global/mail_run.c
new file mode 100644
index 0000000..f376434
--- /dev/null
+++ b/src/global/mail_run.c
@@ -0,0 +1,150 @@
+/*++
+/* NAME
+/* mail_run 3
+/* SUMMARY
+/* run mail component program
+/* SYNOPSIS
+/* #include <mail_run.h>
+/*
+/* int mail_run_foreground(dir, argv)
+/* const char *dir;
+/* char **argv;
+/*
+/* int mail_run_background(dir, argv)
+/* const char *dir;
+/* char **argv;
+/*
+/* NORETURN mail_run_replace(dir, argv)
+/* const char *dir;
+/* char **argv;
+/* DESCRIPTION
+/* This module runs programs that live in the mail program directory.
+/* Each routine takes a directory and a command-line array. The program
+/* pathname is built by prepending the directory and a slash to the
+/* command name.
+/*
+/* mail_run_foreground() runs the named command in the foreground and
+/* waits until the command terminates.
+/*
+/* mail_run_background() runs the named command in the background.
+/*
+/* mail_run_replace() attempts to replace the current process by
+/* an instance of the named command. This function never returns.
+/*
+/* Arguments:
+/* .IP argv
+/* A null-terminated command-line vector. The first array element
+/* is the base name of the program to be executed.
+/* DIAGNOSTICS
+/* The result is (-1) if the command could not be run. Otherwise,
+/* mail_run_foreground() returns the termination status of the
+/* command. mail_run_background() returns the process id in case
+/* of success.
+/* CONFIGURATION PARAMETERS
+/* fork_attempts: number of attempts to fork() a process;
+/* fork_delay: delay in seconds between fork() attempts.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <stringops.h>
+#include <mymalloc.h>
+
+/* Global library. */
+
+#include "mail_params.h"
+#include "mail_run.h"
+
+/* mail_run_foreground - run command in foreground */
+
+int mail_run_foreground(const char *dir, char **argv)
+{
+ int count;
+ char *path;
+ WAIT_STATUS_T status;
+ int pid;
+ int wpid;
+
+#define RETURN(x) { myfree(path); return(x); }
+
+ path = concatenate(dir, "/", argv[0], (char *) 0);
+
+ for (count = 0; count < var_fork_tries; count++) {
+ switch (pid = fork()) {
+ case -1:
+ msg_warn("fork %s: %m", path);
+ break;
+ case 0:
+ /* Reset the msg_cleanup() handlers in the child process. */
+ (void) msg_cleanup((MSG_CLEANUP_FN) 0);
+ execv(path, argv);
+ msg_fatal("execv %s: %m", path);
+ default:
+ do {
+ wpid = waitpid(pid, &status, 0);
+ } while (wpid == -1 && errno == EINTR);
+ RETURN(wpid == -1 ? -1 :
+ WIFEXITED(status) ? WEXITSTATUS(status) : 1)
+ }
+ sleep(var_fork_delay);
+ }
+ RETURN(-1);
+}
+
+/* mail_run_background - run command in background */
+
+int mail_run_background(const char *dir, char **argv)
+{
+ int count;
+ char *path;
+ int pid;
+
+#define RETURN(x) { myfree(path); return(x); }
+
+ path = concatenate(dir, "/", argv[0], (char *) 0);
+
+ for (count = 0; count < var_fork_tries; count++) {
+ switch (pid = fork()) {
+ case -1:
+ msg_warn("fork %s: %m", path);
+ break;
+ case 0:
+ /* Reset the msg_cleanup() handlers in the child process. */
+ (void) msg_cleanup((MSG_CLEANUP_FN) 0);
+ execv(path, argv);
+ msg_fatal("execv %s: %m", path);
+ default:
+ RETURN(pid);
+ }
+ sleep(var_fork_delay);
+ }
+ RETURN(-1);
+}
+
+/* mail_run_replace - run command, replacing current process */
+
+NORETURN mail_run_replace(const char *dir, char **argv)
+{
+ char *path;
+
+ path = concatenate(dir, "/", argv[0], (char *) 0);
+ execv(path, argv);
+ msg_fatal("execv %s: %m", path);
+}