您的位置:首页 > 运维架构 > Linux

linux编写终端注销小程序

2013-01-13 13:18 232 查看

一.注销过程

1.基本步骤:

(有关 utmp 的内容参见 :who命令的编写

注销过程中,系统改变了文件utmp中相应的登录记录,注销过程如下:

(1).打开文件utmp;

(2).从utmp中找到包含你所在终端的登录记录;

(3).对当前记录做修改;

(4).关闭文件;

其中要注意的是第3步:对当前记录做修改。

2.对当前记录做修改:

(1)把ut_type的值从USER_PROCESS DEAD_PROCESS;

(2)把ut_time字段的值改为注销时间,即当前时间;

(3)有些版本会把用户名和远程主机字段的内容清空;

除以上步骤外:最棘手的是如何把修改过阿记录写回文件?不能用write,write只会更新下一条记录,而不是当前那条要修改的记录。因为系统每次打开一个文件都会保存一个指向文件当前位置的指针,当读写完成时,指针都会移向下一个记录位置,这个指针与文件描述符相关联。如何操作呢?可以使用系统调用 lseek 。

指针是与文件描述符相关联的,而不是与文件关联 ,所以如果两个程序同时打开一个文件,这时会有两个指针,两个程序对文件的读操作不会互相干扰。lseek改变文件描述符所关联的指针位置。

3.lseek函数

目标 使指针指向文件中的指针位置

头文件 #include<sys/type.h>

#include<unistd.h>

函数原型 off_t currpos = lseek( int fd , off_t dist , int base );

参数 fd:文件描述符 ; dist:移动的距离 (可以为负);

base :SEEK_SET 文件的开始 ; SEEK_CUR 文件当前; SEEK_END 文件结尾 ;

返回值 -1 遇到错误 ;

二.代码实例

程序需要在终端下以root身份运行,如 #: ./a.out pts/1

( pts/1 为一个打开的终端用户 )

#include <stdio.h>
#include<stdlib.h>
#include <unistd.h>
#include<utmp.h>
#include<fcntl.h>
#include<string.h>
#include<time.h>

int logout_tty(char *line);
int main(int ac,char * av[])
{
if(ac != 2)
{
puts("参数个数不正确\n");
exit(1);
}
char line[32];
strcpy(line,av[1]);
logout_tty(line);
return EXIT_SUCCESS;
}
int logout_tty(char *line)
{
int         fd;
struct utmp rec;
int         len = sizeof(struct utmp);
int         retval = -1;
// 此处  O_RDWR 需要root用户运行
if((fd = open(UTMP_FILE , O_RDWR)) == -1)
{
perror(UTMP_FILE);
return -1;
}
off_t pos;
while(read(fd,&rec,len) == len)
{
if(strncmp(rec.ut_line,line,sizeof(rec.ut_line)) == 0)
{
rec.ut_type = DEAD_PROCESS;
if(time(&rec.ut_time) != -1)
if( (pos=lseek(fd,-len,SEEK_CUR) )!= -1)
if(write(fd,&rec,len) == len)
retval = 0;
break;
}
}
if(close(fd) == -1)
retval = -1;
return retval;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: