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
にはリエントラント版
(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/
に書かれている。