根据 man setpgid(2)
页面,
EACCES An attempt was made to change the process group ID of one of the children of the calling process and the child had already performed an execve(2) (setpgid(), setpgrp()).
ESRCH For getpgid(): pid does not match any process. For setpgid(): pid is not the calling process and not a child of the calling process.
根据描述errno应该是EACCES
。但为什么我得到的是 ESRCH
?
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
void print_errno() {
if (errno == EACCES) printf("errno: EACCES\n");
else if (errno == EPERM) printf("errno: EPERM\n");
else if (errno == ESRCH) printf("errno: ESRCH\n");
}
#define CHECK(syscall, msg) do { \
if ((syscall) == -1) { \
print_errno(); \
perror(msg); \
_exit(1); \
} \
} while(0)
int main () {
int ls_pid;
char *ls_argv[] = { "ls", NULL };
CHECK(ls_pid = fork(), "fork error");
if (!ls_pid) {
CHECK(execvp(ls_argv[0], ls_argv), "execvp error");
} else {
sleep(2);
CHECK(setpgid(ls_pid, ls_pid), "setpgid error");
CHECK(wait(NULL), "wait error");
printf("Finish\n");
}
}
最佳答案
specification of setpgid
没有说明当 pid 参数引用调用进程的 zombie 子进程时 setpgid
返回什么错误,无论它是否调用了 execve
。因此,这在技术上不是错误。
ESRCH
就有意义;它们只是需要保留的数据,直到有人开始调用 wait
。例如,当应用于僵尸时,kill
以 ESRCH
失败是很有意义的。
我想通过一些关于它的实际实现方式的观察来结束,但是,唉,我查看了 Linux 中 setpgid
的源代码,但无法弄清楚它会返回什么在这种情况下,因为 Linux 的 namespace 支持已将许多与进程相关的系统调用变成了可怕的意大利面条迷宫。所以后来我试图转而查看 FreeBSD,但我什至找不到源代码的相关部分,因为 FreeBSD 内核的文件级组织是不可理解的。所以你将不得不没有,抱歉。
关于c - 子僵尸进程的 setpgid 提供 ESRCH 而不是 EACCES?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48545762/