Linux write指令的代码实现(自己编写实现)

系统:ubuntu10.10

实验题目: 编写⼀个 write 简单版本,能够接受用户名作为参数,并 在屏幕上显示你想通信
的用户。查看 write 的标准版本显示的内容。 你的程序应该可以处理这样的特殊情况:你想
聊天的人可能没有登录。另⼀方 面,你想聊天的人可能登录了若干个终端。

 

解决过程:

记得当时安装虚拟系统时,只设定了一个用户,为了做这个实验我必须添加几个用户。如果你系统中已经有多个用户可以省略这一步。

step1、建立多个用户

建立用户的命令为:sudo useradd -d /usr/sam -m sam

建立一个名字叫sam的用户,使用sudo是因为权限不够,必须在root下才能使用useradd,所以在非root下必须添上sudo。注意这时你还不能使用这个用户名登陆,为什么?因为你还没给他授权啊!怎么授权,很简单,给他个密码就得了。

给新建的用户添加密码:sudo passwd sam

然后根据提示输入新密码。

至此用户创建完毕,你可以switch user试试成功没有。

step2、通过用户名找到所在的终端

思路是从utmp文件中根据用户名进行搜索,找到和目的用户名相同的记录,并保存。注意满足条件的记录可能有多条,因为那个用户可能打开了多个终端。所以我们得用一个数组存储。这个数组只要存储tty名字就行了。下面就是这个函数的代码。

 
char **
get_tty( char *logname )
/*
 * purpose: find the tty at which 'logname' is logged in
 * returns: a string or NULL if not logged in
 *  errors: does not handle multiple logins 
 */
{
	static struct utmp utrec[MAX];/* set static because retval is a local value */
	int	      utfd;
	int	      namelen = sizeof( utrec[0].ut_name );
	char	      *retval[MAX] = {NULL} ;
	int 	      index = 0;

	if ( (utfd = open( UTMP_FILE, O_RDONLY )) == -1 )   /* open utmp */
		return NULL;

	/* look for a line where the user is logged in */
	while( read( utfd, &utrec[index], sizeof(struct utmp)) == sizeof(struct utmp) )
		if ( strncmp(logname, utrec[index].ut_name, namelen ) == 0 )/*  */
		{
			retval[index++] = utrec[index].ut_line ;
		}

	close(utfd);                                       /* close & go */
	return retval;
}


step3、通过向目标tty文件写入数据来达到聊天的目的

通过步骤2我们已经通过用户名获得了终端文件名。根据这个终端文件名我们就可以进行聊天了。上面提到了一个用户可能会打开多个终端,所以会有多个终端名,注意要有提醒用户做出选择的代码。接下来主要讲讲如何向对方的终端文件写入数据来达到聊天的目的。

假设tty_name是用户的打开的某个终端的文件名,首先打开这个终端文件:

sprintf(buf, "/dev/%s", tty_name);

fd = open( buf, O_WRONLY );

打开后就可以从键盘中读入,并把内容发送给对方:

while( fgets(buf, BUFSIZ, stdin) != NULL ){ /* write to user */

if ( write(fd, buf, strlen(buf)) == -1 )

  break;

}

到此,核心部分都已经描述清楚了。剩下的就是添砖加瓦,直到满足题目需求。


 

你可能感兴趣的:(Linux write指令的代码实现(自己编写实现))