* include(`../coins-syspro-2000.html-m4') define(Name_,ディレクトリ(可変長の構造体の入出力)) define(This_Page_,Class_Root()YHM_CWD_Short()/YHM_OutputFN()) YHM_Header(Name_) YHM_Title(title,Name_) Class_Page_Header(This_Page_) **YHM_Section(dir-getdents,■getdents(2)によるディレクトリの内容の取得)
UNIXのディレクトリは、ディスク中では、可変長の構造体になっている。C言 語では、直接的には可変長の構造体を扱うことはできない。
IRIX では、getdents(2) システム・コールを使うと、ディスク中に保存され たディレクトリに近いデータを得ることができる。(システム・コールは、シ ステムにより異なる。システムによっては、ディレクトリについても、read() が使えるものがある。SunOS, Solaris でも、getdents()。HP-UX では、 getdirentries()
changequote(`<<<',`>>>')
YHM_Program(<<< ---------------------------------------------------------------------- 1: /* 2: dir-getdents.c -- ディレクトリの内容を表示するプログラム 3: ~yas/syspro1/dir/dir-getdents.c 4: $Header: /home/lab2/OS/yas/syspro1/dir/RCS/dir-getdents.c,v 1.2 1998/05/11 17:18:01 yas Exp $ 5: Start: 1995/03/07 21:44:51 6: */ 7: 8: #includechangequote 実行例。 YHM_Interaction( ---------------------------------------------------------------------- % ./dir-getdents dir1 00 07 a5 60 00 00 17 2e 00 0c 2e 00 01 8f 70 21 ###YHM_Backquote()###.##.###p! 6d 3b 32 b4 00 10 2e 2e 00 00 00 00 00 07 a5 63 m;2###..#######c 6d 3b 32 b7 00 10 66 69 6c 65 32 00 00 07 a5 61 m;2###file2####a ff ff ff ff 00 10 66 69 6c 65 31 00 ######file1# p:0YHM_Comma() off:5934YHM_Comma() ino:501088YHM_Comma() reclen:12YHM_Comma() name:. p:12YHM_Comma() off:1832596148YHM_Comma() ino:26177569YHM_Comma() reclen:16YHM_Comma() name:.. p:28YHM_Comma() off:1832596151YHM_Comma() ino:501091YHM_Comma() reclen:16YHM_Comma() name:file2 p:44YHM_Comma() off:4294967295YHM_Comma() ino:501089YHM_Comma() reclen:16YHM_Comma() name:file1 % ---------------------------------------------------------------------- )/* fprintf(), stderr */ 9: #include /* open(2) */ 10: #include /* open(2) */ 11: #include /* open(2) */ 12: #include /* getdents(2) */ 13: 14: #if 0 15: typedef struct dirent { /* data from readdir() */ 16: ino_t d_ino; /* inode number of entry */ 17: off_t d_off; /* offset of disk directory entry */ 18: unsigned short d_reclen; /* length of this record */ 19: char d_name[1]; /* name of file */ 20: } dirent_t; 21: #endif 22: 23: 24: extern void dir_list( char *dirname ); 25: extern void xdump( unsigned char *buff, int n ); 26: extern void xdump16( unsigned char *buff, int n ); 27: 28: main( int argc, char *argv[] ) 29: { 30: if( argc != 2 ) 31: { 32: fprintf( stderr,"Usage:%% %s dirname \n",argv[0] ); 33: exit( 1 ); 34: } 35: dir_list( argv[1] ); 36: } 37: 38: void dir_list( char *dirname ) 39: { 40: int fd ; 41: struct dirent *p ; 42: char buff[BUFSIZ] ; 43: int rcount ; 44: 45: fd = open( dirname,O_RDONLY ); 46: if( fd == -1 ) 47: { 48: perror( dirname ); 49: exit( 1 ); 50: } 51: 52: while( (rcount=getdents(fd,(dirent_t *)buff,BUFSIZ)) >0 ) 53: { 54: xdump( buff, rcount ); 55: for( p = (struct dirent *)buff ; (char *)p < &buff[rcount] ; 56: p=(struct dirent *) ((int)p+(p->d_reclen)) ) 57: { 58: printf("p:%d, ", (char *)p - buff ); 59: printf("off:%u, ", p->d_off ); /* long */ 60: printf("ino:%u, ", p->d_ino ); /* unsigned long */ 61: printf("reclen:%d, ", p->d_reclen ); 62: printf("name:%s\n", p->d_name ); 63: } 64: } 65: close( fd ); 66: } 67: 68: void xdump( unsigned char *buff, int n ) 69: { 70: if( n<0 || n>100000 ) 71: return; 72: for( ; n>0 ; n-=16, buff+=16 ) 73: xdump16( buff,n>=16?16:n ); 74: } 75: 76: void xdump16( unsigned char *buff, int n ) 77: { 78: register int i ; 79: for( i=0 ; i >>)
ディレクトリを読むためのライブラリ関数として、次のようなものがある。 changequote(`<<<',`>>>')
YHM_Program(<<< ---------------------------------------------------------------------- #includechangequote このライブラリ関数は、システム・コールと比較して移植性が高い。#include DIR *opendir(char *filename); struct direct *readdir(DIR *dirp); long telldir(DIR *dirp); void seekdir(DIR *dirp, long loc); void rewinddir(DIR *dirp); void closedir(DIR *dirp); int dirfd(DIR *dirp) ---------------------------------------------------------------------- >>>)
**YHM_Section(mkdir,■ディレクトリの作成) ディレクトリを作成するには、mkdir(2) システム・コールを用いる。 mkdir(1) コマンドは、mkdir(2) システム・コールを使って作られている。 changequote(`<<<',`>>>')
YHM_Program(<<< ---------------------------------------------------------------------- 1: /* 2: dir-mkdir.c -- ディレクトリを作成するプログラム 3: ~yas/syspro1/dir/dir-mkdir.c 4: $Header: /home/lab2/OS/yas/syspro1/dir/RCS/dir-mkdir.c,v 1.2 1998/05/11 17:01:35 yas Exp $ 5: Start: 1997/05/12 21:26:10 6: */ 7: 8: #includechangequote 単純に man mkdir と打つと、mkdir(1) コマンドのマニュアルが表示される。 mkdir(2) システム・コールを見るには、次のように打つ。 YHM_Interaction( % man 2 mkdir ) **YHM_Section(exercise,■練習問題) ***YHM_SubSection(exercise-19,★練習問題19 lsプログラム)9: #include 10: 11: void main( int argc, char *argv[] ) 12: { 13: if( argc != 2 ) 14: { 15: fprintf( stderr,"Usage:%% %s dirname \n",argv[0] ); 16: exit( 1 ); 17: } 18: if( mkdir( argv[1],0777 ) == -1 ) 19: { 20: perror( argv[1] ); 21: } 22: } ---------------------------------------------------------------------- >>>)
opendir(3) を用いて、次のような動きをするプログラムを作りなさい。
注意: ls -l までやる必要はない。 ***YHM_SubSection(exercise-21,★練習問題21 ディレクトリの削除) rmdir(2) を使ってディレクトリを削除するプログラムを作りなさい。 * include(`tail.html-m4')