waitpid
一次偶然的测试中,发现su程序的BUG后,着手排查问题出自哪。
首先是简化代码作为测试。
int main(int argc, char *const argv[])
{
pid_t pid = fork();
if (!pid)
{
execv("/bin/ping", argv);
//exit(3);
} else
{
int status =-1;
waitpid(pid, &status, 0);
printf("pppp exit = %d \n", status);
exit(status);
}
}
通过上面的例子,发现了子进程返回值的问题。
1.使用shell测试ping失败时返回值为1,但是status的值却为512, 整个程序的返回值却是0
2.使用 exit(1) exit(2) exit(3) 取代execv却发现了返回值为 256 512 768 的规律,瞬间清醒了!!
再一次仔细看编程手册,所有编程法的真相都在官方文档,不要相信搜到的奇怪代码!!!
如下是对返回值的处理,英语好一切皆美好,苍天饶过谁!
If status is not NULL, wait() and waitpid() store status information in the int to which it points.
This integer can be inspected with the following macros
(which take the integer itself as an argument, not a pointer to it, as is done inwait() and waitpid()!):
WIFEXITED(status)
returns true if the child terminated normally, that is, by calling exit(3) or _exit(2), or by returning from main().
WIFsignalED(status)
returns true if the child process was terminated by a signal.
手册上还贴心的给出了示例代码,怪我眼瞎无视各种英文!
if (WIFEXITED(status)) {
printf("exited, status=%d\n", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
printf("killed by signal %d\n", WTERMSIG(status));
} else if (WIFSTOPPED(status)) {
printf("stopped by signal %d\n", WSTOPSIG(status));
} else if (WIFCONTINUED(status)) {
printf("continued\n");
}
最后呢,改造一下这个程序。
这里我只会静静的等待程序运行完成,所以只需要WIFEXITED就结束了。
int main(int argc, char *const argv[])
{
pid_t pid = fork();
if (!pid)
{
execv("/bin/ping", argv);
} else
{
int status =-1;
waitpid(pid, &status, 0);
if (WIFEXITED(status)) {
exit(WEXITSTATUS(status));
}
exit(-1);
}
}
相关阅读
首先我们来了解一下所谓的僵尸进程,僵尸进程就是两个进程,一个父进程,一个子进程,其子进程终止后,0-3G的用户内存被回收,而3-4G的部分内