Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/3d/dir3d.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1989-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
* Eduardo Krell <[email protected]> *
20
* *
21
***********************************************************************/
22
#pragma prototyped
23
24
/*
25
* 3d directory(3)
26
*
27
* NOTE: there are 3 limitations to this implementation
28
*
29
* (1) opendir() allocates one file descriptor for each directory
30
* view and these remain open until closedir()
31
*
32
* (2) telldir() offsets are encoded with the directory view level
33
* and TELLDIR() offset, and the directory view level takes
34
* TABBITS bits, so TELLDIR() offsets are limited to (32-TABBITS)
35
* bits, but that would be one big physical directory
36
*
37
* (3) if dirent.d_type supported then directory stat.st_nlink is
38
* inflated to foil viewpath subdirectory counting that would
39
* skip lower view subdirs not reflected in the top level st_nlink
40
*/
41
42
#define _def_map_ast 1
43
#define _std_strtol 1
44
45
#define getdirentries ______getdirentries
46
#define sbrk ______sbrk
47
#define strmode ______strmode
48
49
#include <ast_std.h>
50
51
#undef getdirentries
52
#undef sbrk
53
#undef strmode
54
55
#include "dir_3d.h"
56
57
#if !_dir_ok
58
#undef dirent
59
#define dirent DIRdirent
60
#endif
61
62
#undef strtol
63
#undef strtoul
64
#undef strtoll
65
#undef strtoull
66
67
static int intercepted;
68
69
DIR*
70
opendir3d(const char* apath)
71
{
72
register char* path;
73
register DIR* dirp = 0;
74
register int n;
75
int oerrno;
76
long visits = 0;
77
struct stat st;
78
79
if (dirp = (DIR*)state.freedirp)
80
state.freedirp = 0;
81
else if (!(dirp = newof(0, DIR, 1, 0)))
82
return 0;
83
intercepted++;
84
dirp->fd = -1;
85
dirp->viewp = dirp->view;
86
n = state.in_2d;
87
if (path = pathreal(apath, P_SLASH, NiL))
88
state.in_2d = 2;
89
else
90
path = (char*)apath;
91
dirp->viewp->dirp = OPENDIR(path);
92
state.in_2d = n;
93
if (!dirp->viewp->dirp)
94
{
95
state.freedirp = (void*)dirp;
96
intercepted = 0;
97
return 0;
98
}
99
dirp->boundary = state.boundary;
100
if (state.in_2d)
101
{
102
dirp->overlay = 0;
103
(dirp->viewp++)->opaque = 0;
104
dirp->viewp->dirp = 0;
105
}
106
else
107
{
108
oerrno = errno;
109
n = strlen(path);
110
path[n] = '/';
111
strcpy(path + n + 1, state.opaque);
112
dirp->viewp->level = state.path.level;
113
state.in_2d++;
114
(dirp->viewp++)->opaque = LSTAT(path, &st) ? 0 : st.st_ino;
115
state.in_2d--;
116
path[n] = 0;
117
while (pathnext(state.path.name, NiL, &visits))
118
{
119
state.in_2d = 2;
120
dirp->viewp->dirp = OPENDIR(state.path.name);
121
state.in_2d = 0;
122
if (dirp->viewp->dirp)
123
{
124
n = strlen(state.path.name);
125
state.path.name[n] = '/';
126
strcpy(state.path.name + n + 1, state.opaque);
127
dirp->viewp->level = state.path.level;
128
(dirp->viewp++)->opaque = LSTAT(state.path.name, &st) ? 0 : st.st_ino;
129
state.path.name[n] = 0;
130
}
131
}
132
errno = oerrno;
133
(dirp->viewp--)->dirp = 0;
134
if (dirp->viewp <= dirp->view)
135
dirp->overlay = 0;
136
else if (!(dirp->overlay = hashalloc(NiL, HASH_set, HASH_ALLOCATE, 0)))
137
{
138
closedir(dirp);
139
intercepted = 0;
140
return 0;
141
}
142
}
143
dirp->viewp = dirp->view;
144
CHEATDIR(dirp);
145
intercepted = 0;
146
return dirp;
147
}
148
149
int
150
closedir3d(register DIR* dirp)
151
{
152
if (dirp)
153
{
154
if (intercepted++)
155
{
156
intercepted--;
157
return CLOSEDIR(dirp);
158
}
159
for (dirp->viewp = dirp->view; dirp->viewp->dirp; dirp->viewp++)
160
CLOSEDIR(dirp->viewp->dirp);
161
if (dirp->overlay)
162
hashfree(dirp->overlay);
163
if (!state.freedirp)
164
state.freedirp = (void*)dirp;
165
else
166
free((char*)dirp);
167
intercepted--;
168
}
169
return 0;
170
}
171
172
struct dirent*
173
readdir3d(register DIR* dirp)
174
{
175
register struct DIRdirent* dp;
176
register Dir_physical_t* covered;
177
178
if (intercepted++)
179
{
180
intercepted--;
181
return READDIR(dirp);
182
}
183
for (;;)
184
{
185
while (!(dp = (struct DIRdirent*)READDIR(dirp->viewp->dirp)))
186
{
187
if (!(++dirp->viewp)->dirp)
188
{
189
intercepted--;
190
return 0;
191
}
192
CHEATDIR(dirp);
193
}
194
#ifdef D_FILENO
195
if (!state.in_2d)
196
{
197
register char* s = dp->d_name;
198
199
/*
200
* skip opaque and hidden entries
201
*/
202
203
if (*s++ == '.' && *s++ == '.' && *s++ == '.')
204
{
205
/*
206
* the following for old opaque
207
*/
208
209
if (!*s && !dirp->viewp->opaque)
210
dirp->viewp->opaque = D_FILENO(dp);
211
continue;
212
}
213
}
214
#endif
215
216
/*
217
* NOTE: this (slimey) method assumes READDIR() returns . first
218
*/
219
220
if (dirp->overlay && (!dirp->boundary || dp->d_name[0] != '.' || dp->d_name[1]))
221
{
222
if ((covered = (Dir_physical_t*)hashget(dirp->overlay, dp->d_name)) && covered < dirp->viewp)
223
continue;
224
if ((dirp->viewp + 1)->dirp)
225
hashput(dirp->overlay, 0, (char*)dirp->viewp);
226
}
227
#ifdef D_FILENO
228
if (D_FILENO(dp) == dirp->viewp->opaque)
229
continue;
230
#endif
231
intercepted--;
232
return (struct dirent*)dp;
233
}
234
/*NOTREACHED*/
235
}
236
237
#undef seekdir
238
239
#define OFFBITS (CHAR_BIT*sizeof(long)-TABBITS)
240
#define SETPOS(l,o) ((((long)(l))<<OFFBITS)|GETOFF(o))
241
#define GETOFF(p) ((p)&((((long)1)<<OFFBITS)-1))
242
#define GETLEV(p) (((p)>>OFFBITS)&((((long)1)<<TABBITS)-1))
243
244
void
245
seekdir3d(register DIR* dirp, long pos)
246
{
247
register int n;
248
int lev;
249
250
if (intercepted++)
251
{
252
intercepted--;
253
SEEKDIR(dirp, pos);
254
return;
255
}
256
if (pos)
257
{
258
lev = GETLEV(pos);
259
pos = GETOFF(pos);
260
for (n = 0; dirp->view[n].dirp; n++)
261
if (lev == dirp->view[n].level)
262
break;
263
}
264
else
265
{
266
n = 0;
267
hashfree(dirp->overlay);
268
dirp->overlay = hashalloc(NiL, HASH_set, HASH_ALLOCATE, 0);
269
}
270
if (dirp->view[n].dirp)
271
{
272
SEEKDIR(dirp->view[n].dirp, pos);
273
dirp->viewp = &dirp->view[n];
274
CHEATDIR(dirp);
275
while (dirp->view[++n].dirp)
276
SEEKDIR(dirp->view[n].dirp, 0L);
277
}
278
intercepted--;
279
}
280
281
#undef telldir
282
283
long
284
telldir3d(DIR* dirp)
285
{
286
if (intercepted++)
287
{
288
intercepted--;
289
return TELLDIR(dirp);
290
}
291
return SETPOS(dirp->viewp->level, TELLDIR(dirp->viewp->dirp));
292
}
293
294
#undef rewinddir
295
296
void
297
rewinddir3d(register DIR* dirp)
298
{
299
seekdir(dirp, 0L);
300
}
301
302
#if !_nosys_readdir64
303
304
struct dirent64*
305
readdir643d(register DIR* dirp)
306
{
307
register struct dirent64* dp;
308
register Dir_physical_t* covered;
309
310
if (intercepted++)
311
{
312
intercepted--;
313
return READDIR64(dirp);
314
}
315
for (;;)
316
{
317
while (!(dp = READDIR64(dirp->viewp->dirp)))
318
{
319
if (!(++dirp->viewp)->dirp)
320
{
321
intercepted--;
322
return 0;
323
}
324
CHEATDIR(dirp);
325
}
326
#ifdef D_FILENO
327
if (!state.in_2d)
328
{
329
register char* s = dp->d_name;
330
331
/*
332
* skip opaque and hidden entries
333
*/
334
335
if (*s++ == '.' && *s++ == '.' && *s++ == '.')
336
{
337
/*
338
* the following for old opaque
339
*/
340
341
if (!*s && !dirp->viewp->opaque)
342
dirp->viewp->opaque = D_FILENO(dp);
343
continue;
344
}
345
}
346
#endif
347
348
/*
349
* NOTE: this (slimey) method assumes READDIR() returns . first
350
*/
351
352
if (dirp->overlay && (!dirp->boundary || dp->d_name[0] != '.' || dp->d_name[1]))
353
{
354
if ((covered = (Dir_physical_t*)hashget(dirp->overlay, dp->d_name)) && covered < dirp->viewp)
355
continue;
356
if ((dirp->viewp + 1)->dirp)
357
hashput(dirp->overlay, 0, (char*)dirp->viewp);
358
}
359
#ifdef D_FILENO
360
if (D_FILENO(dp) == dirp->viewp->opaque)
361
continue;
362
#endif
363
intercepted--;
364
return dp;
365
}
366
/*NOTREACHED*/
367
}
368
369
#undef seekdir
370
371
#define OFFBITS64 (CHAR_BIT*sizeof(off64_t)-TABBITS)
372
#define SETPOS64(l,o) ((((off64_t)(l))<<OFFBITS)|GETOFF(o))
373
#define GETOFF64(p) ((p)&((((off64_t)1)<<OFFBITS)-1))
374
#define GETLEV64(p) (((p)>>OFFBITS)&((((off64_t)1)<<TABBITS)-1))
375
376
void
377
seekdir643d(register DIR* dirp, off64_t pos)
378
{
379
register int n;
380
int lev;
381
382
if (intercepted++)
383
{
384
intercepted--;
385
SEEKDIR64(dirp, pos);
386
return;
387
}
388
if (pos)
389
{
390
lev = GETLEV(pos);
391
pos = GETOFF(pos);
392
for (n = 0; dirp->view[n].dirp; n++)
393
if (lev == dirp->view[n].level)
394
break;
395
}
396
else
397
{
398
n = 0;
399
if (dirp->overlay)
400
{
401
hashfree(dirp->overlay);
402
dirp->overlay = hashalloc(NiL, HASH_set, HASH_ALLOCATE, 0);
403
}
404
}
405
if (dirp->view[n].dirp)
406
{
407
SEEKDIR64(dirp->view[n].dirp, pos);
408
dirp->viewp = &dirp->view[n];
409
CHEATDIR(dirp);
410
while (dirp->view[++n].dirp)
411
SEEKDIR64(dirp->view[n].dirp, (off64_t)0);
412
}
413
intercepted--;
414
}
415
416
#undef telldir
417
418
off64_t
419
telldir643d(DIR* dirp)
420
{
421
if (intercepted)
422
return TELLDIR64(dirp);
423
return SETPOS(dirp->viewp->level, TELLDIR64(dirp->viewp->dirp));
424
}
425
426
#undef rewinddir
427
428
void
429
rewinddir643d(register DIR* dirp)
430
{
431
rewinddir(dirp);
432
}
433
434
#endif
435
436
#if !_mangle_syscall && (!_lib_opendir || !_hdr_dirent)
437
438
#include "dirlib.h"
439
440
#undef _dir_ok
441
442
#define DIR DIRDIR
443
#undef DIRDIR
444
#define opendir OPENDIR
445
#if defined(SYS3D_opendir)
446
#undef OPENDIR
447
#endif
448
#define readdir READDIR
449
#if defined(SYS3D_readdir)
450
#undef READDIR
451
#endif
452
#define seekdir SEEKDIR
453
#if defined(SYS3D_seekdir)
454
#undef SEEKDIR
455
#endif
456
#define telldir TELLDIR
457
#if defined(SYS3D_telldir)
458
#undef TELLDIR
459
#endif
460
#define closedir CLOSEDIR
461
#if defined(SYS3D_closedir)
462
#undef CLOSEDIR
463
#endif
464
465
#define id sys_id
466
#define freedirp sys_freedirp
467
468
#ifndef DIRBLKSIZ
469
#ifdef DIRBLK
470
#define DIRBLKSIZ DIRBLK
471
#else
472
#ifdef DIRBUF
473
#define DIRBLKSIZ DIRBUF
474
#else
475
#define DIRBLKSIZ 8192
476
#endif
477
#endif
478
#endif
479
480
#include "getdents.c"
481
#include "opendir.c"
482
#include "readdir.c"
483
#include "telldir.c"
484
#include "seekdir.c"
485
486
#if !_nosys_readdir64
487
488
#undef dirent
489
#define dirent dirent64
490
#undef getdents
491
#define getdents getdents64
492
#define DIR DIRDIR
493
#undef DIRDIR
494
#undef readdir
495
#define readdir READDIR64
496
#if defined(SYS3D_readdir64)
497
#undef READDIR64
498
#endif
499
500
#if !_nosys_seekdir64
501
#undef seekdir
502
#define seekdir SEEKDIR64
503
#if defined(SYS3D_seekdir64)
504
#undef SEEKDIR64
505
#endif
506
#endif
507
508
#if !_nosys_telldir64
509
#undef telldir
510
#define telldir TELLDIR64
511
#if defined(SYS3D_telldir64)
512
#undef TELLDIR64
513
#endif
514
#endif
515
516
#include "readdir.c"
517
518
#if !_nosys_telldir64
519
#include "telldir.c"
520
#endif
521
522
#if !_nosys_seekdir64
523
#include "seekdir.c"
524
#endif
525
526
#endif
527
528
#endif
529
530