Rune - Implement hard-locking model feature
[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         runesize_t namlen;
17         LValueStor namelvs;
18 } DirStor;
19
20 struct opendir_args {
21         LValueStor lvs;
22         PointerStor path;
23 };
24
25 struct fdopendir_args {
26         LValueStor lvs;
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->lvs.s_Addr;
40         const char *path = args->path.s_Addr;
41
42         STRBOUNDSCHECK(&args->path, PATH_MAX);
43         ds->dir = opendir(path);
44         printf("OPEN %s\n", path);
45         if (ds->dir == NULL) {
46                 ds->error = errno;
47                 *resp = -1;
48         } else {
49                 ds->error = 0;
50                 *resp = 0;
51         }
52 }
53
54 void
55 RuneSysCall_fdopendir(struct fdopendir_args *args, int *resp) 
56 {
57         DirStor *ds = args->lvs.s_Addr;
58
59         ds->dir = fdopendir(args->fd);
60         if (ds->dir == NULL) {
61                 ds->error = errno;
62                 *resp = -1;
63         } else {
64                 ds->error = 0;
65                 *resp = 0;
66         }
67 }
68
69 void
70 RuneSysCall_readdir(LValueStor *lvs, int *resp) 
71 {
72         DirStor *ds = lvs->s_Addr;
73         struct dirent *den;
74         char *ptr;
75
76         den = readdir(ds->dir);
77         ptr = ds->namelvs.s_Addr;
78         if (den) {
79                 ds->type = den->d_type;
80                 ds->namlen = den->d_namlen;
81                 ds->ino = den->d_ino;
82                 dassert(ds->namlen + 1 <= ds->namelvs.s_Type->ty_Bytes);
83                 bcopy(den->d_name, ptr, ds->namlen);
84                 ptr[ds->namlen] = 0;
85                 *resp = 1;
86         } else {
87                 ds->type = 0;
88                 ds->namlen = 0;
89                 ds->ino = -1;
90                 dassert(1 <= ds->namelvs.s_Type->ty_Bytes);
91                 ptr[0] = 0;
92                 *resp = 0;
93         }
94 }
95
96 void
97 RuneSysCall_rewinddir(LValueStor *lvs)
98 {
99         DirStor *ds = lvs->s_Addr;
100
101         rewinddir(ds->dir);
102
103 }
104
105 void
106 RuneSysCall_closedir(LValueStor *lvs)
107 {
108         DirStor *ds = lvs->s_Addr;
109
110         if (ds->dir) {
111                 closedir(ds->dir);
112                 ds->dir = NULL;
113         }
114 }
115
116 void
117 RuneSysCall_dirfd(LValueStor *lvs, int *resp) 
118 {
119         DirStor *ds = lvs->s_Addr;
120
121         if (ds->dir) {
122                 *resp = dirfd(ds->dir);
123                 if (*resp < 0)
124                         ds->error = errno;
125                 else
126                         ds->error = 0;
127         } else {
128                 *resp = -1;
129                 ds->error = EINVAL;
130         }
131 }