構造体(固定長)の入出力

システム・プログラム

                                       電子・情報工学系
                                       新城 靖
                                       <yas@is.tsukuba.ac.jp>

このページは、次の URL にあります。
http://www.hlla.is.tsukuba.ac.jp/~yas/coins/syspro-2000/2000-04-24 /struct.html
あるいは、次のページから手繰っていくこともできます。
http://www.hlla.is.tsukuba.ac.jp/~yas/coins/
http://www.is.tsukuba.ac.jp/~yas/index-j.html

■構造体(固定長)の入出力

高水準(ライブラリ)の入出力機能を使って構造体を読み書きするには、 fread(), fwrite() を使う。

ポータビリティ(別のOSやCPUのコンピュータでも使う)を考える時には、 文字コード、バイトオーダー、浮動小数点の形式、構造体の穴に注意する。 (XDR ライブラリを使えば、ポータビリティが高くなる。XDR については、3 学期の「分散システム」で。)

 
----------------------------------------------------------------------
   1:	
   2:	/*
   3:	        utmp-print.c -- /var/adm/utmp の内容を表示するプログラム
   4:	        ~yas/syspro1/file/utmp-print.c
   5:	        $Header: /home/lab2/OS/yas/syspro1-1998/file/RCS/utmp-print.c,v 1.4 1998/05/11 14:54:49 yas Exp $
   6:	        Start: 1995/03/06 09:01:09
   7:	*/
   8:	
   9:	#include <stdio.h>      /* FILE, NULL, stderr */
  10:	#include <utmp.h>       /* struct utmp */
  11:	#include <time.h>       /* ctime() */
  12:	
  13:	#if     0
  14:	struct utmp
  15:	{
  16:	    char ut_user[8] ;           /* User login name */
  17:	    char ut_id[4] ;             /* /etc/inittab id(usually line #) */
  18:	    char ut_line[12] ;          /* device name (console, lnxx) */
  19:	    short ut_pid ;              /* leave short for compatiblity - process id */
  20:	    short ut_type ;             /* type of entry */
  21:	    struct exit_status ut_exit ;/* The exit status of a process
  22:	                                 * marked as DEAD_PROCESS.
  23:	                                 */
  24:	    time_t ut_time ;            /* time entry was made */
  25:	} ;
  26:	#endif
  27:	
  28:	void utmp_print_file();
  29:	void utmp_print( struct utmp *u );
  30:	void print_char_array( char a[], int len );
  31:	
  32:	main()
  33:	{
  34:	        utmp_print_file();
  35:	}
  36:	
  37:	void utmp_print_file()
  38:	{
  39:	    struct utmp entry;
  40:	    FILE        *fp ;
  41:	        fp = fopen(  UTMP_FILE, "r" );
  42:	        if( fp == NULL )
  43:	        {
  44:	            perror( UTMP_FILE );
  45:	            exit( -1 );
  46:	        }
  47:	        while( fread(&entry, sizeof(entry),1,fp ) == 1 )
  48:	        {
  49:	            utmp_print( &entry );
  50:	        }
  51:	        fclose( fp );
  52:	}
  53:	
  54:	void utmp_print( struct utmp *u )
  55:	{
  56:	        print_char_array( u->ut_user, sizeof(u->ut_user) );
  57:	        print_char_array( u->ut_id, sizeof(u->ut_id) );
  58:	        print_char_array( u->ut_line, sizeof(u->ut_line) );
  59:	        printf("%6d ", u->ut_pid );
  60:	        printf("%6d ", u->ut_type );
  61:	        printf("%s",ctime(&u->ut_time) );
  62:	}
  63:	
  64:	void print_char_array( char a[], int len )
  65:	{
  66:	    int i ;
  67:	        for( i=0 ; i<len && a[i] ; i++ )
  68:	            putchar( a[i] );
  69:	        for( ; i<len ; i++ )
  70:	            putchar(' ');
  71:	        putchar(' ');
  72:	}
----------------------------------------------------------------------
 

ut_time には、1970年1月1日0:00(GMT)からの秒数で時刻 が含まれている。

実行結果


----------------------------------------------------------------------
% ./utmp-print  [←]
              system boot       0      2 Sun Apr 26 05:32:18 1998
              run-level 2       0      1 Sun Apr 26 05:32:18 1998
lnsyscon link                  32      8 Sun Apr 26 05:32:18 1998
rc2      s2                    35      8 Sun Apr 26 05:33:27 1998
LOGIN    t1   ttyd1           703      6 Sun Apr 26 05:33:28 1998
rlogin   q0   ttyq0         11481      8 Mon May 11 23:24:53 1998
yas      q1   ttyq1         11506      7 Mon May 11 23:24:45 1998
yas      q2   ttyq2         11521      7 Mon May 11 23:24:59 1998
i97????  q3   ttyq3           265      8 Sat May  9 18:01:24 1998
t???     q4   ttyq4         28706      8 Wed May  6 13:55:54 1998
s???     q5   ttyq5          2818      8 Sun Apr 26 16:40:12 1998
s???     q6   ttyq6          2889      8 Sun Apr 26 17:05:52 1998
s???     q7   ttyq7          2890      8 Sun Apr 26 17:05:52 1998
% who [←]
yas        ttyq1         5月 11日 23時24分
yas        ttyq2         5月 11日 23時24分
% []
----------------------------------------------------------------------

■練習問題

★練習問題17,長いwhoプログラム

次のような長い表示をするUNIXの who コマンドと似た動きをするプログラム を作りなさい。


----------------------------------------------------------------------
% who [←]
yas      ttyp0   Apr 28 20:32   (top:0.0)
yas      ttyp1   May 11 22:19   (revolution)
yas      ttyp2   May 11 20:03   (hlla0:0.0)
%
----------------------------------------------------------------------

括弧の中は、ログインしてきたホスト名やXウィンドウのディスプレイの名前。

ヒント:utmp ではなく、utmpx を使うとよい。

ヒント:日付の表示は、上の例のように ctime() を使う方法でよい。 あるいは、localtime() や strftime() を使う方法もある。

★練習問題18 lastコマンド

last コマンドと似た動きをするプログラムを作りなさい。

wtmp ではなく wtmpx を使うと、ホスト名まで調べられる。

★練習問題19 出席判定プログラム

あるユーザが、ある与えられた時刻の範囲内にログインしていたかどうかを調 べるプログラムを作りなさい。 たとえば、
% present user 2000/04/24-10:10 2000/04/24-11:30
と与えると、ユーザ名user のユーザが、その時間にログインしていたら、OK を返す。
↑[もどる] ←[4月17日] ・[4月24日] →[5月01日] [課題]
Last updated: 2000/04/23 02:01:00
Yasushi Shinjo / <yas@is.tsukuba.ac.jp>