LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1916|回复: 16

如何禁止后台程序写终端?????

[复制链接]
发表于 2006-5-22 21:48:26 | 显示全部楼层 |阅读模式
目的是禁止某个后台程序运行时写终端,也就是将标准输出和标准出错全部扔掉,不让它显示

在书里面有介绍 获得和设置终端属性 的方法,用到下面两个函数:

  1. #include <termios.h>

  2. int   tcgetattr (int  filedes,  struct  termios   *termptr) ;
  3. int   tcsetattr (int  filedes,   int  opt,  const  struct  termios   *termptr) ;
复制代码

书里有一个介绍他用法的例程,懒得敲进来了,大家看看 http://www.mamiyami.com/document/apue/11.pdf
里面那个程序11-2就是啦,不过这个程序是使用屏蔽标志取或设置一个值,跟我的问题没有太大关系,

书里面提到一个终端标志:c_lflag 的 TOSTOP,
可以用这个标志来禁止后台程序写终端。以下是书里的说明:

  1. • TOSTOP (c_lflag, POSIX.1)如若设置,并且该实现支持作业控制,则将信号SIGTTOU送到试图写控制终端的
  2. 一个后台进程的进程组。按默认,此信号暂停该进程组中所有进程。如果写控制终端的进程忽略或阻塞此信号,
  3. 则终端驱动程序不产生此信号。
复制代码


我的问题来了:是不是要另外写一个程序(假设它为 A),在 A 里 tcsetattr() 函数设置TOSTOP 标志 。然后运行它,此时A 进程就会产生 SIGTTOU 信号。但光产生这个信号是毫无意义的,必须有一个企图写终端的后台进程(假设为B)也同时运行,这时 B 接收到 SIGTTOU 信号,于是它就不能向终端写东西了。

又或者我可以把A 设置为父进程,原本的后台程序 B 作为 A 的子进程,这样只要写一个程序(假设为AB)就可以了。如果后台运行AB,则作为父进程的 A 产生 SIGTTOU 信号,他儿子 B 接收到以后就没法再写终端了。不过这样做可行性也许不大。按照书里面的说法“将信号SIGTTOU送到试图写控制终端的一个后台进程的进程组”这是否就决定了 A 不能为后台进程??而B 必须是后台的??

我还是先试验一下吧,欢迎大家多给些宝贵意见,或者更合理的方法!目的才是最重要的,能禁止后台程序在终端乱嚷嚷就行~
发表于 2006-5-22 22:41:52 | 显示全部楼层
your_cmd > /dev/null 2>&1
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-5-22 23:26:28 | 显示全部楼层
能不能讲明白一点点呢?谢谢~~
回复 支持 反对

使用道具 举报

发表于 2006-5-23 10:20:49 | 显示全部楼层
就是将标准输出和标准出错全部扔掉,不让它显示
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-5-23 21:22:42 | 显示全部楼层
解决拉,程序如下:

  1. #include <termios.h>

  2. #include <unistd.h>

  3. int main()
  4. {
  5.     struct termios term;

  6.     if(tcgetattr(STDOUT_FILENO,&term)<0)
  7.          printf("tcgetattr error!\n");

  8.     term.c_lflag |= TOSTOP;

  9.     if(tcsetattr(STDOUT_FILENO,TCSANOW,&term)<0)
  10.          printf("tcsetattr error!\n");

  11.     return 0;
  12. }
复制代码


这个程序只要运行一次,以后运行的后台程序都无法在终端输出任何信息,就好像在终端输入命令“stty tostop”的效果一样 。至于把它作为后台程序的一个进程能不能也达到同样的效果,这个还没有试验,哪位有经验的多指教啦~~
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-5-23 21:26:00 | 显示全部楼层
可惜的是,这个程序经过交叉编译,移植到 arm 开发板上就不起作用了。开发板上也没有
“stty tostop”的命令。郁闷啊....
回复 支持 反对

使用道具 举报

发表于 2006-5-24 14:12:10 | 显示全部楼层
在开发板上即使写入了终端也没有关系吧, 反正也没人看得到. 而且二楼的兄弟已经指出了方法, 楼主为什么不试试
回复 支持 反对

使用道具 举报

发表于 2006-5-24 15:44:50 | 显示全部楼层
  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <stdio.h>
  4. int main(void)
  5. {
  6.         int fd_null;
  7.         fd_null = open("/dev/null",O_WRONLY);
  8.         dup2(fd_null,1);
  9.         dup2(fd_null,2);
  10.         system(your_command);
  11.         return 0;
  12. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-5-24 21:28:20 | 显示全部楼层
是不是这个意思,用终端设置函数调整的是整个终端的属性!

如果是自己写的程序的话,可以按照daemon进程的写法把终端i/o关闭!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-5-24 23:21:20 | 显示全部楼层
Post by DoDo
在开发板上即使写入了终端也没有关系吧, 反正也没人看得到. 而且二楼的兄弟已经指出了方法, 楼主为什么不试试


2楼的方法我看不懂啊:(看懂了一定试!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表