SYSTEM(3)                  POSIX Programmer's Manual                 SYSTEM(3)



PPRROOLLOOGG
       This manual page is part of the POSIX Programmer's Manual.  The OS
       implementation of this interface may differ (consult the corresponding
       OS manual page for details of OS behavior), or the interface may not be
       implemented on OS.

NNAAMMEE
       system -- issue a command

SSYYNNOOPPSSIISS
       #include <stdlib.h>

       int system(const char *_c_o_m_m_a_n_d);

DDEESSCCRRIIPPTTIIOONN
       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-2017
       defers to the ISO C standard.

       If _c_o_m_m_a_n_d is a null pointer, the _s_y_s_t_e_m() function shall determine
       whether the host environment has a command processor. If _c_o_m_m_a_n_d is not
       a null pointer, the _s_y_s_t_e_m() function shall pass the string pointed to
       by _c_o_m_m_a_n_d to that command processor to be executed in an
       implementation-defined manner; this might then cause the program
       calling _s_y_s_t_e_m() to behave in a non-conforming manner or to terminate.

       The _s_y_s_t_e_m() function shall behave as if a child process were created
       using _f_o_r_k(), and the child process invoked the _s_h utility using
       _e_x_e_c_l() as follows:


           execl(<_s_h_e_l_l _p_a_t_h>, "sh", "-c", _c_o_m_m_a_n_d, (char *)0);

       where <_s_h_e_l_l _p_a_t_h> is an unspecified pathname for the _s_h utility. It is
       unspecified whether the handlers registered with _p_t_h_r_e_a_d___a_t_f_o_r_k() are
       called as part of the creation of the child process.

       The _s_y_s_t_e_m() 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 _s_y_s_t_e_m() and take whatever action is appropriate to the
       application if the command terminated due to receipt of a signal.

       The _s_y_s_t_e_m() function shall not affect the termination status of any
       child of the calling processes other than the process or processes it
       itself creates.

       The _s_y_s_t_e_m() function shall not return until the child process has
       terminated.

       The _s_y_s_t_e_m() function need not be thread-safe.

RREETTUURRNN VVAALLUUEE
       If _c_o_m_m_a_n_d is a null pointer, _s_y_s_t_e_m() shall return non-zero to
       indicate that a command processor is available, or zero if none is
       available.  The _s_y_s_t_e_m() function shall always return non-zero when
       _c_o_m_m_a_n_d is NULL.

       If _c_o_m_m_a_n_d is not a null pointer, _s_y_s_t_e_m() shall return the termination
       status of the command language interpreter in the format specified by
       _w_a_i_t_p_i_d().  The termination status shall be as defined for the _s_h
       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 _s_y_s_t_e_m() shall be
       as if the command language interpreter had terminated using _e_x_i_t(127)
       or ___e_x_i_t(127).  If a child process cannot be created, or if the
       termination status for the command language interpreter cannot be
       obtained, _s_y_s_t_e_m() shall return -1 and set _e_r_r_n_o to indicate the error.

EERRRROORRSS
       The _s_y_s_t_e_m() function may set _e_r_r_n_o values as described by _f_o_r_k().

       In addition, _s_y_s_t_e_m() may fail if:

       EECCHHIILLDD The status of the child process created by _s_y_s_t_e_m() is no longer
              available.

       _T_h_e _f_o_l_l_o_w_i_n_g _s_e_c_t_i_o_n_s _a_r_e _i_n_f_o_r_m_a_t_i_v_e_.

EEXXAAMMPPLLEESS
       None.

AAPPPPLLIICCAATTIIOONN UUSSAAGGEE
       If the return value of _s_y_s_t_e_m() is not -1, its value can be decoded
       through the use of the macros described in _<_s_y_s_/_w_a_i_t_._h_>.  For
       convenience, these macros are also provided in _<_s_t_d_l_i_b_._h_>.

       Note that, while _s_y_s_t_e_m() 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 _f_o_r_k() and _e_x_e_c.
       For example, if SIGINT is being caught or is set to SIG_DFL when
       _s_y_s_t_e_m() is called, then the child is started with SIGINT handling set
       to SIG_DFL.

       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 ''!!''  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 _s_y_s_t_e_m() to
       perform some task invisible to the user. If the user typed the
       interrupt character (""^^CC"", for example) while _s_y_s_t_e_m() is being used in
       this way, one would expect the application to be killed, but only the
       executed command is killed. Applications that use _s_y_s_t_e_m() in this way
       should carefully check the return status from _s_y_s_t_e_m() to see if the
       executed command was successful, and should take appropriate action
       when the command fails.

       Blocking SIGCHLD while waiting for the child to terminate prevents the
       application from catching the signal and obtaining status from
       _s_y_s_t_e_m()'s child process before _s_y_s_t_e_m() can get the status itself.

       The context in which the utility is ultimately executed may differ from
       that in which _s_y_s_t_e_m() 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.

       There is no defined way for an application to find the specific path
       for the shell. However, _c_o_n_f_s_t_r() can provide a value for _P_A_T_H that is
       guaranteed to find the _s_h utility.

       Using the _s_y_s_t_e_m() 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.

