/* * SYS_DIRECTORY.C */ #include "defs.h" #include /* * DirStor */ typedef struct DirStor { DIR *dir; int error; int type; runeino_t ino; runesize_t namlen; LValueStor namelvs; } DirStor; struct opendir_args { LValueStor lvs; PointerStor path; }; struct fdopendir_args { LValueStor lvs; int fd; #if LONG_BITS == 64 int filler01; #endif }; /* * Normal read */ void RuneSysCall_opendir(struct opendir_args *args, int *resp) { DirStor *ds = args->lvs.s_Addr; const char *path = args->path.s_Addr; STRBOUNDSCHECK(&args->path, PATH_MAX); ds->dir = opendir(path); printf("OPEN %s\n", path); if (ds->dir == NULL) { ds->error = errno; *resp = -1; } else { ds->error = 0; *resp = 0; } } void RuneSysCall_fdopendir(struct fdopendir_args *args, int *resp) { DirStor *ds = args->lvs.s_Addr; ds->dir = fdopendir(args->fd); if (ds->dir == NULL) { ds->error = errno; *resp = -1; } else { ds->error = 0; *resp = 0; } } void RuneSysCall_readdir(LValueStor *lvs, int *resp) { DirStor *ds = lvs->s_Addr; struct dirent *den; char *ptr; den = readdir(ds->dir); ptr = ds->namelvs.s_Addr; if (den) { ds->type = den->d_type; ds->namlen = den->d_namlen; ds->ino = den->d_ino; dassert(ds->namlen + 1 <= ds->namelvs.s_Type->ty_Bytes); bcopy(den->d_name, ptr, ds->namlen); ptr[ds->namlen] = 0; *resp = 1; } else { ds->type = 0; ds->namlen = 0; ds->ino = -1; dassert(1 <= ds->namelvs.s_Type->ty_Bytes); ptr[0] = 0; *resp = 0; } } void RuneSysCall_rewinddir(LValueStor *lvs) { DirStor *ds = lvs->s_Addr; rewinddir(ds->dir); } void RuneSysCall_closedir(LValueStor *lvs) { DirStor *ds = lvs->s_Addr; if (ds->dir) { closedir(ds->dir); ds->dir = NULL; } } void RuneSysCall_dirfd(LValueStor *lvs, int *resp) { DirStor *ds = lvs->s_Addr; if (ds->dir) { *resp = dirfd(ds->dir); if (*resp < 0) ds->error = errno; else ds->error = 0; } else { *resp = -1; ds->error = EINVAL; } }