Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5513847
  • 博文数量: 922
  • 博客积分: 19333
  • 博客等级: 上将
  • 技术积分: 11226
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-27 14:33
文章分类

全部博文(922)

文章存档

2023年(1)

2020年(2)

2019年(1)

2017年(1)

2016年(3)

2015年(10)

2014年(17)

2013年(49)

2012年(291)

2011年(266)

2010年(95)

2009年(54)

2008年(132)

分类: LINUX

2012-01-17 22:07:47

++++++APUE读书笔记-09进程关系(05)++++++

 

6、控制终端
================================================
 会话和进程组有一些其它的特性:
 a.会话可以有一个单个的控制终端。这个控制终端一般都是我们登陆时候的终端设备(在终端登陆的情况下),或者是一个伪终端设备(在网络登陆的情况下)。
 b.建立到控制终端连接的会话leader被称作控制进程。
 c.在一个会话中的进程组可以被分成一个单一的前台进程组,以及一个或者多个后台进程组。
 d.如果一个session有一个控制终端,那么它有一个单一的前台进程组,这个session(session就是会话)其他的进程组是后台进程组。
 e.当我们键入终端的中断键(一般都是DELETE或者Control-C)的时候,会发送给所有在前台进程组中的进程一个中断信号。
 f.当我们敲入终端的quit键(一般是Control-backslash)的时候,这会导致一个quit信号发送给所有前台进程组的进程。
 g.如果一个modem(或者网络)的连接断开被终端的接口检测到了,那么会给控制进程(session leader)发送一个hang-up信号。
 参考资料给出了一个图描述了这个叙述。这里不给出原图形了,简单总结原图的意思就是:
 a.controlling terminal在检测到modem disconnect之类的情况的时候会给login shell(也是后台进程组中的进程,也是session leader,也是控制进程)发送hang-up信号。
 b.终端输入或者终端发起的信号会发送给session中的前台进程组。
 c.另外,一个session中还有可能存在其他的后台进程组。

 一般来说,我们不用担心控制终端,因为在我们登陆进去的时候它会自动被建立。
 POSIX.1把分配控制终端机制留给了各自实现。
 从UNIX System V继承过来的系统,会在session leader打开第一个没有和session建立联系的终端设备的时候分配一个控制终端.当然这假设session leader调用的open没有指定O_NOCTTY标志。
 基于BSD的系统会在session leader调用ioctl(有一个TIOCSCTTY请求参数,第三个参数是空指针)的时候给一个session分配一个控制终端。在调用之前,session不能已经有了controlling terminal(否则调用不成功).一般来说,这个ioctl调用后面需要接着一个setsid调用,这个调用保证进程是一个没有控制终端的session leader.在BSD系列的系统中,POSIX.1中open的O_NOCTTY标记并没有使用,除非是要和其他系统相互兼容的时候。

 有时候一个程序想要和controlling terminal进行交互,并且不考虑标准输入输出是否被重新定向了。程序用来确保自己是要和controlling terminal进行交互的方法是通过打开/dev/tty文件.这个特殊文件在内核中和controlling terminal是同义的。一般来说,如果程序没有controlling terminal,那么打开这个设备文件会失败。
 一个经典的例子是getpass函数,这个函数读取密码(这时候terminal 的echo是关闭的).这个函数被crypt程序调用,可以在管道中使用。例如:
 crypt < salaries | lpr
 解密salaries文件然后通过管道输出到打印池。因为crypt从标准输入读取输入文件,不用使用标准输入输入密码。并且,crypt程序每次运行的时候,需要输入加密的密码,这样我们就不用将密码保存在文件中了(保存在文件中有安全隐患)。
 有一些已知的方法将crypt使用的encoding给break,这里不说了。

参考:


7、tcgetpgrp, tcsetpgrp, 和 tcgetsid 函数
================================================
 我们需要一种方法来告诉内核哪个进程组是前台的,这个终端设备驱动知道向哪里发送终端输入以及终端产生的信号
 #include
 pid_t tcgetpgrp(int filedes);
 如果成功返回前台的进程组id,否则出错并返回1(其值实际为-1)。

 int tcsetpgrp(int filedes, pid_t pgrpid);
 如果成功返回0,否则出错并返回1(其值实际为-1)。

 tcgetpgrp函数返回和参数filedes相关的打开的终端的前台进程组id。
 如果进程有一个控制终端,那么函数tcsetpgrp会设置前台进程组id为pgrpid.pgrpid的值必须是当前同一个会话中的进程组id的值,filedes必须是session的控制终端的引用。
 大多数应用程序不会直接调用这两个函数,它们一般是被作业控制的shell来进行调用的。

 Single UNIX Specification定义了一个XSI扩展,叫做tcgetsid允许应用程序通过一个给定的控制tty的描述符号获得session leader的进程组id。
 #include
 pid_t tcgetsid(int filedes);
 如果成功返回session leader的进程组id,否则出错并返回1(其值实际为-1)。
 需要管理控制终端的应用程序可以使用tcgetsid函数来辨别控制终端session leader的session id(这个和session leader所在的进程组一样)。

参考:

 

 

阅读(688) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~