]> git.zerfleddert.de Git - micropolis/blame_incremental - src/tcl/compat/opendir.c
let the monster survive if it is born in a river
[micropolis] / src / tcl / compat / opendir.c
... / ...
CommitLineData
1/*
2 * opendir.c --
3 *
4 * This file provides dirent-style directory-reading procedures
5 * for V7 Unix systems that don't have such procedures. The
6 * origin of this code is unclear, but it seems to have come
7 * originally from Larry Wall.
8 *
9 */
10
11#include <tclint.h>
12#include <tclunix.h>
13
14#undef DIRSIZ
15#define DIRSIZ(dp) \
16 ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
17
18/*
19 * open a directory.
20 */
21DIR *
22opendir(name)
23char *name;
24{
25 register DIR *dirp;
26 register int fd;
27 char *myname;
28
29 myname = ((*name == '\0') ? "." : name);
30 if ((fd = open(myname, 0, 0)) == -1)
31 return NULL;
32 if ((dirp = (DIR *)ckalloc(sizeof(DIR))) == NULL) {
33 close (fd);
34 return NULL;
35 }
36 dirp->dd_fd = fd;
37 dirp->dd_loc = 0;
38 return dirp;
39}
40
41/*
42 * read an old style directory entry and present it as a new one
43 */
44#ifndef pyr
45#define ODIRSIZ 14
46
47struct olddirect {
48 ino_t od_ino;
49 char od_name[ODIRSIZ];
50};
51#else /* a Pyramid in the ATT universe */
52#define ODIRSIZ 248
53
54struct olddirect {
55 long od_ino;
56 short od_fill1, od_fill2;
57 char od_name[ODIRSIZ];
58};
59#endif
60
61/*
62 * get next entry in a directory.
63 */
64struct dirent *
65readdir(dirp)
66register DIR *dirp;
67{
68 register struct olddirect *dp;
69 static struct dirent dir;
70
71 for (;;) {
72 if (dirp->dd_loc == 0) {
73 dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf,
74 DIRBLKSIZ);
75 if (dirp->dd_size <= 0)
76 return NULL;
77 }
78 if (dirp->dd_loc >= dirp->dd_size) {
79 dirp->dd_loc = 0;
80 continue;
81 }
82 dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
83 dirp->dd_loc += sizeof(struct olddirect);
84 if (dp->od_ino == 0)
85 continue;
86 dir.d_ino = dp->od_ino;
87 strncpy(dir.d_name, dp->od_name, ODIRSIZ);
88 dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
89 dir.d_namlen = strlen(dir.d_name);
90 dir.d_reclen = DIRSIZ(&dir);
91 return (&dir);
92 }
93}
94
95/*
96 * close a directory.
97 */
98void
99closedir(dirp)
100register DIR *dirp;
101{
102 close(dirp->dd_fd);
103 dirp->dd_fd = -1;
104 dirp->dd_loc = 0;
105 ckfree((char *) dirp);
106}
Impressum, Datenschutz