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