我正在开发一个需要确定是否需要的应用程序
由进程打开的伪终端是其控制终端。我试着这么做
使用tcgetpgrp()
libc / system调用来实现此目的。
1)我注意到tcgetpgrp()
为主伪终端返回0
简单的应用如下。我在Linux 4.10.3上运行Glibc 2.25。
int main()
{
int master_fd = open("/dev/ptmx", O_RDWR);
grantpt(master_fd);
unlockpt(master_fd);
char *slave_pty = ptsname(master_fd);
int slave_fd = open(slave_pty, O_RDWR);
struct termios term;
tcgetattr(slave_fd, &term);
term.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
tcsetattr(slave_fd, TCSANOW, &term);
if (fork()) {
// parent
close(slave_fd);
while (1) {
pid_t pgrp = tcgetpgrp(master_fd);
// tcgetpgrp on master_fd returns 0
printf("tcgetpgrp returned: %d\n", pgrp);
sleep(1);
}
} else {
// child
close(master_fd);
while (1) {
pid_t pgrp = tcgetpgrp(slave_fd);
// tcgetpgrp on slave_fd returns -1
printf("tcgetpgrp returned: %d\n", pgrp);
sleep(1);
}
}
return 0;
}
2)tcgetpgrp()
的Linux手册页说:
当fd指呼叫的控制终端时 进程,函数tcgetpgrp()将返回前台进程 该终端的组ID(如果有),某些值更大 而不是目前不是进程组ID的1。什么时候 fd不是指呼叫的控制终端 进程,返回-1,并正确设置errno。
3)tcgetpgrp()
的POSIX手册页说:
成功完成后,tcgetpgrp()将返回 与之关联的前台进程的进程组ID的值 与终端。否则,返回-1并设置errno 表示错误。
4)通过libc源代码,我发现tcgetpgrp()
包装器的唯一功能
使用ioctl(TIOCGPGRP)
调用内核并转发返回值
给来电者。
除非我误解了它,否则Linux人似乎很暧昧 传递给tcgetpgrp的fd不是控制终端时会发生什么 调用过程。虽然第一句似乎是在说a 值>将返回1,第二句说-1将是 返回。
当手册页显示值>将返回1不是进程 小组,这是否意味着我必须通过所有过程的列表 系统中的组以确定返回值是否指向有效 进程组?
返回值0的含义是什么?这是一个有效的流程组吗?
我的程序中是否缺少某些内容?
我仍然试图通过内核源代码来追踪它......但确实如此 有谁知道这背后的历史?
(我的理解是主人通常不应该是控制终端,但系统调用行为和手册页上的解释似乎仍然很奇怪。)
感谢。