C语言操作utmp文件获取用户登录状态

Aria
Aria
发布时间:2026-10-13 | 3人浏览过
原创

在Linux系统编程中,utmp文件记录了当前登录系统的用户信息。本文将详细解析C语言中操作该文件的三个关键API:getutent()、setutent()和endutent(),并通过实例展示如何遍历并筛选用户进程记录。

结果与目标

通过调用标准库函数,读取/var/run/utmp(或系统配置的文件路径)中的条目,获取特定类型(如USER_PROCESS)的登录会话详情,包括用户名、终端设备、远程主机IP等信息。

准备条件

  1. 环境要求:GNU/Linux操作系统,安装GCC编译器。
  2. 头文件依赖:需包含<utmp.h>以获取结构体定义及函数原型。
  3. 权限说明:utmp文件通常为只读,但可能需要具备相应权限才能访问所有条目。

真实操作顺序

第1步:包含必要头文件

目的:引入定义struct utmp及相关常数的接口。

#include <stdio.h>
#include <utmp.h>

第2步:初始化并打开utmp文件

目的:确保读取位置指向文件起始处。getutent()在首次调用时会自动打开文件,但显式调用setutent()可重置内部文件指针,便于重复遍历。

setutent();

第3步:循环读取登录数据

目的:逐条获取登录记录,直到返回NULL表示结束。重点筛选类型为USER_PROCESS的有效用户会话。

  • 入口:getutent()函数。
  • 动作:struct utmp *u = getutent();。若返回非空指针,则解引用结构体检查u->ut_type。
  • 重要参数:
    • ut_type:记录类型,常见值包括USER_PROCESS(一般用户进程)、LOGIN_PROCESS(登录进程)等。
    • ut_user:登录账号名。
    • ut_line:终端设备名(如pts/0)。
    • ut_host:远程主机地址。
while((u = getutent()) != NULL) {
    if(u->ut_type == USER_PROCESS) {
        printf("Type: %d\nUser: %s\nLine: %s\nHost: %s\n", 
               u->ut_type, u->ut_user, u->ut_line, u->ut_host);
    }
}

第4步:关闭文件描述符

目的:释放资源。当不再需要读取或需要重新从头遍历时,应调用此函数。

endutent();

结构体详解:struct utmp

getutent()返回的struct utmp包含以下关键字段:

成员变量 类型 说明
ut_type short int 记录类型(如USER_PROCESS, BOOT_TIME等)
ut_pid pid_t 关联进程的PID
ut_line char[UT_LINESIZE] 终端线路名(省略了/dev/前缀)
ut_user char[UT_NAMESIZE] 登录用户名
ut_host char[UT_HOSTSIZE] 远程主机名称或IP地址
ut_tv struct timeval 登录时间戳

常见ut_type常量

  • EMPTY:空记录。
  • RUN_LVL:运行级别改变记录。
  • BOOT_TIME:系统开机时间。
  • INIT_PROCESS:由init衍生的进程。
  • LOGIN_PROCESS:登录处理进程。
  • USER_PROCESS:普通用户进程(通常关注此项)。
  • DEAD_PROCESS:已结束的进程记录。

完整示例代码

以下代码演示如何遍历并打印所有活跃的用户进程登录信息:

#include <stdio.h>
#include <utmp.h>

int main() {
    struct utmp *u;
    
    // 确保从头开始读取
    setutent();
    
    while((u = getutent()) != NULL) {
        // 仅处理用户进程
        if(u->ut_type == USER_PROCESS) {
            printf("PID: %d | User: %s | Line: %s | Host: %s\n",
                   u->ut_pid,
                   (u->ut_user[0] != '\0') ? u->ut_user : "(null)",
                   u->ut_line,
                   (u->ut_host[0] != '\0') ? u->ut_host : "(local)");
        }
    }
    
    // 关闭文件
    endutent();
    
    return 0;
}

简要总结

通过getutent()系列函数,开发者可以轻量级地接入系统登录状态监控。关键在于正确识别ut_type以过滤无效记录,并在结束后调用endutent()保持文件句柄清洁。以上就是C语言中操作utmp文件的相关函数用法的详细内容,更多关于C语言系统编程的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表