xref: /netbsd-src/external/ibm-public/postfix/dist/src/global/mail_run.c (revision 41fbaed053f8fbfdf9d2a4ee0a7386a3c83f8505)
1 /*	$NetBSD: mail_run.c,v 1.1.1.1 2009/06/23 10:08:46 tron Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	mail_run 3
6 /* SUMMARY
7 /*	run mail component program
8 /* SYNOPSIS
9 /*	#include <mail_run.h>
10 /*
11 /*	int	mail_run_foreground(dir, argv)
12 /*	const char *dir;
13 /*	char	**argv;
14 /*
15 /*	int	mail_run_background(dir, argv)
16 /*	const char *dir;
17 /*	char	**argv;
18 /*
19 /*	NORETURN mail_run_replace(dir, argv)
20 /*	const char *dir;
21 /*	char	**argv;
22 /* DESCRIPTION
23 /*	This module runs programs that live in the mail program directory.
24 /*	Each routine takes a directory and a command-line array. The program
25 /*	pathname is built by prepending the directory and a slash to the
26 /*	command name.
27 /*
28 /*	mail_run_foreground() runs the named command in the foreground and
29 /*	waits until the command terminates.
30 /*
31 /*	mail_run_background() runs the named command in the background.
32 /*
33 /*	mail_run_replace() attempts to replace the current process by
34 /*	an instance of the named command. This function never returns.
35 /*
36 /*	Arguments:
37 /* .IP argv
38 /*	A null-terminated command-line vector. The first array element
39 /*	is the base name of the program to be executed.
40 /* DIAGNOSTICS
41 /*	The result is (-1) if the command could not be run. Otherwise,
42 /*	mail_run_foreground() returns the termination status of the
43 /*	command. mail_run_background() returns the process id in case
44 /*	of success.
45 /* CONFIGURATION PARAMETERS
46 /*	fork_attempts: number of attempts to fork() a process;
47 /*	fork_delay: delay in seconds between fork() attempts.
48 /* LICENSE
49 /* .ad
50 /* .fi
51 /*	The Secure Mailer license must be distributed with this software.
52 /* AUTHOR(S)
53 /*	Wietse Venema
54 /*	IBM T.J. Watson Research
55 /*	P.O. Box 704
56 /*	Yorktown Heights, NY 10598, USA
57 /*--*/
58 
59 /* System library. */
60 
61 #include <sys_defs.h>
62 #include <sys/wait.h>
63 #include <unistd.h>
64 #include <errno.h>
65 
66 /* Utility library. */
67 
68 #include <msg.h>
69 #include <stringops.h>
70 #include <mymalloc.h>
71 
72 /* Global library. */
73 
74 #include "mail_params.h"
75 #include "mail_run.h"
76 
77 /* mail_run_foreground - run command in foreground */
78 
mail_run_foreground(const char * dir,char ** argv)79 int     mail_run_foreground(const char *dir, char **argv)
80 {
81     int     count;
82     char   *path;
83     WAIT_STATUS_T status;
84     int     pid;
85     int     wpid;
86 
87 #define RETURN(x) { myfree(path); return(x); }
88 
89     path = concatenate(dir, "/", argv[0], (char *) 0);
90 
91     for (count = 0; count < var_fork_tries; count++) {
92 	switch (pid = fork()) {
93 	case -1:
94 	    msg_warn("fork %s: %m", path);
95 	    break;
96 	case 0:
97 	    /* Reset the msg_cleanup() handlers in the child process. */
98 	    (void) msg_cleanup((MSG_CLEANUP_FN) 0);
99 	    execv(path, argv);
100 	    msg_fatal("execv %s: %m", path);
101 	default:
102 	    do {
103 		wpid = waitpid(pid, &status, 0);
104 	    } while (wpid == -1 && errno == EINTR);
105 	    RETURN(wpid == -1 ? -1 :
106 		   WIFEXITED(status) ? WEXITSTATUS(status) : 1)
107 	}
108 	sleep(var_fork_delay);
109     }
110     RETURN(-1);
111 }
112 
113 /* mail_run_background - run command in background */
114 
mail_run_background(const char * dir,char ** argv)115 int     mail_run_background(const char *dir, char **argv)
116 {
117     int     count;
118     char   *path;
119     int     pid;
120 
121 #define RETURN(x) { myfree(path); return(x); }
122 
123     path = concatenate(dir, "/", argv[0], (char *) 0);
124 
125     for (count = 0; count < var_fork_tries; count++) {
126 	switch (pid = fork()) {
127 	case -1:
128 	    msg_warn("fork %s: %m", path);
129 	    break;
130 	case 0:
131 	    /* Reset the msg_cleanup() handlers in the child process. */
132 	    (void) msg_cleanup((MSG_CLEANUP_FN) 0);
133 	    execv(path, argv);
134 	    msg_fatal("execv %s: %m", path);
135 	default:
136 	    RETURN(pid);
137 	}
138 	sleep(var_fork_delay);
139     }
140     RETURN(-1);
141 }
142 
143 /* mail_run_replace - run command, replacing current process */
144 
mail_run_replace(const char * dir,char ** argv)145 NORETURN mail_run_replace(const char *dir, char **argv)
146 {
147     char   *path;
148 
149     path = concatenate(dir, "/", argv[0], (char *) 0);
150     execv(path, argv);
151     msg_fatal("execv %s: %m", path);
152 }
153