システム・プログラム
電子・情報工学系
新城 靖
<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 までやる必要はない。