GETUTENT(3) | Linux Programmer's Manual | GETUTENT(3) |
名前
getutent, getutid, getutline, pututline, setutent, endutent, utmpname - utmp ファイルのエントリにアクセスする書式
#include <utmp.h>説明
新しいアプリケーションでは、これらの関数の "utmpx"版を使用すべきである。これらは POSIX.1 で規定されている。「準拠」の節を参照。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 は静的な記憶領域に確保され、次にこれらの関数を呼び出した際に上書きされるかもしれない。エラー
- ENOMEM
- メモリ不足。
- ESRCH
- レコードが見つからなかった。
関数 setutent(), pututline(), getut*() は open(2) に書かれている理由でも失敗することがある。
ファイル
/var/run/utmp 現在ログイン中のユーザーのデータベース準拠
XPG2, SVr4.XPG2 と SVID 2 では、 pututline() 関数は値を返さないとされており、 (AIX, HP-UX, Linux libc5 などの) 多くのシステムではそうなっている。 HP-UX では、上述の pututline() と同じプロトタイプを持つ新しい関数 _pututline() が導入されている (この関数は Linux libc5 にもある)。
現在では、Linux 以外のシステムでは、これらの関数は全て廃止されている。 SUSv1 の後に出てきた POSIX.1-2001 では、もはやこれらの関数はなく、代わりに以下のものを使う。
#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) が追加されている。#define _GNU_SOURCE /* or _SVID_SOURCE or _BSD_SOURCE;
feature_test_macros(7) 参照 */
#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 );
例
以下の例では、 utmp のレコードの追加・削除を行っている。このコードは、擬似端末 (pseudo terminal) から実行されることを想定している。実際のアプリケーションでは getpwuid(3) と ttyname(3) の戻り値を検査するべきである。
#include <string.h>
#include <stdlib.h>
#include <pwd.h>
#include <unistd.h>
#include <utmp.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 プロジェクトのリリース 3.51 の一部である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。2008-06-29 |