简体   繁体   English

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

[英]Return value of system() is not return value of executed program

I would like to execute an executable file whose main() returns 2 using system() . 我想执行一个可执行文件,其main()使用system()返回2。 This is what I did 这就是我做的

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

and test1 is test1

#include <stdio.h>

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

    return 2;
}

This is what I'm getting 这就是我得到的

test1 has been executed and its return value is 2
The return value: 512

My question is why I'm getting 512 . 我的问题是为什么我得到512

Quote man 3 system : 引用man 3 system

The value returned is -1 on error (eg fork (2) failed), and the return status of the command otherwise. 错误时返回的值为-1 (例如fork (2)失败),否则返回命令的返回状态。 This latter return status is in the format specified in wait (2). 后一种返回状态采用wait (2)中指定的格式。 Thus, the exit code of the command will be WEXITSTATUS(status) . 因此,命令的退出代码将是WEXITSTATUS(status)

man 2 wait shows the other information packed into the status returned by system (3). man 2 wait显示其他信息被打包到system (3)返回的status

  • 512 means the program exited with exit status 2. 512表示程序退出,退出状态为2。
  • 2 would mean the program was killed by signal 2 (SIGINT). 2意味着程序被信号2(SIGINT)杀死。

Note that that the string ./test1 takes 8 characters because of the trailing NUL. 请注意,由于尾随NUL,字符串./test1需要8个字符。 Your strcpy is clobbering some memory outside of command . 你的strcpycommand之外破坏了一些记忆。 Fix: 固定:

char command[8];
strcpy(command, "./test1");

Of course, there's no reason to make a copy in the first place. 当然,没有理由首先制作副本。

const char* command = "./test1";
system(command)

or even 甚至

system("./test1")

The return value of system is actually the return value of waitpid() under POSIX. 系统的返回值实际上是POSIX下waitpid()的返回值。

status actually has a lot of information embedded in it: status实际上嵌入了很多信息:

From the system(3) manpage: 从系统(3)手册页:

The following macros may be used to test the manner of exit of the process. 以下宏可用于测试进程退出的方式。 One of the first three macros will evaluate to a non-zero (true) value: 前三个宏中的一个将评估为非零(真)值:

WIFEXITED(status)

True if the process terminated normally by a call to _exit(2) or exit(3). 如果通过调用_exit(2)或exit(3)正常终止进程,则为True

WIFSIGNALED(status)

True if the process terminated due to receipt of a signal. 如果由于收到信号而终止进程,则为True

WIFSTOPPED(status)

True if the process has not terminated, but has stopped and can be restarted. 如果进程尚未终止,但已停止并可以重新启动,则为True
This macro can be true only if the wait call specified the WUNTRACED option or if the child process is being traced (see ptrace(2)). 仅当等待调用指定了WUNTRACED选项或正在跟踪子进程时,此宏才可以为true(请参阅ptrace(2))。

Depending on the values of those macros, the following macros produce the remaining status information about the child process: 根据这些宏的值,以下宏将生成有关子进程的剩余状态信息:

WEXITSTATUS(status)

If WIFEXITED(status) is true , evaluates to the low-order 8 bits of the argument passed to _exit(2) or exit(3) by the child. 如果WIFEXITED(status)true ,则计算子项传递给_exit(2)或exit(3)的参数的低位8位。

WTERMSIG(status)

If WIFSIGNALED(status) is true , evaluates to the number of the signal that caused the termination of the process. 如果WIFSIGNALED(status)true ,则计算导致进程终止的信号编号。

WCOREDUMP(status)

If WIFSIGNALED(status) is true , evaluates as true if the termination of the process was accompanied by the creation of a core file containing an image of the process when the signal was received. 如果WIFSIGNALED(status)true ,则如果进程终止伴随着在收到信号时创建包含进程映像的核心文件,则计算结果为true。

WSTOPSIG(status)

If WIFSTOPPED(status) is true , evaluates to the number of the signal that caused the process to stop. 如果WIFSTOPPED(status)true ,则计算导致进程停止的信号编号。

Solution

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

This is, in fact, undefined behavior. 事实上,这是未定义的行为。 command only holds 7 characters, but your string "./test1" has 8, including the null-terminator. command只保存7个字符,但字符串"./test1"有8个,包括空终止符。 You'll need to either increase the size of command , or just call system directly with the literal string: system("./test1") 您需要增加command的大小,或者直接使用文字字符串调用systemsystem("./test1")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM