システム・プログラム 電子・情報工学系 新城 靖 <yas@is.tsukuba.ac.jp>
このページは、次の URL にあります。
http://www.hlla.is.tsukuba.ac.jp/~yas/coins/syspro-2000/2000-04-24
/dir.html
あるいは、次のページから手繰っていくこともできます。
http://www.hlla.is.tsukuba.ac.jp/~yas/coins/
http://www.is.tsukuba.ac.jp/~yas/index-j.html
UNIXのディレクトリは、ディスク中では、可変長の構造体になっている。C言 語では、直接的には可変長の構造体を扱うことはできない。
IRIX では、getdents(2) システム・コールを使うと、ディスク中に保存され たディレクトリに近いデータを得ることができる。(システム・コールは、シ ステムにより異なる。システムによっては、ディレクトリについても、read() が使えるものがある。SunOS, Solaris でも、getdents()。HP-UX では、 getdirentries()
---------------------------------------------------------------------- 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: #include <stdio.h> /* fprintf(), stderr */ 9: #include <sys/types.h> /* open(2) */ 10: #include <sys/stat.h> /* open(2) */ 11: #include <fcntl.h> /* open(2) */ 12: #include <sys/dirent.h> /* 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<n ; i++ ) 80: printf("%02x ",buff[i] ); 81: for( i=n ; i<16 ; i++ ) 82: printf(" "); 83: for( i=0 ; i<n ; i++ ) 84: printf("%c",isprint(buff[i])?buff[i]:'#'); 85: for( i=n ; i<16 ; i++ ) 86: printf(" "); 87: printf("\n"); 88: } 89: ----------------------------------------------------------------------実行例。
---------------------------------------------------------------------- % ./dir-getdents dir100 07 a5 60 00 00 17 2e 00 0c 2e 00 01 8f 70 21 ###`###.##.###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:0, off:5934, ino:501088, reclen:12, name:. p:12, off:1832596148, ino:26177569, reclen:16, name:.. p:28, off:1832596151, ino:501091, reclen:16, name:file2 p:44, off:4294967295, ino:501089, reclen:16, name:file1 %
----------------------------------------------------------------------
ディレクトリを読むためのライブラリ関数として、次のようなものがある。
---------------------------------------------------------------------- #include <sys/types.h> #include <sys/dir.h> 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) ----------------------------------------------------------------------このライブラリ関数は、システム・コールと比較して移植性が高い。
---------------------------------------------------------------------- 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: #include <stdio.h> 9: #include <sys/stat.h> 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: } ----------------------------------------------------------------------単純に man mkdir と打つと、mkdir(1) コマンドのマニュアルが表示される。 mkdir(2) システム・コールを見るには、次のように打つ。
% man 2 mkdir![]()
opendir(3) を用いて、次のような動きをするプログラムを作りなさい。
注意: ls -l までやる必要はない。