Linux mesg命令的简单实现


 实验题目:不想被那些发送 write 的人打扰的用户可以使用命令 mesg。阅读 mesg.通过程 序试验以

了解它如何工作,然后写)个这样的程序。


首先我们得知道mesg命令是做什么的。实际上, mesg命令决定是否允许其他人传讯息到自己的终端机界面

y : 允许讯息传到终端机 界面上。
n : 不允许讯息传到终端机 界面上 。
如果没有设定,则讯息传递与否则由终端机界面目前状态而定。
打开一个终端(terminal),就会在/dev/pts下生成一个表示这个终端的文件。这时我们可以通过tty命令看下目前所在的终端的文件名:
lwq@ubuntu:~$ tty
       /dev/pts/0
我目前打开的终端文件名是/dev/pts/0.
进一步地我们应该想到,当我在终端/dev/pts/0上执行mesg n命令后,其他的用户将不能通过write命令和我进行聊天,为什么?在上一篇实验总结上,我们已经知道write名令其实就是对终端文件的读写操作,执行mesg n命令后其他用户不能向dev/pts/0进行写操作了。也就是说其他用户对该终端文件的写权限变了。我们可以验证下。
下面是我在我的ubuntu上输入与mesg相关命令后的结果:
1、输入mesg y
lwq@ubuntu:~$ mesg y
结果是把其他用户对该终端文件的可写位置为1。
输入指令:ls -l /dev/pts/0
lwq@ubuntu:~$ ls -l /dev/pts/0
结果为:
       crw--w---- 1 lwq tty 136, 0 2013-05-11 05:55 /dev/pts/0
注意这个 crw--w----,看到了吧,其他用户对该终端文件的可写位(从左往右数第六位)为1。再执行下mesg n指令,让后再查看下其他用户对该终端设备的可写权限变了没。结果如下:
lwq@ubuntu:~$ mesg n
       lwq@ubuntu:~$ ls -l /dev/pts/0
       crw------- 1 lwq tty 136, 0 2013-05-11 06:11 /dev/pts/0
注意,crw-------,第六位已经由可写w变成了不可写-。
到现在我们已经知道,mesg指令是通过修改权限位来实现的,因此我们的简单版本的mesg也可以通过修改权限位来实现。
你可能又会问了,怎么知道我现在打开的终端的文件名,用tty吗?可是用代码怎么实现啊?不会是要研究内核代码吧?这个也是困扰我的主要问题,查了好多资料,都没有一个好的解决办法。最后,我是通过在代码(我是用c语言实现的)中执行shell脚本解决的。代码如下:
#include <stdlib>
void main(){
......//定义
......//其他的部分
system("tty>output.txt");
.....//其他部分
}
就是 system("tty>output.txt");把当前终端文件名写入到了output.txt,然后接着从output.txt读入文件名,根据该文件名找到他的信息(stat函数)。
分析完毕,下面是一个模拟mesg命令的简单代码实现。
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>

#define MASKGW 16
#define SETGW0 65519
#define SETGW1 16

/*
	
*/
int main(int ac, char *argv[]){
	char tty_name[255];
	int fd;
	int length;
	struct stat info;
	int state;
	//output the tty name to output.txt
	system("tty>output.txt");
	if( (fd = open( "output.txt", O_RDONLY )) == -1 ){
		printf("file open error\n");
		exit( 1 );
	}
	//read the tty name and save it to the array tty_name
	if((length = read( fd, tty_name, 255 ))<0){
		printf("file read error\n");
		exit( 1 );
	}
	close( fd );
	tty_name[--length] = '\0';
	if( stat( tty_name, &info ) == -1){
		perror(tty_name);
		exit( 1 );
	}
	if( ac == 1 ){
		state = ((info.st_mode)&MASKGW);
		if( state == 16 )
			printf("is y\n");
		else
			printf("is n\n");
		exit( 0 );
	}
	//change group w according to 'y' and 'n'
	if( (strcmp(argv[1],"y")) == 0 )
		info.st_mode =	(info.st_mode)|SETGW1;

	else
		info.st_mode = (info.st_mode)&(SETGW0);
	//set group w
	chmod(tty_name, info.st_mode);
}

你可能感兴趣的:(Linux mesg命令的简单实现)