1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459
|
'\" et
.TH SYSTEM "3P" 2013 "IEEE/The Open Group" "POSIX Programmer's Manual"
.SH PROLOG
This manual page is part of the POSIX Programmer's Manual.
The Linux implementation of this interface may differ (consult
the corresponding Linux manual page for details of Linux behavior),
or the interface may not be implemented on Linux.
.SH NAME
system
\(em issue a command
.SH SYNOPSIS
.LP
.nf
#include <stdlib.h>
.P
int system(const char *\fIcommand\fP);
.fi
.SH DESCRIPTION
The functionality described on this reference page is aligned with the
ISO\ C standard. Any conflict between the requirements described here and the
ISO\ C standard is unintentional. This volume of POSIX.1\(hy2008 defers to the ISO\ C standard.
.P
If
.IR command
is a null pointer, the
\fIsystem\fR()
function shall determine whether the host environment has a command
processor. If
.IR command
is not a null pointer, the
\fIsystem\fR()
function shall pass the string pointed to by
.IR command
to that command processor to be executed in an implementation-defined
manner; this might then cause the program calling
\fIsystem\fR()
to behave in a non-conforming manner or to terminate.
.P
The
\fIsystem\fR()
function shall behave as if a child process were created using
\fIfork\fR(),
and the child process invoked the
.IR sh
utility using
\fIexecl\fR()
as follows:
.sp
.RS 4
.nf
\fB
execl(<\fIshell path\fP>, "sh", "-c", \fIcommand\fP, (char *)0);
.fi \fR
.P
.RE
.P
where <\fIshell path\fP> is an unspecified pathname for the
.IR sh
utility. It is unspecified whether the handlers registered with
\fIpthread_atfork\fR()
are called as part of the creation of the child process.
.P
The
\fIsystem\fR()
function shall ignore the SIGINT and SIGQUIT signals, and shall
block the SIGCHLD
signal, while waiting for the command to terminate. If this might
cause the application to miss a signal that would have killed it, then
the application should examine the return value from
\fIsystem\fR()
and take whatever action is appropriate to the application if the
command terminated due to receipt of a signal.
.P
The
\fIsystem\fR()
function shall not affect the termination status of any child of the
calling processes other than the process or processes it itself
creates.
.P
The
\fIsystem\fR()
function shall not return until the child process has terminated.
.P
The
\fIsystem\fR()
function need not be thread-safe.
.SH "RETURN VALUE"
If
.IR command
is a null pointer,
\fIsystem\fR()
shall return non-zero to indicate that a command processor is
available, or zero if none is available.
The
\fIsystem\fR()
function shall always return non-zero when
.IR command
is NULL.
.P
If
.IR command
is not a null pointer,
\fIsystem\fR()
shall return the termination status of the command language interpreter
in the format specified by
\fIwaitpid\fR().
The termination status shall be as defined for the
.IR sh
utility; otherwise, the termination status is unspecified. If some
error prevents the command language interpreter from executing after
the child process is created, the return value from
\fIsystem\fR()
shall be as if the command language interpreter had terminated using
.IR exit (127)
or
.IR _exit (127).
If a child process cannot be created, or if the termination status for
the command language interpreter cannot be obtained,
\fIsystem\fR()
shall return \(mi1 and set
.IR errno
to indicate the error.
.SH ERRORS
The
\fIsystem\fR()
function may set
.IR errno
values as described by
.IR "\fIfork\fR\^(\|)".
.br
.P
In addition,
\fIsystem\fR()
may fail if:
.TP
.BR ECHILD
The status of the child process created by
\fIsystem\fR()
is no longer available.
.LP
.IR "The following sections are informative."
.SH EXAMPLES
None.
.SH "APPLICATION USAGE"
If the return value of
\fIsystem\fR()
is not \(mi1, its value can be decoded through the use of the macros
described in
.IR <sys/wait.h> .
For convenience, these macros are also provided in
.IR <stdlib.h> .
.P
Note that, while
\fIsystem\fR()
must ignore SIGINT and SIGQUIT and block SIGCHLD while waiting for the
child to terminate, the handling of signals in the executed command is
as specified by
\fIfork\fR()
and
.IR exec .
For example, if SIGINT is being caught or is set to SIG_DFL when
\fIsystem\fR()
is called, then the child is started with SIGINT handling set to
SIG_DFL.
.P
Ignoring SIGINT and SIGQUIT in the parent process prevents coordination
problems (two processes reading from the same terminal, for example)
when the executed command ignores or catches one of the signals. It is
also usually the correct action when the user has given a command to
the application to be executed synchronously (as in the
.BR '!'
command in many interactive applications). In either case, the signal
should be delivered only to the child process, not to the application
itself. There is one situation where ignoring the signals might have
less than the desired effect. This is when the application uses
\fIsystem\fR()
to perform some task invisible to the user. If the user typed the
interrupt character (\c
.BR \(dq^C\(dq ,
for example) while
\fIsystem\fR()
is being used in this way, one would expect the application to be
killed, but only the executed command is killed. Applications that use
\fIsystem\fR()
in this way should carefully check the return status from
\fIsystem\fR()
to see if the executed command was successful, and should take
appropriate action when the command fails.
.P
Blocking SIGCHLD while waiting for the child to terminate prevents the
application from catching the signal and obtaining status from
\fIsystem\fR()'s
child process before
\fIsystem\fR()
can get the status itself.
.P
The context in which the utility is ultimately executed may differ from
that in which
\fIsystem\fR()
was called. For example, file descriptors that have the FD_CLOEXEC
flag set are closed, and the process ID and parent process ID are
different. Also, if the executed utility changes its environment
variables or its current working directory, that change is not
reflected in the caller's context.
.P
There is no defined way for an application to find the specific path
for the shell. However,
\fIconfstr\fR()
can provide a value for
.IR PATH
that is guaranteed to find the
.IR sh
utility.
.P
Using the
\fIsystem\fR()
function in more than one thread in a process or when the SIGCHLD
signal is being manipulated by more than one thread in a process may
produce unexpected results.
.SH RATIONALE
The
\fIsystem\fR()
function should not be used by programs that have set user (or group)
ID privileges. The
\fIfork\fR()
and
.IR exec
family of functions (except
\fIexeclp\fR()
and
\fIexecvp\fR()),
should be used instead. This prevents any unforeseen manipulation of
the environment of the user that could cause execution of commands not
anticipated by the calling program.
.P
There are three levels of specification for the
\fIsystem\fR()
function. The ISO\ C standard gives the most basic. It requires that the function
exists, and defines a way for an application to query whether a command
language interpreter exists. It says nothing about the command language
or the environment in which the command is interpreted.
.P
POSIX.1\(hy2008 places additional restrictions on
\fIsystem\fR().
It requires that if there is a command language interpreter, the
environment must be as specified by
\fIfork\fR()
and
.IR exec .
This ensures, for example, that close-on-\c
.IR exec
works, that file locks are not inherited, and that the process ID is
different. It also specifies the return value from
\fIsystem\fR()
when the command line can be run, thus giving the application some
information about the command's completion status.
.P
Finally, POSIX.1\(hy2008 requires the command to be interpreted as in the shell
command language defined in the Shell and Utilities volume of POSIX.1\(hy2008.
.P
Note that,
.IR system (NULL)
is required to return non-zero, indicating that there is a command
language interpreter. At first glance, this would seem to conflict with
the ISO\ C standard which allows
.IR system (NULL)
to return zero. There is no conflict, however. A system must have a
command language interpreter, and is non-conforming if none is present.
It is therefore permissible for the
\fIsystem\fR()
function on such a system to implement the behavior specified by the
ISO\ C standard as long as it is understood that the implementation does not
conform to POSIX.1\(hy2008 if
.IR system (NULL)
returns zero.
.P
It was explicitly decided that when
.IR command
is NULL,
\fIsystem\fR()
should not be required to check to make sure that the command language
interpreter actually exists with the correct mode, that there are
enough processes to execute it, and so on. The call
.IR system (NULL)
could, theoretically, check for such problems as too many existing
child processes, and return zero. However, it would be inappropriate to
return zero due to such a (presumably) transient condition. If some
condition exists that is not under the control of this application and
that would cause any
\fIsystem\fR()
call to fail, that system has been rendered non-conforming.
.P
Early drafts required, or allowed,
\fIsystem\fR()
to return with
.IR errno
set to
.BR [EINTR]
if it was interrupted with a signal. This error return was removed, and
a requirement that
\fIsystem\fR()
not return until the child has terminated was added. This means that if
a
\fIwaitpid\fR()
call in
\fIsystem\fR()
exits with
.IR errno
set to
.BR [EINTR] ,
\fIsystem\fR()
must reissue the
\fIwaitpid\fR().
This change was made for two reasons:
.IP " 1." 4
There is no way for an application to clean up if
\fIsystem\fR()
returns
.BR [EINTR] ,
short of calling
\fIwait\fR(),
and that could have the undesirable effect of returning the status of
children other than the one started by
\fIsystem\fR().
.IP " 2." 4
While it might require a change in some historical implementations,
those implementations already have to be changed because they use
\fIwait\fR()
instead of
\fIwaitpid\fR().
.P
Note that if the application is catching SIGCHLD signals, it will
receive such a signal before a successful
\fIsystem\fR()
call returns.
.P
To conform to POSIX.1\(hy2008,
\fIsystem\fR()
must use
\fIwaitpid\fR(),
or some similar function, instead of
\fIwait\fR().
.P
The following code sample illustrates how
\fIsystem\fR()
might be implemented on an implementation conforming to POSIX.1\(hy2008.
.sp
.RS 4
.nf
\fB
#include <signal.h>
int system(const char *cmd)
{
int stat;
pid_t pid;
struct sigaction sa, savintr, savequit;
sigset_t saveblock;
if (cmd == NULL)
return(1);
sa.sa_handler = SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigemptyset(&savintr.sa_mask);
sigemptyset(&savequit.sa_mask);
sigaction(SIGINT, &sa, &savintr);
sigaction(SIGQUIT, &sa, &savequit);
sigaddset(&sa.sa_mask, SIGCHLD);
sigprocmask(SIG_BLOCK, &sa.sa_mask, &saveblock);
if ((pid = fork()) == 0) {
sigaction(SIGINT, &savintr, (struct sigaction *)0);
sigaction(SIGQUIT, &savequit, (struct sigaction *)0);
sigprocmask(SIG_SETMASK, &saveblock, (sigset_t *)0);
execl("/bin/sh", "sh", "-c", cmd, (char *)0);
_exit(127);
}
if (pid == -1) {
stat = -1; /* errno comes from fork() */
} else {
while (waitpid(pid, &stat, 0) == -1) {
if (errno != EINTR){
stat = -1;
break;
}
}
}
sigaction(SIGINT, &savintr, (struct sigaction *)0);
sigaction(SIGQUIT, &savequit, (struct sigaction *)0);
sigprocmask(SIG_SETMASK, &saveblock, (sigset_t *)0);
return(stat);
}
.fi \fR
.P
.RE
.P
Note that, while a particular implementation of
\fIsystem\fR()
(such as the one above) can assume a particular path for the shell,
such a path is not necessarily valid on another system. The above
example is not portable, and is not intended to be.
.P
One reviewer suggested that an implementation of
\fIsystem\fR()
might want to use an environment variable such as
.IR SHELL
to determine which command interpreter to use. The supposed
implementation would use the default command interpreter if the one
specified by the environment variable was not available. This would
allow a user, when using an application that prompts for command lines
to be processed using
\fIsystem\fR(),
to specify a different command interpreter. Such an implementation is
discouraged. If the alternate command interpreter did not follow the
command line syntax specified in the Shell and Utilities volume of POSIX.1\(hy2008, then changing
.IR SHELL
would render
\fIsystem\fR()
non-conforming. This would affect applications that expected the
specified behavior from
\fIsystem\fR(),
and since the Shell and Utilities volume of POSIX.1\(hy2008 does not mention that
.IR SHELL
affects
\fIsystem\fR(),
the application would not know that it needed to unset
.IR SHELL .
.SH "FUTURE DIRECTIONS"
None.
.SH "SEE ALSO"
.IR "\fIexec\fR\^",
.IR "\fIpipe\fR\^(\|)",
.IR "\fIpthread_atfork\fR\^(\|)",
.IR "\fIwait\fR\^(\|)"
.P
The Base Definitions volume of POSIX.1\(hy2008,
.IR "\fB<limits.h>\fP",
.IR "\fB<signal.h>\fP",
.IR "\fB<stdlib.h>\fP",
.IR "\fB<sys_wait.h>\fP"
.P
The Shell and Utilities volume of POSIX.1\(hy2008,
.IR "\fIsh\fR\^"
.SH COPYRIGHT
Portions of this text are reprinted and reproduced in electronic form
from IEEE Std 1003.1, 2013 Edition, Standard for Information Technology
-- Portable Operating System Interface (POSIX), The Open Group Base
Specifications Issue 7, Copyright (C) 2013 by the Institute of
Electrical and Electronics Engineers, Inc and The Open Group.
(This is POSIX.1-2008 with the 2013 Technical Corrigendum 1 applied.) In the
event of any discrepancy between this version and the original IEEE and
The Open Group Standard, the original IEEE and The Open Group Standard
is the referee document. The original Standard can be obtained online at
http://www.unix.org/online.html .
Any typographical or formatting errors that appear
in this page are most likely
to have been introduced during the conversion of the source files to
man page format. To report such errors, see
https://www.kernel.org/doc/man-pages/reporting_bugs.html .
|