whoコマンドを作成してみた。
Unix/Linuxプログラミング理論と実践Bruce Molayアスキー・メディアワークスこのアイテムの詳細を見る |
whoコマンドの作り方が載っていたので本の通り作成してみました。
内容は簡単でユーザのログイン情報が書き込まれるutmpというファイルを読み込んでutmp構造体にデータを格納し表示するだけです。
#include <stdio.h> #include <unistd.h> #include <utmp.h> #include <fcntl.h> #include <time.h> void show_info(struct utmp *); void show_time(long); int main() { struct utmp utbuf; int utmpfd; if ((utmpfd = open(UTMP_FILE, O_RDONLY)) == -1) { perror(UTMP_FILE); return 1; } while (read(utmpfd, &utbuf, sizeof(utbuf)) == sizeof(utbuf)) show_info(&utbuf); close(utmpfd); return 0; } void show_info(struct utmp *utbufp) { if (utbufp->ut_type != USER_PROCESS) return; printf("%-8.8s", utbufp->ut_name); printf(" "); printf("%-8.8s", utbufp->ut_line); printf(" "); show_time(utbufp->ut_time); if (utbufp->ut_host[0] != '\0') printf(" (%s)", utbufp->ut_host); printf("\n"); } void show_time(long timeval) { char *cp; cp = ctime(&timeval); printf("%12.12s", cp + 4); }
Fedora上では問題なくコンパイルが通り動いたのですがMac OS Xだといろんな箇所でコンパイルエラーになりうまくいきませんでした。
しかもutmpは非推奨とまでいわれる始末です。
more /usr/include/utmp.hでヘッダファイルの中身を見てみるとなんか構造が微妙に違うし...。
調べてみるとMac OS X Leopardではutmpではなくutmpxを使うのがお作法のようです。
で以下のように修正するとうまく動きました。
#include <stdio.h> #include <unistd.h> #include <utmpx.h> #include <fcntl.h> #include <time.h> void show_info(struct utmpx *); void show_time(long); int main() { struct utmpx utbuf; int utmpfd; if ((utmpfd = open(UTMPX_FILE, O_RDONLY)) == -1) { perror(UTMPX_FILE); return 1; } while (read(utmpfd, &utbuf, sizeof(utbuf)) == sizeof(utbuf)) show_info(&utbuf); close(utmpfd); return 0; } void show_info(struct utmpx *utbufp) { if (utbufp->ut_type != USER_PROCESS) return; printf("%-8.8s", utbufp->ut_user); printf(" "); printf("%-8.8s", utbufp->ut_line); printf(" "); show_time(utbufp->ut_tv.tv_sec); if (utbufp->ut_host[0] != '\0') printf(" (%s)", utbufp->ut_host); printf("\n"); } void show_time(long timeval) { char *cp; cp = ctime(&timeval); printf("%12.12s", cp + 4); }
Macはなんでutmpを非推奨にしてutmpxにしたんでしょう。
こういう微妙な違いが意外に面白かったりするんですけどね。