1 /* $Id: getdents.c,v 1.9 2006/12/30 23:19:11 yamt Exp $ */
4 * Copyright (c)2004, 2006 YAMAMOTO Takashi,
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 void print_dents(FILE *, const void *, int);
40 int main(int, char *[]);
43 print_dents(FILE *fp
, const void *vp
, int sz
)
46 const char *ep
= cp
+ sz
;
47 const struct dirent
*d
;
51 fprintf(fp
, "fileno=%" PRIu64
52 ", type=%d, reclen=%d, len=%d, %s\n",
53 (uint64_t)d
->d_fileno
, (int)d
->d_type
, (int)d
->d_reclen
,
54 (int)d
->d_namlen
, d
->d_name
);
61 for (cp
= vp
, i
= 0; cp
< ep
; cp
++, i
++) {
63 fprintf(fp
, "%08tx:", cp
- (const char *)vp
);
64 fprintf(fp
, "%02x ", (int)(unsigned char)*cp
);
77 char u_buf
[DIRBLKSIZ
];
82 main(int argc
, char *argv
[])
89 struct ent
*blks
= NULL
;
94 errx(EXIT_FAILURE
, "arg");
97 off
= strtoull(argv
[2], 0, 0);
101 printf("dir=%s\n", path
);
102 fd
= open(path
, O_RDONLY
);
104 err(EXIT_FAILURE
, "open");
105 printf("seek: off=%" PRIx64
"(%" PRIu64
")\n",
106 (uint64_t)off
, (uint64_t)off
);
107 if (off
!= lseek(fd
, off
, SEEK_SET
))
108 err(EXIT_FAILURE
, "lseek");
110 #if defined(DENSE_DIRECTORY)
111 printf("searching valid offsets..\n");
112 for (off
= 0; ; off
++) {
114 blks
= realloc(blks
, sizeof(*blks
) * (nblks
+ 1));
116 err(EXIT_FAILURE
, "realloc");
118 memset(p
, 0, sizeof(*p
));
119 p
->off
= off
= lseek(fd
, off
, SEEK_SET
);
120 if (off
== (off_t
)-1)
121 err(EXIT_FAILURE
, "lseek");
122 printf("off=%" PRIx64
"(%" PRIu64
")\n",
123 (uint64_t)off
, (uint64_t)off
);
124 p
->sz
= ret
= getdents(fd
, p
->u
.u_buf
, DIRBLKSIZ
);
125 printf("getdents: %d\n", ret
);
127 if (errno
== EINVAL
) {
130 errx(EXIT_FAILURE
, "getdents");
136 print_dents(stdout
, p
->u
.u_buf
, ret
);
138 printf("%d valid offsets found\n", nblks
);
139 #else /* defined(DENSE_DIRECTORY) */
140 printf("start reading..\n");
143 blks
= realloc(blks
, sizeof(*blks
) * (nblks
+ 1));
145 err(EXIT_FAILURE
, "realloc");
147 memset(p
, 0, sizeof(*p
));
148 p
->off
= off
= lseek(fd
, (off_t
)0, SEEK_CUR
);
149 if (off
== (off_t
)-1)
150 err(EXIT_FAILURE
, "lseek");
151 printf("off=%" PRIx64
"(%" PRIu64
")\n",
152 (uint64_t)off
, (uint64_t)off
);
153 p
->sz
= ret
= getdents(fd
, p
->u
.u_buf
, DIRBLKSIZ
);
154 printf("getdents: %d\n", ret
);
156 err(EXIT_FAILURE
, "getdents");
158 print_dents(stdout
, p
->u
.u_buf
, ret
);
160 printf("%d blks read\n", nblks
);
161 #endif /* defined(DENSE_DIRECTORY) */
164 printf("re-open the file\n");
166 err(EXIT_FAILURE
, "close");
167 fd
= open(path
, O_RDONLY
);
169 err(EXIT_FAILURE
, "open");
172 printf("starting random read...\n");
173 for (count
= nblks
* 4 + 10; count
; count
--) {
180 off
= lseek(fd
, p
->off
, SEEK_SET
);
181 if (off
== (off_t
)-1)
183 printf("off=%" PRIx64
"(%" PRIu64
")\n",
184 (uint64_t)off
, (uint64_t)off
);
185 ret
= getdents(fd
, buf
, DIRBLKSIZ
);
186 printf("getdents: %d\n", ret
);
188 err(EXIT_FAILURE
, "getdents");
191 fprintf(stderr
, "off=%" PRIx64
192 ": different sz %d != %d\n",
193 (uint64_t)off
, p
->sz
, ret
);
195 } else if (memcmp(p
->u
.u_buf
, buf
, (size_t)ret
)) {
197 fprintf(stderr
, "off=%" PRIx64
": different data\n",
199 fprintf(stderr
, "previous:\n");
200 print_dents(stderr
, p
->u
.u_buf
, p
->sz
);
201 fprintf(stderr
, "now:\n");
202 print_dents(stderr
, buf
, ret
);
206 const struct dirent
*d1
= (void *)p
->u
.u_buf
;
207 const struct dirent
*d2
= (void *)buf
;
209 if (p
->sz
== 0 || ret
== 0 ||
210 d1
->d_fileno
!= d2
->d_fileno
||
211 #if defined(DT_UNKNOWN)
212 (d1
->d_type
!= DT_UNKNOWN
&&
213 d2
->d_type
!= DT_UNKNOWN
&&
214 d1
->d_type
!= d2
->d_type
) ||
215 #endif /* defined(DT_UNKNOWN) */
216 d1
->d_namlen
!= d2
->d_namlen
||
217 memcmp(d1
->d_name
, d2
->d_name
, d1
->d_namlen
)) {
218 fprintf(stderr
, "fatal difference\n");