GETUTENT(3)

名前
getutent, getutid, getutline, pututline, setutent, endutent, utmpname - utmp ファイルのエントリーにアクセスする

書式
#include <utmp.h>

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);

説明
新しいアプリケーションでは、これらの関数の "utmpx" 版を使用すべきである。 これらは POSIX.1 で規定されている。「準拠」の節を参照。

utmpname() は、他の utmp 関数がアクセスする (utmp フォーマットの) ファイルの名前を指定する。他の関数を使う前に utmpname() を使って ファイル名の指定を行わなかった場合は、 <path.h> で 定義されている _PATH_UTMP がファイル名とみなされる。

setutent() は、ファイルポインターを utmp ファイルの先頭に移動する。 一般的には、他の関数を使う前にこの関数を呼び出しておくと良いだろう。

endutent() は utmp ファイルをクローズする。ユーザーコードで 他の関数を使ってこのファイルにアクセスを行った時は、最後にこの関数を 呼び出すべきである。

getutent() は utmp ファイルの現在のファイル位置から一行読み込み、 行の各フィールドの内容を収めた構造体へのポインターを返す。 この構造体の定義は utmp(5) に書かれている。

getutid() は、 utmp ファイル中の現在の位置から順方向 (末尾に向かう方向) へ ut に基く検索を行う。 ut->ut_type が RUN_LVL, BOOT_TIME, NEW_TIME, OLD_TIME の いずれかなら、 getutid() は ut_type フィールドが ut->ut_type に一致する最初のエントリーを探す。 ut->ut_type が INIT_PROCESS, LOGIN_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 ファイルに書き出す。 pututline() は getutid() を用いて、新たなエントリーを 挿入するのにふさわしい場所を探す。 ut を挿入するふさわしい場所が 見つからない場合は、新たなエントリーをファイルの末尾に追加する。

返り値
getutent(), getutid(), getutline() は、成功すると struct utmp へのポインターを返す。 失敗すると NULL を返す (レコードが見つからなかった場合も失敗となる)。 この struct utmp は静的な記憶領域に確保され、次にこれらの関数を 呼び出した際に上書きされるかもしれない。

pututline() は成功すると ut を返す。失敗すると NULL を返す。

utmpname() は、新しい名前の格納に成功すると 0 を返し、失敗すると -1 を返す。

エラーが発生した場合、これらの関数は errno にエラーの原因を示す値を設定する。

エラー

ENOMEM
    メモリー不足。

ESRCH
    レコードが見つからなかった。

関数 setutent(), pututline(), getut*() は open(2) に書かれている理由でも失敗することがある。

ファイル

/var/run/utmp
    現在ログイン中のユーザーのデータベース

/var/log/wtmp
    ユーザーログインの履歴データベース

属性
この節で使用されている用語の説明については、 attributes(7) を参照。
インターフェース | 属性 | 値
getutent() | Thread safety | MT-Unsafe init race:utent race:utentbuf sig:ALRM timer
getutid(), getutline() | Thread safety | MT-Unsafe init race:utent sig:ALRM timer
pututline() | Thread safety | MT-Unsafe race:utent sig:ALRM timer
setutent(), endutent(), utmpname() | Thread safety | MT-Unsafe race:utent

In the above table, utent in race:utent signifies that if any of the functions setutent(), getutent(), getutid(), getutline(), pututline(), utmpname(), or endutent() are used in parallel in different threads of a program, then data races could occur.

準拠
XPG2, SVr4.

XPG2 と SVID 2 では、 pututline() 関数は値を返さないとされており、 (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 と同じになっている。 完全を期すために、glibc では utmpxname() も提供している。この関数は POSIX.1 では規定されていない。

Linux 以外のシステムでは、 utmpx 構造体は utmp 構造体の上位集合 (superset) になっていて、 追加のフィールドがあったり、既存のフィールドのサイズが大きくなっていたり するものもある。複数のファイルが使用されている場合もあり、多くの場合 /var/*/utmpx と /var/*/wtmpx というファイルが使われる。

一方、 Linux glibc では複数の utmpx ファイル は使われていない。 utmp 構造体が十分に大きいからである。 上記の名前に "x" が付いた関数は "x" が付いていない対応する関数の別名と なっている (例えば getutxent() は getutent() の別名である)。

注意

  glibc での注意
上記の関数群はスレッドセーフではない。 glibc にはリエントラント版 (reentrant) が追加されている。

#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 のレコードの追加・削除を行っている。このコードは、 擬似端末 (pseudo terminal) から実行されることを想定している。 実際のアプリケーションでは 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)

この文書について
この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。