[英]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 (egfork
(2) failed), and the return status of the command otherwise. 错误时返回的值为-1
(例如fork
(2)失败),否则返回命令的返回状态。 This latter return status is in the format specified inwait
(2). 后一种返回状态采用wait
(2)中指定的格式。 Thus, the exit code of the command will beWEXITSTATUS(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
. 你的strcpy
在command
之外破坏了一些记忆。 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 theWUNTRACED
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)
istrue
, 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)
istrue
, evaluates to the number of the signal that caused the termination of the process. 如果WIFSIGNALED(status)
为true
,则计算导致进程终止的信号编号。
WCOREDUMP(status)
If
WIFSIGNALED(status)
istrue
, 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)
istrue
, evaluates to the number of the signal that caused the process to stop. 如果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;
}
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
的大小,或者直接使用文字字符串调用system
: system("./test1")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.