1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
26 #if _dir_ok || _lib_getdents
35 * read directory entries into directory block
37 * NOTE: directory entries must fit within DIRBLKSIZ boundaries
45 extern int dirread(int, char*, int);
47 #if _lib_getdirentries
48 extern int getdirentries(int, char*, int, long*);
52 getdents(int fd
, void* buf
, size_t siz
)
61 if (fstat(fd
, &st
)) return(-1);
62 if (!S_ISDIR(st
.st_mode
))
71 #if _lib_getdirentries
74 return(getdirentries(fd
, buf
, siz
, &off
));
79 register char* sp
; /* system */
80 register struct dirent
* up
; /* user */
88 sp
= (char*)buf
+ siz
- m
- 1;
89 if (!(n
= dirread(fd
, sp
, m
))) return(0);
92 up
= (struct dirent
*)buf
;
94 while (sp
< (char*)buf
+ siz
- m
+ n
)
97 while (*sp
>= '0' && *sp
<= '9')
98 i
= 10 * i
+ *sp
++ - '0';
99 while (*sp
&& *sp
!= '\t') sp
++;
104 while ((*u
= *sp
++) && u
< up
->d_name
+ MAXNAMLEN
) u
++;
106 up
->d_reclen
= sizeof(struct dirent
) - sizeof(up
->d_name
) + (up
->d_namlen
= u
- up
->d_name
) + 1;
107 up
->d_reclen
= roundof(up
->d_reclen
, 8);
108 up
= (struct dirent
*)((char*)up
+ up
->d_reclen
);
111 return((char*)up
- (char*)buf
);
115 #if _mem_d_reclen_direct
116 return(read(fd
, buf
, siz
));
120 #define MAXREC roundof(sizeof(*up)-sizeof(up->d_name)+sizeof(sp->d_name)+1,8)
122 register struct direct
* sp
; /* system */
123 register struct dirent
* up
; /* user */
128 char tmp
[sizeof(sp
->d_name
) + 1];
131 * we assume sizeof(struct dirent) > sizeof(struct direct)
134 up
= (struct dirent
*)buf
;
135 n
= (siz
/ MAXREC
) * sizeof(struct direct
);
136 if ((!(m
= n
& ~511) || m
< MAXREC
) && (!(m
= n
& ~255) || m
< MAXREC
)) m
= n
;
139 if ((n
= read(fd
, (char*)buf
+ siz
- m
, m
)) <= 0) break;
140 sp
= (struct direct
*)((char*)buf
+ siz
- m
);
141 while (sp
< (struct direct
*)((char*)buf
+ siz
- m
+ n
))
145 up
->d_fileno
= sp
->d_ino
;
148 while (s
< sp
->d_name
+ sizeof(sp
->d_name
) && *s
)
151 strcpy(up
->d_name
, tmp
);
152 up
->d_reclen
= sizeof(struct dirent
) - sizeof(up
->d_name
) + (up
->d_namlen
= u
- tmp
) + 1;
153 up
->d_reclen
= roundof(up
->d_reclen
, 8);
154 up
= (struct dirent
*)((char*)up
+ up
->d_reclen
);
158 } while (up
== (struct dirent
*)buf
);
159 return((char*)up
- (char*)buf
);