sd: remove 'ssd' driver support
[unleashed/tickless.git] / usr / src / lib / libast / common / dir / getdents.c
blob1cb90fbc34ef82beb2072143337a8bd596dc94e2
1 /***********************************************************************
2 * *
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 *
8 * *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
20 * *
21 ***********************************************************************/
22 #pragma prototyped
24 #include "dirlib.h"
26 #if _dir_ok || _lib_getdents
28 NoN(getdents)
30 #else
33 * getdents
35 * read directory entries into directory block
37 * NOTE: directory entries must fit within DIRBLKSIZ boundaries
40 #ifndef MAXNAMLEN
41 #define MAXNAMLEN 255
42 #endif
44 #if _lib_dirread
45 extern int dirread(int, char*, int);
46 #endif
47 #if _lib_getdirentries
48 extern int getdirentries(int, char*, int, long*);
49 #endif
51 ssize_t
52 getdents(int fd, void* buf, size_t siz)
54 struct stat st;
56 if (siz < DIRBLKSIZ)
58 errno = EINVAL;
59 return(-1);
61 if (fstat(fd, &st)) return(-1);
62 if (!S_ISDIR(st.st_mode))
64 #ifdef ENOTDIR
65 errno = ENOTDIR;
66 #else
67 errno = EBADF;
68 #endif
69 return(-1);
71 #if _lib_getdirentries
73 long off;
74 return(getdirentries(fd, buf, siz, &off));
76 #else
77 #if _lib_dirread
79 register char* sp; /* system */
80 register struct dirent* up; /* user */
81 char* u;
82 int n;
83 int m;
84 int i;
86 m = (siz * 6) / 10;
87 m = roundof(m, 8);
88 sp = (char*)buf + siz - m - 1;
89 if (!(n = dirread(fd, sp, m))) return(0);
90 if (n > 0)
92 up = (struct dirent*)buf;
93 sp[n] = 0;
94 while (sp < (char*)buf + siz - m + n)
96 i = 0;
97 while (*sp >= '0' && *sp <= '9')
98 i = 10 * i + *sp++ - '0';
99 while (*sp && *sp != '\t') sp++;
100 if (*sp++)
102 up->d_fileno = i;
103 u = up->d_name;
104 while ((*u = *sp++) && u < up->d_name + MAXNAMLEN) u++;
105 *u = 0;
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);
114 #else
115 #if _mem_d_reclen_direct
116 return(read(fd, buf, siz));
117 #else
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 */
124 register char* s;
125 register char* u;
126 int n;
127 int m;
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))
143 if (sp->d_ino)
145 up->d_fileno = sp->d_ino;
146 s = sp->d_name;
147 u = tmp;
148 while (s < sp->d_name + sizeof(sp->d_name) && *s)
149 *u++ = *s++;
150 *u = 0;
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);
156 sp++;
158 } while (up == (struct dirent*)buf);
159 return((char*)up - (char*)buf);
161 #endif
162 #endif
163 #endif
166 #endif