曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 5965|回复: 0
打印 上一主题 下一主题

utmpx 结构

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2011-12-31 22:57:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
utmpwtmp 这两个文件包含了 utmpx 结构记录。utmpx 结构定义在 <utmpx.h> 头文件中。可以通过命令 man 5 utmpx 获得更详细的说明信息:
[C++] 纯文本查看 复制代码
/* Values for ut_type field, below */

           #define EMPTY         0 /* Record does not contain valid info
                                      (formerly known as UT_UNKNOWN on Linux) */
           #define RUN_LVL       1 /* Change in system run-level (see
                                      init(8)) */
           #define BOOT_TIME     2 /* Time of system boot (in ut_tv) */
           #define NEW_TIME      3 /* Time after system clock change
                                      (in ut_tv) */
           #define OLD_TIME      4 /* Time before system clock change
                                      (in ut_tv) */
           #define INIT_PROCESS  5 /* Process spawned by init(8) */
           #define LOGIN_PROCESS 6 /* Session leader process for user login */
           #define USER_PROCESS  7 /* Normal process */
           #define DEAD_PROCESS  8 /* Terminated process */
           #define ACCOUNTING    9 /* Not implemented */

           #define UT_LINESIZE      32
           #define UT_NAMESIZE      32
           #define UT_HOSTSIZE     256

           struct exit_status {              /* Type for ut_exit, below */
               short int e_termination;      /* Process termination status */
               short int e_exit;             /* Process exit status */
           };
 struct utmp {
               short   ut_type;              /* Type of record */
               pid_t   ut_pid;               /* PID of login process */
               char    ut_line[UT_LINESIZE]; /* Device name of tty - "/dev/" */
               char    ut_id[4];             /* Terminal name suffix,
                                                or inittab(5) ID */
               char    ut_user[UT_NAMESIZE]; /* Username */
               char    ut_host[UT_HOSTSIZE]; /* Hostname for remote login, or
                                                kernel version for run-level
                                                messages */
               struct  exit_status ut_exit;  /* Exit status of a process
                                                marked as DEAD_PROCESS; not
                                                used by Linux init(8) */
               /* The ut_session and ut_tv fields must be the same size when
                  compiled 32- and 64-bit.  This allows data files and shared
                  memory to be shared between 32- and 64-bit applications. */
           #if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
               int32_t ut_session;           /* Session ID (getsid(2)),
                                                used for windowing */
               struct {
                   int32_t tv_sec;           /* Seconds */
                   int32_t tv_usec;          /* Microseconds */
               } ut_tv;                      /* Time entry was made */
           #else
                long   ut_session;           /* Session ID */
                struct timeval ut_tv;        /* Time entry was made */
           #endif

               int32_t ut_addr_v6[4];        /* Internet address of remote
                                                host; IPv4 address uses
                                                just ut_addr_v6[0] */
               char __unused[20];            /* Reserved for future use */
           };

对于一个登录进程来说,ut_lineut_id 存储了登录的设备信息。比如我们用直接运行 who 命令时,打印出来的第二列就是 ut_line 所存储信息,比如 pts/0,pts/1,tty/1 等;而 ut_id 则这些设备的后缀,如 /0, /1, /2 等。关于终端的一些概念可参考:http://www.groad.net/bbs/read.php?tid-5794.html

在一个窗口环境里,一些终端模拟器(虚拟终端,比如 putty, xshell 等)会使用 ut_session 这个域来记录该终端窗口的会话ID。关于会话ID可参考:getsid() -- 获得会话ID

ty_type 是一个整型值,它定义了写到 utmp 文件中的记录的类型。该值是可能是下面的一组常数中的一个:

EMPTY (0)
表示记录不包含有效的账号信息。

RUN_LVL (1)
表示记录了系统运行等级(run-level)的改变。关于系统运行等级的更多信息可以通过 man init 来查看。

BOOT_TIME (2)
表示记录了系统开机时间,该时间由 ut_tv 域给出。通常 RUN_LVL 和 BOOT_TIME 是由 init 程序记录的,它们会被写到 utmp 和 wtmp 两个文件中。

NEW_TIME (3)
表示记录了系统时钟改变后所使用的新的时间,该时间值由 ut_tv 给出。

OLD_TIME (4)
表示记录了在系统时钟改变前使用的旧的时间,该时间值由 ut_tv 给出。OLD_TIME 和 NEW_TIME 会由 NTP (或类似程序)守护进程在系统时钟改变时写到 utmp 和 wtmp 文件中。

INIT_PROCESS (5)
表示记录了一个由 init 衍生出来的进程,比如 getty 。可参考 inittab 获得更多的细节信息。

LOGIN_PROCESS (6)
表示记录了一个登录用户的会话首进程,比如当你按下 Ctrl + Alt + F1 键到从 tty1 登录时,就会显示该记录类型。

USER_PROCESS (7)
记录一般用户进程,通常是一个登录的会话,登录用户的用户名记录在 ut_user 中。

DEAD_PROCESS (8)
表示记录一个已经结束了的进程。

INIT_PROCESS 通常由 getty (或相似的程序,如 agetty,mingetty)的调用而产生。在系统启动时,init 进程会为每个终端和虚拟控制台创建一个子进程,然后每个子进程就会执行(exec) getty 程序。getty 程序会打开终端并提示用户输入用户名,然后执行 login 程序。在用户验证成功并执行了一些其他的步骤后,login 就 fork 出一个子进程用以执行用户的登录 shell 。一个完整的登录会话生命周期由以下 4 个写到 wtmp 里的 4 个记录表示:

(1) 一条 INIT_PROCESS 记录,由 init 来写。
(2) 一条 LOGIN_PROCESS 记录,由 getty 来写。
(3) 一条 USER_PROCESS 记录,由 login 来写。
(4) 一条 DEAD_PROCESS 记录,在检测到一个 login 子进程结束时(用户退出或注销),该记录由 init 来写。

测试代码:
[C++] 纯文本查看 复制代码
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <utmpx.h>
#include <paths.h>

int main(int argc, char *argv[])
{
    struct utmpx *utp;

    setutxent();

    printf ("User     Type      PID   Line   Id        Host                Date/time\n");

    while ((utp = getutxent()) != NULL) {    /*顺序读取*/
        printf("%-8s ", utp->ut_user);
        printf("%-9.9s ", 
                (utp->ut_type == EMPTY) ?    "EMPTY" :
                (utp->ut_type == RUN_LVL) ?    "RUN_LVL" :
                (utp->ut_type == BOOT_TIME) ?    "BOOT_TIME" :
                (utp->ut_type == NEW_TIME) ?    "NEW_TIME" :
                (utp->ut_type == OLD_TIME) ?    "OLD_TIME" :
                (utp->ut_type == INIT_PROCESS)? "INIT_PR" :
                (utp->ut_type == LOGIN_PROCESS)? "LOGIN_PR" :
                (utp->ut_type == USER_PROCESS) ? "USER_PR" :
                (utp->ut_type == DEAD_PROCESS) ? "DEAD_PR" : "???");
        printf ("%-5d %-6.6s %-9.9s %-20.20s ", (long)utp->ut_pid, utp->ut_line, utp->ut_id, utp->ut_host);

        printf ("%s", ctime((time_t *) & (utp->ut_tv.tv_sec)));

    }
    endutxent();

    exit (EXIT_SUCCESS);
}

运行输出:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

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

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-2 22:56 , Processed in 0.086914 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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