system()的返回值不是执行程序的返回值

Cro*_*oCo 3 c program-entry-point return

我想执行一个可执行文件,其main()返回2使用system().这就是我做的

#include <stdio.h>
#include <string.h>

int main(int argc, char *agrv[])
{
    char command[7];
    strcpy(command, "./test1");
    printf("The return value: %d\n", system(command));

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

并且test1

#include <stdio.h>

int main(void)
{
    printf("test1 has been executed and its return value is 2\n");

    return 2;
}
Run Code Online (Sandbox Code Playgroud)

这就是我得到的

test1 has been executed and its return value is 2
The return value: 512
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么我得到了512.

ike*_*ami 6

Quote man 3 system:

返回的值是-1出错(例如fork(2)失败),否则返回命令的返回状态.后一种返回状态采用wait(2)中指定的格式.因此,命令的退出代码将是WEXITSTATUS(status).

man 2 wait显示statussystem(3)返回的其他信息.

  • 512 表示程序以退出状态2退出.
  • 2 意味着程序被信号2(SIGINT)杀死.

请注意,./test1由于尾随NUL ,该字符串需要8个字符.你strcpy在外面打破了一些记忆command.固定:

char command[8];
strcpy(command, "./test1");
Run Code Online (Sandbox Code Playgroud)

当然,没有理由首先制作副本.

const char* command = "./test1";
system(command)
Run Code Online (Sandbox Code Playgroud)

甚至

system("./test1")
Run Code Online (Sandbox Code Playgroud)


Ahm*_*sud 5

系统的返回值实际上是POSIX下waitpid()的返回值.

status 实际上有很多信息嵌入其中:

从系统(3)手册页:

以下宏可用于测试进程退出的方式.前三个宏中的一个将评估为非零(真)值:

WIFEXITED(status)

True 如果通过调用_exit(2)或exit(3)正常终止进程.

WIFSIGNALED(status)

True 如果由于收到信号而终止了该过程.

WIFSTOPPED(status)

True如果进程尚未终止,但已停止并可以重新启动.
仅当等待调用指定了WUNTRACED选项或正在跟踪子进程时,此宏才可以为true (请参阅ptrace(2)).

根据这些宏的值,以下宏将生成有关子进程的剩余状态信息:

WEXITSTATUS(status)

如果WIFEXITED(status)true,则计算子项传递给_exit(2)或exit(3)的参数的低8位.

WTERMSIG(status)

如果WIFSIGNALED(status)true,则评估导致过程终止的信号的编号.

WCOREDUMP(status)

如果WIFSIGNALED(status)true,则如果过程终止伴随着在收到信号时创建包含过程图像的核心文件,则评估为真.

WSTOPSIG(status)

如果WIFSTOPPED(status)true,则评估导致进程停止的信号的编号.

#include <stdio.h>
#include <string.h>
#include <limits.h>

int main(int argc, char *argv[])
{
    int status;
    char command[PATH_MAX]; /* PATH_MAX is defined in sys/syslimits.h, included by limits.h */
    strcpy(command, "./test1");
    status = system(command);
    if ( WIFEXITED(status) ) {
          printf("The return value: %d\n", WEXITSTATUS(status));
    }
    else if (WIFSIGNALED(status)) {
          printf("The program exited because of signal (signal no:%d)\n", WTERMSIG(status));
    } 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • “WIFEXITED”等宏应该使用“system(3)”或“wait(2)”函数进行记录。否则请参阅 POSIX.1 (2013) [sys/wait.h](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_wait.h.html) (2认同)