127 const char *myname =
"vstream_parse_args";
150 msg_panic(
"%s: got VSTREAM_POPEN_ARGV and VSTREAM_POPEN_COMMAND", myname);
151 args->
argv = va_arg(ap,
char **);
155 msg_panic(
"%s: got VSTREAM_POPEN_ARGV and VSTREAM_POPEN_COMMAND", myname);
156 args->
command = va_arg(ap,
char *);
160 args->
uid = va_arg(ap, uid_t);
164 args->
gid = va_arg(ap, gid_t);
167 args->
env = va_arg(ap,
char **);
170 args->
export = va_arg(ap,
char **);
173 args->
shell = va_arg(ap,
char *);
179 msg_panic(
"%s: unknown key: %d", myname, key);
184 msg_panic(
"%s: missing VSTREAM_POPEN_ARGV or VSTREAM_POPEN_COMMAND", myname);
195 const char *myname =
"vstream_popen";
206 vstream_parse_args(&args, ap);
215 switch (pid = fork()) {
217 (void) close(sockfd[0]);
218 (void) close(sockfd[1]);
222 if (close(sockfd[1]))
224 for (fd = 0; fd < 2; fd++)
226 if (
DUP2(sockfd[0], fd) < 0)
228 if (sockfd[0] >= 2 && close(sockfd[0]))
243 if (setenv(
"PATH", _PATH_DEFPATH, 1))
246 for (cpp = args.
env; *cpp; cpp += 2)
247 if (setenv(cpp[0], cpp[1], 1))
268 if (close(sockfd[0]))
281 pid_t saved_pid = stream->
pid;
290 msg_panic(
"vstream_pclose: stream has no process");
298 if (saved_waitpid_fn != 0)
299 pid = saved_waitpid_fn(saved_pid, &wait_status, 0);
301 pid = waitpid(saved_pid, &wait_status, 0);
302 }
while (pid == -1 && errno == EINTR);
303 return (pid == -1 ? -1 :
304 WIFSIGNALED(wait_status) ? WTERMSIG(wait_status) :
305 WEXITSTATUS(wait_status));
317 int main(
int argc,
char **argv)
327 msg_fatal(
"usage: %s 'command'", argv[0]);
358 msg_warn(
"exit status: %d", status);
#define vstring_fgets(s, p)
#define VSTREAM_POPEN_ARGV
int vstream_pclose(VSTREAM *stream)
#define VSTREAM_POPEN_ENV
NORETURN msg_panic(const char *fmt,...)
void(* MSG_CLEANUP_FN)(void)
int main(int argc, char **argv)
void argv_add(ARGV *argvp,...)
VSTREAM * vstream_popen(int flags,...)
#define VSTREAM_POPEN_COMMAND
void clean_env(char **preserve_list)
#define VSTREAM_POPEN_EXPORT
int vstream_fclose(VSTREAM *stream)
#define VSTREAM_POPEN_SHELL
void msg_warn(const char *fmt,...)
VSTRING * vstring_alloc(ssize_t len)
#define VSTREAM_POPEN_WAITPID_FN
NORETURN msg_fatal(const char *fmt,...)
int vstream_fflush(VSTREAM *stream)
ARGV * argv_split(const char *, const char *)
#define VSTREAM_POPEN_UID
#define vstream_fwrite(v, b, n)
VSTREAM_WAITPID_FN waitpid_fn
void set_ugid(uid_t uid, gid_t gid)
int duplex_pipe(int *fds)
struct VSTREAM_POPEN_ARGS VSTREAM_POPEN_ARGS
VSTRING * vstring_free(VSTRING *vp)
VSTREAM_WAITPID_FN waitpid_fn
NORETURN exec_command(const char *command)
#define VSTREAM_POPEN_GID
pid_t(* VSTREAM_WAITPID_FN)(pid_t, WAIT_STATUS_T *, int)
MSG_CLEANUP_FN msg_cleanup(MSG_CLEANUP_FN cleanup_fn)
VSTREAM * vstream_fdopen(int fd, int flags)
#define VSTREAM_POPEN_END
void argv_terminate(ARGV *argvp)