I read about APUE 3rd, 8.13, system Function, and I saw a version of system function implementation without signal handling.Code is like below:
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>
int system(const char *cmdstring) /* version without signal handling */
{
pid_t pid;
int status;
if (cmdstring == NULL)
return(1); /* always a command processor with UNIX */
if ((pid = fork()) < 0) {
status = -1; /* probably out of processes */
} else if (pid == 0) { /* child */
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
_exit(127); /* execl error */
} else { /* parent */
while (waitpid(pid, &status, 0) < 0) {
if (errno != EINTR) {
status = -1; /* error other than EINTR from waitpid() */
break;
}
}
}
return(status);
}
And the code used to test system function of this version is like below:
int main(void)
{
int status;
if ((status = system("date")) < 0)
err_sys("system() error");
pr_exit(status);
if ((status = system("nosuchcommand")) < 0)
err_sys("system() error");
pr_exit(status);
if ((status = system("who; exit 44")) < 0)
err_sys("system() error");
pr_exit(status);
exit(0);
}
And the result of the test code is shown by the picture(just ignore the Chinese in the result if you can't understand):
I wonder why will execl return if "nosuchcommand", which is not valid for /bin/sh, is given to /bin/sh. In my point of view, execl just replace the code of current process and then run from entry point, even though "nosuchcommand" is not valid for /bin/sh, it has nothing to do with execl but /bin/sh. So, how execl know "nosuchcommand" is not valid for /bin/sh to execute and return? Does execl treat /bin/sh differently by checking the command given to /bin/sh before executing /bin/sh so that it will know the invalid argument given to /bin/sh in advance? I know execl won't treat /bin/sh differently, so, how does execl know "nosuchcommand" is not valid for /bin/sh to execute and return?
sh -c nosuchcommand
itself returns 127. It's one of those return codes with a special meaning.
So I don't think you're seeing execl actually returning in this case.