4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of the
9 * License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
21 * Copyright (c) 2018, Intel Corporation.
26 #include <sys/types.h>
31 * callvpe() - execute a file with given arguments and environment.
32 * \param file[in] name or path of file to be executed.
33 * \param args[in] arguments to file.
34 * \param envp[in] execution environment.
35 * \return -1 on failure (for example if fork() failed).
36 * \return process return status on success.
38 * callvpe() is intended as a safer replacement for system(). It
39 * executes the file specified and returns after it has completed. As
40 * with system during execution of the command, SIGCHLD will be
41 * blocked, and SIGINT and SIGQUIT will be ignored. The main
42 * difference between system(cmd) and callvpe(file, args, envp) is
43 * that system() calls exec("/bin/sh" "-c" "cmd") whereas callvpe()
44 * bypasses the shell and passes the args given directly to execvpe().
48 * snprintf(cmd, sizeof(cmd), "rm -rf %s\n", path);
53 * char *args[] = { "rm", "-rf", "--", path, NULL };
54 * extern char **environ;
55 * rc = callvpe("/bin/rm", args, environ);
57 * Note that since callvpe() does not use the shell, IO redirection
58 * and pipelines (cmd > /dev/null, cmd 2>&1, cmd1 | cmd2, ...) are not
61 int callvpe(const char *file, char *const args[], char *const envp[])
63 struct sigaction sa = {
64 .sa_handler = SIG_IGN,
66 struct sigaction sa_int_saved;
67 struct sigaction sa_quit_saved;
68 sigset_t sigset_saved;
74 sigemptyset(&sa.sa_mask);
76 rc = sigaction(SIGINT, &sa, &sa_int_saved);
80 rc = sigaction(SIGQUIT, &sa, &sa_quit_saved);
84 sigaddset(&sa.sa_mask, SIGCHLD);
85 rc = sigprocmask(SIG_BLOCK, &sa.sa_mask, &sigset_saved);
96 execvpe(file, args, envp);
100 pid2 = waitpid(pid, &status, 0);
109 sigprocmask(SIG_SETMASK, &sigset_saved, NULL);
111 sigaction(SIGQUIT, &sa_quit_saved, NULL);
113 sigaction(SIGINT, &sa_int_saved, NULL);