1SYSTEM(3P) POSIX Programmer's Manual SYSTEM(3P)
2
3
4
6 This manual page is part of the POSIX Programmer's Manual. The Linux
7 implementation of this interface may differ (consult the corresponding
8 Linux manual page for details of Linux behavior), or the interface may
9 not be implemented on Linux.
10
12 system — issue a command
13
15 #include <stdlib.h>
16
17 int system(const char *command);
18
20 The functionality described on this reference page is aligned with the
21 ISO C standard. Any conflict between the requirements described here
22 and the ISO C standard is unintentional. This volume of POSIX.1‐2017
23 defers to the ISO C standard.
24
25 If command is a null pointer, the system() function shall determine
26 whether the host environment has a command processor. If command is not
27 a null pointer, the system() function shall pass the string pointed to
28 by command to that command processor to be executed in an implementa‐
29 tion-defined manner; this might then cause the program calling system()
30 to behave in a non-conforming manner or to terminate.
31
32 The system() function shall behave as if a child process were created
33 using fork(), and the child process invoked the sh utility using
34 execl() as follows:
35
36
37 execl(<shell path>, "sh", "-c", command, (char *)0);
38
39 where <shell path> is an unspecified pathname for the sh utility. It is
40 unspecified whether the handlers registered with pthread_atfork() are
41 called as part of the creation of the child process.
42
43 The system() function shall ignore the SIGINT and SIGQUIT signals, and
44 shall block the SIGCHLD signal, while waiting for the command to termi‐
45 nate. If this might cause the application to miss a signal that would
46 have killed it, then the application should examine the return value
47 from system() and take whatever action is appropriate to the applica‐
48 tion if the command terminated due to receipt of a signal.
49
50 The system() function shall not affect the termination status of any
51 child of the calling processes other than the process or processes it
52 itself creates.
53
54 The system() function shall not return until the child process has ter‐
55 minated.
56
57 The system() function need not be thread-safe.
58
60 If command is a null pointer, system() shall return non-zero to indi‐
61 cate that a command processor is available, or zero if none is avail‐
62 able. The system() function shall always return non-zero when command
63 is NULL.
64
65 If command is not a null pointer, system() shall return the termination
66 status of the command language interpreter in the format specified by
67 waitpid(). The termination status shall be as defined for the sh util‐
68 ity; otherwise, the termination status is unspecified. If some error
69 prevents the command language interpreter from executing after the
70 child process is created, the return value from system() shall be as if
71 the command language interpreter had terminated using exit(127) or
72 _exit(127). If a child process cannot be created, or if the termina‐
73 tion status for the command language interpreter cannot be obtained,
74 system() shall return -1 and set errno to indicate the error.
75
77 The system() function may set errno values as described by fork().
78
79 In addition, system() may fail if:
80
81 ECHILD The status of the child process created by system() is no longer
82 available.
83
84 The following sections are informative.
85
87 None.
88
90 If the return value of system() is not -1, its value can be decoded
91 through the use of the macros described in <sys/wait.h>. For conve‐
92 nience, these macros are also provided in <stdlib.h>.
93
94 Note that, while system() must ignore SIGINT and SIGQUIT and block
95 SIGCHLD while waiting for the child to terminate, the handling of sig‐
96 nals in the executed command is as specified by fork() and exec. For
97 example, if SIGINT is being caught or is set to SIG_DFL when system()
98 is called, then the child is started with SIGINT handling set to
99 SIG_DFL.
100
101 Ignoring SIGINT and SIGQUIT in the parent process prevents coordination
102 problems (two processes reading from the same terminal, for example)
103 when the executed command ignores or catches one of the signals. It is
104 also usually the correct action when the user has given a command to
105 the application to be executed synchronously (as in the '!' command in
106 many interactive applications). In either case, the signal should be
107 delivered only to the child process, not to the application itself.
108 There is one situation where ignoring the signals might have less than
109 the desired effect. This is when the application uses system() to per‐
110 form some task invisible to the user. If the user typed the interrupt
111 character ("^C", for example) while system() is being used in this way,
112 one would expect the application to be killed, but only the executed
113 command is killed. Applications that use system() in this way should
114 carefully check the return status from system() to see if the executed
115 command was successful, and should take appropriate action when the
116 command fails.
117
118 Blocking SIGCHLD while waiting for the child to terminate prevents the
119 application from catching the signal and obtaining status from sys‐
120 tem()'s child process before system() can get the status itself.
121
122 The context in which the utility is ultimately executed may differ from
123 that in which system() was called. For example, file descriptors that
124 have the FD_CLOEXEC flag set are closed, and the process ID and parent
125 process ID are different. Also, if the executed utility changes its
126 environment variables or its current working directory, that change is
127 not reflected in the caller's context.
128
129 There is no defined way for an application to find the specific path
130 for the shell. However, confstr() can provide a value for PATH that is
131 guaranteed to find the sh utility.
132
133 Using the system() function in more than one thread in a process or
134 when the SIGCHLD signal is being manipulated by more than one thread in
135 a process may produce unexpected results.
136
138 The system() function should not be used by programs that have set user
139 (or group) ID privileges. The fork() and exec family of functions
140 (except execlp() and execvp()), should be used instead. This prevents
141 any unforeseen manipulation of the environment of the user that could
142 cause execution of commands not anticipated by the calling program.
143
144 There are three levels of specification for the system() function. The
145 ISO C standard gives the most basic. It requires that the function
146 exists, and defines a way for an application to query whether a command
147 language interpreter exists. It says nothing about the command language
148 or the environment in which the command is interpreted.
149
150 POSIX.1‐2008 places additional restrictions on system(). It requires
151 that if there is a command language interpreter, the environment must
152 be as specified by fork() and exec. This ensures, for example, that
153 close-on-exec works, that file locks are not inherited, and that the
154 process ID is different. It also specifies the return value from sys‐
155 tem() when the command line can be run, thus giving the application
156 some information about the command's completion status.
157
158 Finally, POSIX.1‐2008 requires the command to be interpreted as in the
159 shell command language defined in the Shell and Utilities volume of
160 POSIX.1‐2017.
161
162 Note that, system(NULL) is required to return non-zero, indicating that
163 there is a command language interpreter. At first glance, this would
164 seem to conflict with the ISO C standard which allows system(NULL) to
165 return zero. There is no conflict, however. A system must have a com‐
166 mand language interpreter, and is non-conforming if none is present.
167 It is therefore permissible for the system() function on such a system
168 to implement the behavior specified by the ISO C standard as long as it
169 is understood that the implementation does not conform to POSIX.1‐2008
170 if system(NULL) returns zero.
171
172 It was explicitly decided that when command is NULL, system() should
173 not be required to check to make sure that the command language inter‐
174 preter actually exists with the correct mode, that there are enough
175 processes to execute it, and so on. The call system(NULL) could, theo‐
176 retically, check for such problems as too many existing child pro‐
177 cesses, and return zero. However, it would be inappropriate to return
178 zero due to such a (presumably) transient condition. If some condition
179 exists that is not under the control of this application and that would
180 cause any system() call to fail, that system has been rendered non-con‐
181 forming.
182
183 Early drafts required, or allowed, system() to return with errno set to
184 [EINTR] if it was interrupted with a signal. This error return was
185 removed, and a requirement that system() not return until the child has
186 terminated was added. This means that if a waitpid() call in system()
187 exits with errno set to [EINTR], system() must reissue the waitpid().
188 This change was made for two reasons:
189
190 1. There is no way for an application to clean up if system() returns
191 [EINTR], short of calling wait(), and that could have the undesir‐
192 able effect of returning the status of children other than the one
193 started by system().
194
195 2. While it might require a change in some historical implementations,
196 those implementations already have to be changed because they use
197 wait() instead of waitpid().
198
199 Note that if the application is catching SIGCHLD signals, it will
200 receive such a signal before a successful system() call returns.
201
202 To conform to POSIX.1‐2008, system() must use waitpid(), or some simi‐
203 lar function, instead of wait().
204
205 The following code sample illustrates how system() might be implemented
206 on an implementation conforming to POSIX.1‐2008.
207
208
209 #include <signal.h>
210 int system(const char *cmd)
211 {
212 int stat;
213 pid_t pid;
214 struct sigaction sa, savintr, savequit;
215 sigset_t saveblock;
216 if (cmd == NULL)
217 return(1);
218 sa.sa_handler = SIG_IGN;
219 sigemptyset(&sa.sa_mask);
220 sa.sa_flags = 0;
221 sigemptyset(&savintr.sa_mask);
222 sigemptyset(&savequit.sa_mask);
223 sigaction(SIGINT, &sa, &savintr);
224 sigaction(SIGQUIT, &sa, &savequit);
225 sigaddset(&sa.sa_mask, SIGCHLD);
226 sigprocmask(SIG_BLOCK, &sa.sa_mask, &saveblock);
227 if ((pid = fork()) == 0) {
228 sigaction(SIGINT, &savintr, (struct sigaction *)0);
229 sigaction(SIGQUIT, &savequit, (struct sigaction *)0);
230 sigprocmask(SIG_SETMASK, &saveblock, (sigset_t *)0);
231 execl("/bin/sh", "sh", "-c", cmd, (char *)0);
232 _exit(127);
233 }
234 if (pid == -1) {
235 stat = -1; /* errno comes from fork() */
236 } else {
237 while (waitpid(pid, &stat, 0) == -1) {
238 if (errno != EINTR){
239 stat = -1;
240 break;
241 }
242 }
243 }
244 sigaction(SIGINT, &savintr, (struct sigaction *)0);
245 sigaction(SIGQUIT, &savequit, (struct sigaction *)0);
246 sigprocmask(SIG_SETMASK, &saveblock, (sigset_t *)0);
247 return(stat);
248 }
249
250 Note that, while a particular implementation of system() (such as the
251 one above) can assume a particular path for the shell, such a path is
252 not necessarily valid on another system. The above example is not por‐
253 table, and is not intended to be.
254
255 Note also that the above example implementation is not thread-safe.
256 Implementations can provide a thread-safe system() function, but doing
257 so involves complications such as how to restore the signal disposi‐
258 tions for SIGINT and SIGQUIT correctly if there are overlapping calls,
259 and how to deal with cancellation. The example above would not restore
260 the signal dispositions and would leak a process ID if cancelled. This
261 does not matter for a non-thread-safe implementation since canceling a
262 non-thread-safe function results in undefined behavior (see Section
263 2.9.5.2, Cancellation Points). To avoid leaking a process ID, a
264 thread-safe implementation would need to terminate the child process
265 when acting on a cancellation.
266
267 One reviewer suggested that an implementation of system() might want to
268 use an environment variable such as SHELL to determine which command
269 interpreter to use. The supposed implementation would use the default
270 command interpreter if the one specified by the environment variable
271 was not available. This would allow a user, when using an application
272 that prompts for command lines to be processed using system(), to spec‐
273 ify a different command interpreter. Such an implementation is discour‐
274 aged. If the alternate command interpreter did not follow the command
275 line syntax specified in the Shell and Utilities volume of
276 POSIX.1‐2017, then changing SHELL would render system() non-conforming.
277 This would affect applications that expected the specified behavior
278 from system(), and since the Shell and Utilities volume of POSIX.1‐2017
279 does not mention that SHELL affects system(), the application would not
280 know that it needed to unset SHELL.
281
283 None.
284
286 Section 2.9.5.2, Cancellation Points, exec, pipe(), pthread_atfork(),
287 wait()
288
289 The Base Definitions volume of POSIX.1‐2017, <limits.h>, <signal.h>,
290 <stdlib.h>, <sys_wait.h>
291
292 The Shell and Utilities volume of POSIX.1‐2017, sh
293
295 Portions of this text are reprinted and reproduced in electronic form
296 from IEEE Std 1003.1-2017, Standard for Information Technology -- Por‐
297 table Operating System Interface (POSIX), The Open Group Base Specifi‐
298 cations Issue 7, 2018 Edition, Copyright (C) 2018 by the Institute of
299 Electrical and Electronics Engineers, Inc and The Open Group. In the
300 event of any discrepancy between this version and the original IEEE and
301 The Open Group Standard, the original IEEE and The Open Group Standard
302 is the referee document. The original Standard can be obtained online
303 at http://www.opengroup.org/unix/online.html .
304
305 Any typographical or formatting errors that appear in this page are
306 most likely to have been introduced during the conversion of the source
307 files to man page format. To report such errors, see https://www.ker‐
308 nel.org/doc/man-pages/reporting_bugs.html .
309
310
311
312IEEE/The Open Group 2017 SYSTEM(3P)