The system () function uses __ function

Source: Internet
Author: User
one, System () Understanding

Function: the system () function calls "/bin/sh-c command" to execute a specific command, blocking the current process until the command command has finished executing

Prototype:

int system (const char *command);

return value:

If you cannot start the Shell Run command, System returns 127, and returns 1 if there are other errors that cannot perform the system call. If system is able to execute smoothly, return the exit code for that command.


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 returns after the command has been CO Mpleted.

During execution of the command, SIGCHLD would be blocked, and SIGINT and Sigquit would be ignored.

The system () function calls/bin/sh to execute the command specified by the parameter,/bin/sh is typically a soft connection, pointing to a specific shell, such as the BASH,-C option is to tell the shell to read the command from the string command; SIGCHLD is blocked, like saying: Hi, the kernel, this will not send me a sigchld signal, and so I am busy to say, during the execution of the command, SIGINT and Sigquit were ignored, meaning that the process received the two signals without any action.

Return VALUE
The value returned is-1 on error (e.g. Fork (2) failed), and the
Return status is the command otherwise. This latter return status is
In the format specified in Wait (2). Thus, the exit code of the command
would be wexitstatus (status). In Case/bin/sh could is executed,
The exit status would be is that by 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. For a better understanding of the system () function return value, you need to understand its execution, in fact the system () function performs three steps: 1.fork a subprocess; 2. Call the EXEC function in a subprocess to execute command; 3. Call wait in the parent process to await the completion of the child process. For fork failure, the system () function returns-1. Returns the value returned by the command through exit or return if exec execution succeeds, and the command completes successfully. (Note that command execution does not represent successful execution, such as command: "rm debuglog.txt", which executes smoothly regardless of whether the file exists or not) if Exec fails, the command does not execute smoothly, such as by a signal interruption, or the command command does not exist at all, the system () function returns 127. If command is NULL, the system () function returns a value other than 0, typically 1.
two, System () function principle

Functions such as fork, EXECVE, waitpid are invoked when the system function executes.

Linux version of the system function source code:

int system (const char * cmdstring)
{
    pid_t pid;
    int status;
 
if (cmdstring = = NULL)
{
    return (1);//If cmdstring is empty, returns a value other than 0, typically 1
} if (
 
(PID = fork ()) <0)
{
    status =-1; Fork failed, return-1
}
else if (pid = = 0)//subprocess
{
    execl ("/bin/sh", "sh", "C", Cmdstring, (char *) 0);
    _exit (127); exec execution failed to return 127, noting that exec only returns to the current process only in the case of failure, and the success of the process now does not exist ~ ~
}
else//parent process
{
    while waitpid (PID, & Status, 0) < 0)
    {
        if (errno!= eintr)
        {
            status =-1;//If Waitpid is interrupted by a signal, return-1 break
            ;
        }
    }
}
 
    return status; Returns the return status of the child process if Waitpid succeeds
}

The first analysis of the principle, and then look at the above code you can expect to read:
Returns directly when the command accepted by system is null, otherwise fork a subprocess because fork is returned in two processes: both parent and child, to check that the returned Pid,fork returns 0 in the subprocess and returns the PID of the child process in the parent process. The parent process uses WAITPID to wait for the child process to end, and the subprocess calls Execl to start a program instead of itself, execl ("/bin/sh", "sh", "-C", Cmdstring, (char*) 0) is the calling shell, and the path to the shell is/ Bin/sh, the subsequent strings are arguments, and then the subprocess becomes a shell process, and the Shell's arguments
Is cmdstring, which is the parameter accepted by system. The shell in Windows is the command, and presumably everyone is familiar with the shell's acceptance of the command.

If the above you do not understand, then I explain the fork principle: When a process a calls fork, the system kernel creates a new process B and copies the memory image of A to B's process space, because A and B are the same, so how do they know if they are a parent or a subprocess? Look at the return value of the fork. Fork returns 0 in the subprocess and returns the PID of the child process in the parent process.

EXECL is the compiler's function (to some extent hides the specific system implementation), in Linux it will then produce a Linux system call EXECVE, prototype see below:


int Execve (const char * file,const char **argv,const char **envp);

When you see this, you will understand why system () accepts the environment variables of the parent process, but the system returns the main function after changing the environment variable with system. The reason for this is that the implementation of the system can be seen through the creation of a new process, from my analysis you can see that there is no process communication between the parent process and the child process, and the child process cannot naturally change the environment variables of the parent process.

The processing of the return value by the system function involves 3 stages:


Phase 1: Prepare for the creation of a child process. If it fails, return-1.

Phase 2: Call/bin/sh to pull up the shell script, and if pull fails or the shell does not finish properly (see note 1), the reason value is written to the low 8~15 bit of the status. The man of system

It only says that it will write a value of 127, but the actual test will also write a 126 equivalent.

Phase 3: If the shell script finishes properly, fill the shell return value into the low 8~15 bit of status.

Note 1:

As long as it can be called to/bin/sh, and the execution of the shell process is not interrupted by other signals, it is normal to end.

For example: No matter what reason value returned in the shell script, is 0 or not 0, is the normal execution end. Even if the shell script does not exist or does not have execute permissions, it is the normal execution end.

This is an abnormally close case if the shell script is forced to kill during execution.

How to Judge Phase 2, the shell foot-book process is the end of the normal execution. The system provides macros: wifexited (status). If wifexited (status) is true, the normal end is indicated.

How to get the shell return value in Phase 3. You can do this directly by moving the 8bit to the right, but it is safe to use a system-supplied macro: wexitstatus (status).

Since we generally judge whether this script executes correctly through the return value in the shell script, if 0 is successfully returned, the failure returns a positive number.

So in summary, the way to determine whether a system function calls a shell script to end normally is to set 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, there is no execution permissions, and other scenarios, the first 2 conditions will still be set up, at this time Wexitstatus (status) is 127,126 values.

Therefore, we cannot define a value of 127,126 as a return in a shell script, or we cannot distinguish between the return value of the shell or the reason for calling the shell script exception. Returns in the shell script

The value is better than 1 to start incrementing. Sample programs:

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


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.