Rune - Further Object abstraction work
[rune.git] / libruntime / sys_directory.c
1 /*
2  * SYS_DIRECTORY.C
3  */
4
5 #include "defs.h"
6 #include <dirent.h>
7
8 /*
9  * DirStor
10  */
11 typedef struct DirStor {
12     DIR    *dir;
13     int     error;
14     int     type;
15     runeino_t ino;
16     urunesize_t namlen;
17     LValueStor namelvs;
18 } DirStor;
19
20 struct opendir_args {
21     DirStor *ds;
22     const char *path;
23 };
24
25 struct fdopendir_args {
26     DirStor *ds;
27     int     fd;
28 #if LONG_BITS == 64
29     int     filler01;
30 #endif
31 };
32
33 /*
34  * Normal read
35  */
36 void
37 RUNESYSCALL(opendir) (struct opendir_args *args, int *resp)
38 {
39     DirStor *ds = args->ds;
40     const char *path = args->path;
41
42     ds->dir = opendir(path);
43     if (ds->dir == NULL) {
44         ds->error = errno;
45         *resp = -1;
46     } else {
47         ds->error = 0;
48         *resp = 0;
49     }
50 }
51
52 void
53 RUNESYSCALL(fdopendir) (struct fdopendir_args *args, int *resp)
54 {
55     DirStor *ds = args->ds;
56
57     ds->dir = fdopendir(args->fd);
58     if (ds->dir == NULL) {
59         ds->error = errno;
60         *resp = -1;
61     } else {
62         ds->error = 0;
63         *resp = 0;
64     }
65 }
66
67 void
68 RUNESYSCALL(readdir) (DirStor *ds, int *resp)
69 {
70     struct dirent *den;
71     char   *ptr;
72     Type   *type;
73
74     den = readdir(ds->dir);
75     ptr = ds->namelvs.lv_Addr;
76     type = ds->namelvs.lv_Type;
77     if (den) {
78         ds->type = den->d_type;
79         ds->namlen = den->d_namlen;
80         ds->ino = den->d_ino;
81         dassert(ds->namlen + 1 <= type->ty_Bytes);
82         bcopy(den->d_name, ptr, ds->namlen);
83         ptr[ds->namlen] = 0;
84         *resp = 1;
85     } else {
86         ds->type = 0;
87         ds->namlen = 0;
88         ds->ino = -1;
89         dassert(1 <= type->ty_Bytes);
90         ptr[0] = 0;
91         *resp = 0;
92     }
93 }
94
95 void
96 RUNESYSCALL(rewinddir) (DirStor *ds, void *resp __unused)
97 {
98     rewinddir(ds->dir);
99
100 }
101
102 void
103 RUNESYSCALL(closedir) (DirStor *ds, void *resp __unused)
104 {
105     if (ds->dir) {
106         closedir(ds->dir);
107         ds->dir = NULL;
108     }
109 }
110
111 void
112 RUNESYSCALL(dirfd) (DirStor *ds, int *resp)
113 {
114     if (ds->dir) {
115         *resp = dirfd(ds->dir);
116         if (*resp < 0)
117             ds->error = errno;
118         else
119             ds->error = 0;
120     } else {
121         *resp = -1;
122         ds->error = EINVAL;
123     }
124 }