首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >终端访问控制问题

终端访问控制问题
EN

Stack Overflow用户
提问于 2013-10-12 04:16:58
回答 2查看 293关注 0票数 4

我正在尝试写一个外壳。在运行前台进程时,分叉进程管道将被赋予自己的进程组id。然后,终端被交给这个进程组id (使用tcsetpgrp),外壳等待它终止,然后再给自己终端控制。这个很好用。

出现的问题是当我试图运行后台进程时。同样,我给管道中的所有进程一个单独的进程组id,但是这次我不给这个组提供终端控制。在运行时,给定背景命令的输出被输出到终端(在它完成执行之前),并且终端同时给用户返回提示符。应该发生的是,尝试写入终端的子进程应该得到一个SIGTTOU,并且应该停止,但这显然不会发生。我验证了分叉进程都具有相同的进程组id,并且这个id与shell的不同。

退出shell (通过ctrl)并返回到运行它的标准bash shell时,因为在shell终止时我没有收获后台进程,后台进程继续运行(这是例外)。奇怪的是,这个过程继续将输出写入bash,即使它不是前台进程。这导致我得出结论,要么由于POSIX错误(不太可能),这个后台进程没有得到任何SIGTTOU,要么它正在处理它们(导致停止被忽略的默认操作),或者后台进程忽略SIGTTOU。

在执行分叉进程之前,是否有一种方法可以确保它在接收到SIGTTOU时停止(假设exec二进制文件不会更改任何内容)?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-12 05:22:47

SIGTTOU被发送到后台进程,该进程只有在为终端设置termios标志TOSTOP时才试图写入该终端。默认情况下,它通常不设置,在这种情况下,后台进程可以愉快地写入终端。( TOSTOP标志不影响读取权限。如果进程试图读取,它将被发送一个SIGTTIN。)

所以,是的,前台进程可以做一些事情:使用tcsetattr设置TOSTOP

票数 3
EN

Stack Overflow用户

发布于 2013-10-12 05:50:23

解决方案是让分叉进程在调用exec之前执行以下操作:

代码语言:javascript
复制
struct termios term; 
if (tcgetattr(STDIN_FILENO, &term) < 0)
        printf("ERROR\n");
    term.c_lflag = TOSTOP;
    if (tcsetattr(STDIN_FILENO,TCSANOW,&term)<0)
        printf("ERROR\n");
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19330488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档