This article was reproduced from: http://www.cnblogs.com/mickole/p/3187974.html
One, System () understands
Function: the system () function calls "/bin/sh-c command" to execute a specific command, blocking the current process until command execution is complete
Prototype:
int system (const char *command);
return value:
If the shell Run command cannot be started, System returns 127, and returns 1 if there are other errors that cannot be performed on the system call. Returns the exit code for the command if the system can execute smoothly.
Description
Man Help:
#include <stdlib.h>
int system (const char *command);
description
system () Executes a command specified in command by calling/bin/sh-c
command, and R Eturns after the command has been completed. During exe-
cution of the command, SIGCHLD'll be blocked, an D SIGINT and sigquit
'll be ignored.
RETURN VALUE
The value returned is-1 on error (e.g. Fork (2) failed), and the
Return status of the command otherwise. This latter return status is
In the format specified in Wait (2). Thus, the exit code of the command
'll be Wexitstatus (status). In case/bin/sh could not being executed,
The exit status would be, that's a command that does exit (127).
If the value of command is NULL, System () returns Non-zero if the shell
is available, and zero if not.
System () does not affect the wait status of any other children.
Second, the system () function principle
When the system function executes, functions such as fork, Execve, Waitpid, and so on are called.
Linux version of the system function source code:
int system (const char * cmdstring) { pid_t pid; int status; if (cmdstring = = NULL) { return (1); } if (PID = fork ()) <0) { status =-1; } else if (PID = = 0) { execl ("/bin/sh", "sh", "-C", Cmdstring, (char *) 0); _exit (127); This statement will not execute if the child process is performing normally } else{while (Waitpid (PID, &status, 0) < 0) {
if (errno! = einter) { status =-1; Break ; }}} return status; }
- Function description
System () calls fork () to produce a child process that calls the/BIN/SH-C string to execute the command represented by the argument string string, which returns the process that was originally called when execution is complete.
The SIGCHLD signal is temporarily shelved while the system () is being called, and the SIGINT and sigquit signals are ignored.
return value
=-1: Error occurred
= 0: The call succeeds but no child processes appear
>0: ID of the child process that successfully exited
If system () fails when calling/bin/sh, it returns 127, and other failure reasons return-1. If the argument string is a null pointer (NULL), a non-0 value of > is returned. If the system () call succeeds, it will eventually return
The return value after the shell command is executed, but this return value is also likely to return 127 for system () call/bin/sh failure, so it is better to check errno to confirm the success of the execution.
Additional Instructions
Do not use System () when writing programs with Suid/sgid permissions, and System () inherits environment variables, which can cause system security issues through environment variables.
The system function handles the return value, which involves 3 stages:
Phase 1: Preparation for creating child processes. If it fails, return-1.
Phase 2: Call/bin/sh to pull up the shell script, if the pull fails or the shell does not perform properly (see note 1), the reason value is written to the low 8~15 bit of status. The man in system only stated that it would write a value of 127, but the measured findings would also write 126 equivalents.
Phase 3: If the shell script finishes gracefully, fill the shell return value into the low 8~15 bit of status.
Note 1:
As long as the ability to call to/bin/sh, and the execution of the shell process is not abnormal interruption of other signals, are counted as normal end.
For example: Regardless of the reason returned in the shell script, whether the value is 0 or not 0, the normal execution ends. Even if the shell script does not exist or does not have execute permissions, it is the end of normal execution.
If the shell script is forced to kill during execution, the case is ended abnormally.
How do you determine whether the shell script process is performing properly at Phase 2? The system provides macros: wifexited (status). If wifexited (status) is true, the normal end is indicated.
How do I get the shell return value in Phase 3? You can do this directly by moving the 8bit right, but it's safe to use the system-provided macros: Wexitstatus (status).
Since we generally determine whether this script is executing correctly in the shell script by the return value, if 0 is returned successfully, the failure returns a positive number.
So in summary, the method that determines whether a system function calls the shell script to end normally is the following 3 conditions:
(1)-1! = Status
(2) wifexited (status) is True
(3) 0 = = Wexitstatus (status)
Attention:
According to the above analysis, when the shell script does not exist, do not execute permissions and other scenarios, to the first 2 conditions will still be established, at this time Wexitstatus (status) is 127,126 and other values.
Therefore, we cannot define a 127,126 value as a return value in a shell script, or we cannot distinguish between the return value of the shell or the reason for calling the shell script exception. The return value in the shell script should be 1 more than the beginning increment.
Sample program:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #define EXIT_ERR (m) do{ perror (m); Exit (exit_failure);} while (0); int main (void) { int status; Status = System ("Ls-l|wc-l"); if (status = =-1) { exit_err ("system error"); } else{ if (wifexited (status)) { if (wexitstatus (status) = = 0) printf ("Run Command successful\n"); else printf ("Run command fail and exit code is%d\n", Wexitstatus (status)); } else printf ("Exit status =%d\n", Wexitstatus (status)); } return 0;}
Results:
Linux system Programming process (VII): System () function uses "Go"