Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/dir/getdents.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1985-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* Phong Vo <[email protected]> *
20
* *
21
***********************************************************************/
22
#pragma prototyped
23
24
#include "dirlib.h"
25
26
#if _dir_ok || _lib_getdents
27
28
NoN(getdents)
29
30
#else
31
32
/*
33
* getdents
34
*
35
* read directory entries into directory block
36
*
37
* NOTE: directory entries must fit within DIRBLKSIZ boundaries
38
*/
39
40
#ifndef MAXNAMLEN
41
#define MAXNAMLEN 255
42
#endif
43
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
50
51
ssize_t
52
getdents(int fd, void* buf, size_t siz)
53
{
54
struct stat st;
55
56
if (siz < DIRBLKSIZ)
57
{
58
errno = EINVAL;
59
return(-1);
60
}
61
if (fstat(fd, &st)) return(-1);
62
if (!S_ISDIR(st.st_mode))
63
{
64
#ifdef ENOTDIR
65
errno = ENOTDIR;
66
#else
67
errno = EBADF;
68
#endif
69
return(-1);
70
}
71
#if _lib_getdirentries
72
{
73
long off;
74
return(getdirentries(fd, buf, siz, &off));
75
}
76
#else
77
#if _lib_dirread
78
{
79
register char* sp; /* system */
80
register struct dirent* up; /* user */
81
char* u;
82
int n;
83
int m;
84
int i;
85
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)
91
{
92
up = (struct dirent*)buf;
93
sp[n] = 0;
94
while (sp < (char*)buf + siz - m + n)
95
{
96
i = 0;
97
while (*sp >= '0' && *sp <= '9')
98
i = 10 * i + *sp++ - '0';
99
while (*sp && *sp != '\t') sp++;
100
if (*sp++)
101
{
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);
109
}
110
}
111
return((char*)up - (char*)buf);
112
}
113
}
114
#else
115
#if _mem_d_reclen_direct
116
return(read(fd, buf, siz));
117
#else
118
{
119
120
#define MAXREC roundof(sizeof(*up)-sizeof(up->d_name)+sizeof(sp->d_name)+1,8)
121
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];
129
130
/*
131
* we assume sizeof(struct dirent) > sizeof(struct direct)
132
*/
133
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;
137
do
138
{
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))
142
{
143
if (sp->d_ino)
144
{
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);
155
}
156
sp++;
157
}
158
} while (up == (struct dirent*)buf);
159
return((char*)up - (char*)buf);
160
}
161
#endif
162
#endif
163
#endif
164
}
165
166
#endif
167
168