GETUTENT - Linux手册页

时间:2019-08-20 18:00:11  来源:igfitidea点击:

Linux程序员手册 第3部分
更新日期: 2020-06-09

名称

getutent,getutid,getutline,pututline,setutent,endutent,utmpname-访问utmp文件条目

语法

#包括

struct utmp * getutent(void);
struct utmp * getutid(const struct utmp * ut);
struct utmp * getutline(const struct utmp * ut);

struct utmp * pututline(const struct utmp * ut);

void setutent(void);
void endutent(void);

int utmpname(const char * file);

说明

新的应用程序应使用这些功能的POSIX.1指定的" utmpx"版本。请参阅遵循。

utmpname()为其他utmp函数设置utmp格式文件的名称。如果在使用其他函数之前未使用utmpname()设置文件名,则它们假定为_PATH_UTMP,如中所定义。

setutent()将文件指针后退到utmp文件的开头。通常,在其他任何函数之前调用它是一个好主意。

endutent()关闭utmp文件。当用户代码使用其他功能访问文件时,应调用该函数。

getutent()从utmp文件中的当前文件位置读取一行。它返回一个指向包含行字段的结构的指针。 utmp(5)中显示了此结构的定义。

getutid()根据ut从utmp文件中的当前文件位置向前搜索。如果ut-> ut_type是RUN_LVLBOOT_TIME,NEW_TIME或OLD_TIME之一,则getutid()将找到其ut_type字段与ut-> ut_type匹配的第一个条目。如果ut-> ut_type是INIT_PROCESSLOGIN_PROCESS,USER_PROCESS或DEAD_PROCESS之一,则getutid()将找到其ut_id字段与ut-> ut_id匹配的第一个条目。

getutline()从utmp文件中的当前文件位置向前搜索。它扫描ut_type为USER_PROCESS或LOGIN_PROCESS的条目,并返回其ut_line字段与ut-> ut_line匹配的第一个条目。

pututline()将utmp结构ut写入utmp文件。它使用getutid()搜索文件中的正确位置以插入新条目。如果找不到适合ut的插槽,pututline()会将新条目附加到文件末尾。

返回值

getutent(),getutid()和getutline()在成功时返回指向结构utmp的指针,在失败时返回NULL(包括"未找到记录"的情况)。此utmp结构分配在静态存储中,并可能被后续调用覆盖。

成功时pututline()返回ut;如果失败,则返回NULL。

如果新名称已成功存储,则utmpname()返回0;否则,则返回-1。

如果发生错误,则将这些功能errno设置为指示原因。

错误说明

ENOMEM
内存不足。
ESRCH
找不到记录。

由于open(2)中描述的原因,setutent(),pututline()和getut *()函数也会失败。

文件

/var/run/utmp
当前登录用户的数据库
/var/log/wtmp
过去用户登录的数据库

属性

有关本节中使用的术语的说明,请参见attribute(7)。

InterfaceAttributeValue
getutent()Thread safetyMT-Unsafe init race:utent
race:utentbuf sig:ALRM timer
getutid(),
getutline()
Thread safetyMT-Unsafe init race:utent
sig:ALRM timer
pututline()Thread safetyMT-Unsafe race:utent
sig:ALRM timer
setutent(),
endutent(),
utmpname()
Thread safetyMT-Unsafe race:utent

在上表中,race中的utent:utent表示是否在以下位置并行使用了setutent(),getutent(),getutid(),getutline(),pututline(),utmpname()或endutent()中的任何一个函数。程序的不同线程,则可能发生数据争用。

遵循规范

XPG2,SVr4。

在XPG2和SVID 2中,记录了功能pututline()返回void,这就是它在许多系统(AIX,HP-UX)上所做的事情。 HP-UX引入了新函数_pututline(),上面给出了pututline()的原型。

现在,所有这些功能在非Linux系统上都是过时的。 SUSv1之后的POSIX.1-2001和POSIX.1-2008没有任何这些功能,而是使用

#include <utmpx.h>

struct utmpx *getutxent(void);
struct utmpx *getutxid(const struct utmpx *);
struct utmpx *getutxline(const struct utmpx *);
struct utmpx *pututxline(const struct utmpx *);
void setutxent(void);
void endutxent(void);

这些函数由glibc提供,并执行与没有" x"的等效函数相同的任务,但是使用struct utmpx,在Linux上定义为与struct utmp相同。为了完整起见,尽管POSIX.1未指定此功能,但glibc还提供了utmpxname()。

在其他一些系统上,utmpx结构是utmp结构的超集,具有其他字段和现有字段的较大版本,并维护了并行文件,通常是/ var / * / utmpx和/ var / * / wtmpx。

另一方面,Linux glibc不使用并行的utmpx文件,因为它的utmp结构已经足够大。上面列出的" x"函数只是对应的别名(不带" x")(例如,getutxent()是getutent()的别名)。

备注

Glibc notes

上面的函数不是线程安全的。 Glibc添加可重入版本

#include <utmp.h>

int getutent_r(struct utmp *ubuf, struct utmp **ubufp);

int getutid_r(struct utmp *ut,
              struct utmp *ubuf, struct utmp **ubufp);

int getutline_r(struct utmp *ut,
                struct utmp *ubuf, struct utmp **ubufp);

glibc的功能测试宏要求(请参阅feature_test_macros(7)):

getutent_r(),getutid_r(),getutline_r():

_GNU_SOURCE
    || /* since glibc 2.19: */ _DEFAULT_SOURCE
    || /* glibc <= 2.19: */    _SVID_SOURCE || _BSD_SOURCE

这些函数是GNU扩展,与不带_r后缀的同名函数类似。 ubuf参数为这些函数提供了存储结果的地方。成功时,它们返回0,并将指向结果的指针写入* ubufp。错误时,这些函数将返回-1。以上功能没有utmpx等效项。 (POSIX.1未指定此类功能。)

示例

以下示例假定从伪终端中运行utmp记录,添加和删除该记录。为了在实际应用程序中使用,应检查getpwuid(3)和ttyname(3)的返回值。

#include <string.h>
#include <stdlib.h>
#include <pwd.h>
#include <unistd.h>
#include <utmp.h>
#include <time.h>

int
main(int argc, char *argv[])
{
    struct utmp entry;

    system("echo before adding entry:;who");

    entry.ut_type = USER_PROCESS;
    entry.ut_pid = getpid();
    strcpy(entry.ut_line, ttyname(STDIN_FILENO) + strlen("/dev/"));
    /* only correct for ptys named /dev/tty[pqr][0-9a-z] */
    strcpy(entry.ut_id, ttyname(STDIN_FILENO) + strlen("/dev/tty"));
    time(&entry.ut_time);
    strcpy(entry.ut_user, getpwuid(getuid())->pw_name);
    memset(entry.ut_host, 0, UT_HOSTSIZE);
    entry.ut_addr = 0;
    setutent();
    pututline(&entry);

    system("echo after adding entry:;who");

    entry.ut_type = DEAD_PROCESS;
    memset(entry.ut_line, 0, UT_LINESIZE);
    entry.ut_time = 0;
    memset(entry.ut_user, 0, UT_NAMESIZE);
    setutent();
    pututline(&entry);

    system("echo after removing entry:;who");

    endutent();
    exit(EXIT_SUCCESS);
}

另外参见

getutmp(3),utmp(5)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/