IEEE P1003.2 Draft 11.2 - September 1991 Copyright (c) 1991 by the Institute of Electrical and Electronics Engineers, Inc. 345 East 47th Street New York, NY 10017, USA All rights reserved as an unpublished work. This is an unapproved and unpublished IEEE Standards Draft, subject to change. The publication, distribution, or copying of this draft, as well as all derivative works based on this draft, is expressly prohibited except as set forth below. Permission is hereby granted for IEEE Standards Committee participants to reproduce this document for purposes of IEEE standardization activities only, and subject to the restrictions contained herein. Permission is hereby also granted for member bodies and technical committees of ISO and IEC to reproduce this document for purposes of developing a national position, subject to the restrictions contained herein. Permission is hereby also granted to the preceding entities to make limited copies of this document in an electronic form only for the stated activities. The following restrictions apply to reproducing or transmitting the document in any form: 1) all copies or portions thereof must identify the document's IEEE project number and draft number, and must be accompanied by this entire notice in a prominent location; 2) no portion of this document may be redistributed in any modified or abridged form without the prior approval of the IEEE Standards Department. Other entities seeking permission to reproduce this document, or any portion thereof, for standardization or other activities, must contact the IEEE Standards Department for the appropriate license. Use of information contained in this unapproved draft is at your own risk. IEEE Standards Department Copyright and Permissions 445 Hoes Lane, P.O. Box 1331 Piscataway, NJ 08855-1331, USA +1 (908) 562-3800 +1 (908) 562-1571 [FAX] P1003.2/D11.2 INFORMATION TECHNOLOGY--POSIX B.3.1 C Binding for Execute Command Function: _s_y_s_t_e_m() B.3.1.1 Synopsis #include int system(const char *_c_o_m_m_a_n_d); B.3.1.2 Description This standard requires the _s_y_s_t_e_m() function as described in the C Standard {7}. The _s_y_s_t_e_m() function shall execute the command specified by the string pointed to by _c_o_m_m_a_n_d. The environment of the executed command shall be as if a child process were created using the POSIX.1 {8} _f_o_r_k() function, and the child process invoked the sh utility (see 4.56) using the POSIX.1 {8} _e_x_e_c_l() function as follows: execl(<_s_h_e_l_l _p_a_t_h>, "_s_h", "-_c", _c_o_m_m_a_n_d, (_c_h_a_r *)_0); where <_s_h_e_l_l _p_a_t_h> is an unspecified pathname for the sh utility. The _s_y_s_t_e_m() function shall ignore the SIGINT and SIGQUIT signals, and 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(es) it itself creates. The _s_y_s_t_e_m() function shall not return until the child process has terminated. B.3.1.3 Returns If _c_o_m_m_a_n_d is NULL, the _s_y_s_t_e_m() function shall return nonzero. If _c_o_m_m_a_n_d is not NULL, the _s_y_s_t_e_m() function shall return the termination status of the command language interpreter in the format specified by the _w_a_i_t_p_i_d() function in POSIX.1 {8}. The termination status of the command language interpreter is as specified for the sh utility, except that if some error prevents the command language interpreter from executing after the child process is created, the return Copyright (c) 1991 IEEE. All rights reserved. This is an unapproved IEEE Standards Draft, subject to change. 916 B C Language Bindings Option Part 2: SHELL AND UTILITIES P1003.2/D11.2 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. B.3.1.4 Errors The _s_y_s_t_e_m() function may set _e_r_r_n_o values as described by _f_o_r_k() in POSIX.1 {8}. BEGIN_RATIONALE B.3.1.5 Rationale. (_T_h_i_s _s_u_b_c_l_a_u_s_e _i_s _n_o_t _a _p_a_r_t _o_f _P_1_0_0_3._2) The C Standard {7} specifies that when _c_o_m_m_a_n_d is NULL, _s_y_s_t_e_m() returns nonzero if there is a command interpreter available and zero if one is not available. At first reading, it might appear that POSIX.2 conflicts with this, since it requires _s_y_s_t_e_m(NULL) to always return nonzero. There is no conflict, however. A POSIX.2 implementation must always have a command interpreter available, and is nonconforming if none is present. It is therefore permissible for the _s_y_s_t_e_m() function on a POSIX.2 system to implement the behavior specified by the C Standard {7} as long as it is understood that the implementation is not POSIX.2 conforming if 1 _s_y_s_t_e_m(NULL) returns zero. 1 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 will be 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 (^C 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 will be 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. Copyright (c) 1991 IEEE. All rights reserved. This is an unapproved IEEE Standards Draft, subject to change. B.3 C Binding for Shell Command Interface 917 P1003.2/D11.2 INFORMATION TECHNOLOGY--POSIX 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. _E_x_a_m_p_l_e_s_,__U_s_a_g_e The context in which the utility is ultimately executed may differ from that in which the _s_y_s_t_e_m() function was called. For example, file descriptors that have the FD_CLOEXEC flag set will be closed, and the process ID and parent process ID will be different. Also, if the executed utility changes its environment variables or its current working directory, that change will not be reflected in the caller's context. Earlier drafts of this standard required, or allowed, _s_y_s_t_e_m() to return with _e_r_r_n_o [EINTR] 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 [EINTR], _s_y_s_t_e_m() must re-issue 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 [EINTR], short of calling _w_a_i_t(), and that could have the undesirable effect of returning 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 1 such a signal before a successful _s_y_s_t_e_m() call returns. 1 _H_i_s_t_o_r_y__o_f__D_e_c_i_s_i_o_n_s__M_a_d_e The C Standard {7} requires that a call to _s_y_s_t_e_m() with a NULL will return a nonzero value, indicating the presence of a command language interpreter available to the system. 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, etc. 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 _a_n_y _s_y_s_t_e_m() call to fail, that system has been rendered nonconformant. Modified in Draft 6 to reflect the availability of the _w_a_i_t_p_i_d() function in POSIX.1 {8}. To conform to this standard, _s_y_s_t_e_m() must use Copyright (c) 1991 IEEE. All rights reserved. This is an unapproved IEEE Standards Draft, subject to change. 918 B C Language Bindings Option Part 2: SHELL AND UTILITIES P1003.2/D11.2 _w_a_i_t_p_i_d(), or some similar function, instead of _w_a_i_t(). Figure B-1 illustrates how _s_y_s_t_e_m() might be implemented on a POSIX.1 {8} implementation. 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. 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 PATH that is guaranteed to find the sh utility. One reviewer suggested that an implementation of _s_y_s_t_e_m() might want to use an environment variable such as 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 _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 POSIX.2, then changing SHELL would render _s_y_s_t_e_m() nonconformant. This would affect applications that expected the specified behavior from _s_y_s_t_e_m(), and since this standard does not mention that SHELL affects _s_y_s_t_e_m(), the application would not know that it needed to unset SHELL. END_RATIONALE B.3.2 C Binding for Pipe Communications with Programs Functions: _p_o_p_e_n(), _p_c_l_o_s_e() B.3.2.1 Synopsis #include FILE *popen(const char *_c_o_m_m_a_n_d, const char *_m_o_d_e); int pclose(FILE *_s_t_r_e_a_m); B.3.2.2 Description The _p_o_p_e_n() function shall execute the command specified by the string _c_o_m_m_a_n_d. It shall create a pipe between the calling program and the executed command, and return a pointer to a C Standard {7} stream that can be used to either read from or write to the pipe. The _p_c_l_o_s_e() function shall close the stream, wait for the command to terminate, and return the termination status from the command language interpreter. Copyright (c) 1991 IEEE. All rights reserved. This is an unapproved IEEE Standards Draft, subject to change. B.3 C Binding for Shell Command Interface 919