So I have a program that calls execvp() as seen below
void ext_com(char* buffer){
char **command;
pid_t child_pid;
command = get_input(buffer);
child_pid = fork();
if(child_pid<0){
perror("failed");
exit(1);
}
if (!child_pid) {
/* Never returns if the call is successful */
int ret= execvp(command[0], command);//call ls
if(ret == -1){
printf("bad command\n");
last_exit = ret;
exit(ret);
}
} else {
int stat_loc;
run_pid = child_pid;
waitpid(child_pid, &stat_loc, WUNTRACED) &255;
last_exit=stat_loc;
}
free(command);
}
Which has last_exit as a global int, last_exit status is not 0 when I run the command correctly nor is it -1 when I run a bad command, it also is not 1 when I run some non existent flag such as ls 444. It sometimes does return a number between 1 and 255 however is this behaviour wrong (apart from returning non zero when execvp() is called correctly), and how do I fix it.
Thank you
Regarding
fork()When you
fork()a child process, the child gets a copy of its parent's memory. Except to the extent that you leverage a shared-memory mechanism, the child cannot communicate with the parent via variables, no matter their scope or linkage.In particular, in this code fragment ...
... the assignment to
last_exitis useless, because the (only) process it affects terminates immediately afterward.Regarding
execvp()Whether the program's arguments are valid is a matter that the program itself decides. It doesn't get to the point of making such evaluations unless it is successfully launched.
execvp()'s return value is not associated with the exit status or any other behavior of the program it launches. It does not wait for that program to complete, so that that information is even available to it.execvp()does not return if it is able to launch the specified program at all, and it fails (returning -1) only if it cannot do so. Note that this means you never have to test its return value -- if the function returns at all then you know without checking that the return value was -1. Failures typically are the result of the specified program not being found, not being accessible for read and execution, or not having a recognized executable format.If you want to know about that program's exit status then the parent process (the one that
fork()ed the child in which theexecvp()call was performed) mustwait()orwaitpid()for it, and use the information provided by that function.Regarding
exit()andwaitpid()Although
exit()accepts anintargument, the exit status available from thewait()family of functions (or from a shell) conveys only 8 bits of exit-status information. In particular, the argument toexit()is not conveyed in whole to the parent viawaitpid(). The exit status available that way (in the event that the program terminates normally) is a number between 0 and 255.The status code provided by the
wait-family functions conveys multiple pieces of information, includingwaitreturned because) the process was continued from a stopped stateYou should use the macros defined for extracting these details from the status code (see the documentation for
wait()et al.). If you want to determine the child's exit status then you should first useWIFEXITED(stat_loc)to verify that it terminated normally at all. Supposing that it did,WEXITSTATUS(stat_loc)will give you the exit status, which, again, has only 8 significant bits. If the child terminates by callingexit(-1)then you should expect the status reported viawaitpid()to be 255.