RRAATTIIOONNAALLEE
       The _s_y_s_t_e_m() function should not be used by programs that have set user
       (or group) ID privileges. The _f_o_r_k() and _e_x_e_c family of functions
       (except _e_x_e_c_l_p() and _e_x_e_c_v_p()), 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.

       There are three levels of specification for the _s_y_s_t_e_m() 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.

       POSIX.1-2008 places additional restrictions on _s_y_s_t_e_m().  It requires
       that if there is a command language interpreter, the environment must
       be as specified by _f_o_r_k() and _e_x_e_c.  This ensures, for example, that
       close-on-_e_x_e_c works, that file locks are not inherited, and that the
       process ID is different. It also specifies the return value from
       _s_y_s_t_e_m() when the command line can be run, thus giving the application
       some information about the command's completion status.

       Finally, POSIX.1-2008 requires the command to be interpreted as in the
       shell command language defined in the Shell and Utilities volume of
       POSIX.1-2017.

       Note that, _s_y_s_t_e_m(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 _s_y_s_t_e_m(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 _s_y_s_t_e_m() 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-2008
       if _s_y_s_t_e_m(NULL) returns zero.

       It was explicitly decided that when _c_o_m_m_a_n_d is NULL, _s_y_s_t_e_m() 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 _s_y_s_t_e_m(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 _s_y_s_t_e_m() call to fail, that system has been
       rendered non-conforming.

       Early drafts required, or allowed, _s_y_s_t_e_m() to return with _e_r_r_n_o set to
       [[EEIINNTTRR]] if it was interrupted with a signal. This error return was
       removed, and a requirement that _s_y_s_t_e_m() not return until the child has
       terminated was added. This means that if a _w_a_i_t_p_i_d() call in _s_y_s_t_e_m()
       exits with _e_r_r_n_o set to [[EEIINNTTRR]], _s_y_s_t_e_m() must reissue the _w_a_i_t_p_i_d().
       This change was made for two reasons:

        1. There is no way for an application to clean up if _s_y_s_t_e_m() returns
           [[EEIINNTTRR]], short of calling _w_a_i_t(), and that could have the
           undesirable effect of returning the status of children other than
           the one started by _s_y_s_t_e_m().

        2. While it might require a change in some historical implementations,
           those implementations already have to be changed because they use
           _w_a_i_t() instead of _w_a_i_t_p_i_d().

       Note that if the application is catching SIGCHLD signals, it will
       receive such a signal before a successful _s_y_s_t_e_m() call returns.

       To conform to POSIX.1-2008, _s_y_s_t_e_m() must use _w_a_i_t_p_i_d(), or some
       similar function, instead of _w_a_i_t().

       The following code sample illustrates how _s_y_s_t_e_m() might be implemented
       on an implementation conforming to POSIX.1-2008.


           #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);
           }

       Note that, while a particular implementation of _s_y_s_t_e_m() (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.

       Note also that the above example implementation is not thread-safe.
       Implementations can provide a thread-safe _s_y_s_t_e_m() function, but doing
       so involves complications such as how to restore the signal
       dispositions for SIGINT and SIGQUIT correctly if there are overlapping
       calls, and how to deal with cancellation. The example above would not
       restore the signal dispositions and would leak a process ID if
       cancelled. This does not matter for a non-thread-safe implementation
       since canceling a non-thread-safe function results in undefined
       behavior (see _S_e_c_t_i_o_n _2_._9_._5_._2, _C_a_n_c_e_l_l_a_t_i_o_n _P_o_i_n_t_s).  To avoid leaking
       a process ID, a thread-safe implementation would need to terminate the
       child process when acting on a cancellation.

       One reviewer suggested that an implementation of _s_y_s_t_e_m() might want to
       use an environment variable such as _S_H_E_L_L 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 _s_y_s_t_e_m(), 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-2017, then changing _S_H_E_L_L would render _s_y_s_t_e_m() non-conforming.
       This would affect applications that expected the specified behavior
       from _s_y_s_t_e_m(), and since the Shell and Utilities volume of POSIX.1-2017
       does not mention that _S_H_E_L_L affects _s_y_s_t_e_m(), the application would not
       know that it needed to unset _S_H_E_L_L.

FFUUTTUURREE DDIIRREECCTTIIOONNSS
       None.

SSEEEE AALLSSOO
       _S_e_c_t_i_o_n _2_._9_._5_._2, _C_a_n_c_e_l_l_a_t_i_o_n _P_o_i_n_t_s, _e_x_e_c, _p_i_p_e(), _p_t_h_r_e_a_d___a_t_f_o_r_k(),
       _w_a_i_t()

       The Base Definitions volume of POSIX.1-2017, <<lliimmiittss..hh>>, <<ssiiggnnaall..hh>>,
       <<ssttddlliibb..hh>>, <<ssyyss__wwaaiitt..hh>>

       The Shell and Utilities volume of POSIX.1-2017, _s_h

CCOOPPYYRRIIGGHHTT
       Portions of this text are reprinted and reproduced in electronic form
       from IEEE Std 1003.1-2017, Standard for Information Technology --
       Portable Operating System Interface (POSIX), The Open Group Base
       Specifications Issue 7, 2018 Edition, Copyright (C) 2018 by the
       Institute of Electrical and Electronics Engineers, Inc and The Open
       Group.  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.opengroup.org/unix/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 .



IEEE/The Open Group                  2017                            SYSTEM(3)
