Reputation: 5741
I would like to execute an executable file whose main() returns 2 using system()
.
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
#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
.
Upvotes: 4
Views: 5733
Reputation: 385655
Quote man 3 system
:
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 inwait
(2). Thus, the exit code of the command will beWEXITSTATUS(status)
.
man 2 wait
shows the other information packed into the status
returned by system
(3).
512
means the program exited with exit status 2.2
would mean the program was killed by signal 2 (SIGINT).Note that that the string ./test1
takes 8 characters because of the trailing NUL. Your strcpy
is clobbering some memory outside of 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")
Upvotes: 6
Reputation: 22374
The return value of system is actually the return value of waitpid() under POSIX.
status
actually has a lot of information embedded in it:
From the system(3) manpage:
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).
WIFSIGNALED(status)
True
if the process terminated due to receipt of a signal.
WIFSTOPPED(status)
True
if the process has not terminated, but has stopped and can be restarted.
This macro can be true only if the wait call specified theWUNTRACED
option or if the child process is being traced (see 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.
WTERMSIG(status)
If
WIFSIGNALED(status)
istrue
, evaluates to the number of the signal that caused the termination of the process.
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.
WSTOPSIG(status)
If
WIFSTOPPED(status)
istrue
, evaluates to the number of the signal that caused the process to stop.
#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;
}
Upvotes: 8
Reputation: 11706
This is, in fact, undefined behavior. command
only holds 7 characters, but your string "./test1"
has 8, including the null-terminator. You'll need to either increase the size of command
, or just call system
directly with the literal string: system("./test1")
Upvotes: 0