diff options
Diffstat (limited to 'do/dirop')
-rw-r--r-- | do/dirop | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/do/dirop b/do/dirop new file mode 100644 index 0000000000..6f4c0b6a12 --- /dev/null +++ b/do/dirop @@ -0,0 +1,101 @@ +int +do_dirop(optype,stab,gimme,arglast) +int optype; +STAB *stab; +int gimme; +int *arglast; +{ +#if defined(DIRENT) && defined(HAS_READDIR) + register ARRAY *ary = stack; + register STR **st = ary->ary_array; + register int sp = arglast[1]; + register STIO *stio; + long along; +#ifndef apollo + struct DIRENT *readdir(); +#endif + register struct DIRENT *dp; + + if (!stab) + goto nope; + if (!(stio = stab_io(stab))) + stio = stab_io(stab) = stio_new(); + if (!stio->dirp && optype != O_OPEN_DIR) + goto nope; + st[sp] = &str_yes; + switch (optype) { + case O_OPEN_DIR: + if (stio->dirp) + closedir(stio->dirp); + if (!(stio->dirp = opendir(str_get(st[sp+1])))) + goto nope; + break; + case O_READDIR: + if (gimme == G_ARRAY) { + --sp; + /*SUPPRESS 560*/ + while (dp = readdir(stio->dirp)) { +#ifdef DIRNAMLEN + (void)astore(ary,++sp, + str_2mortal(str_make(dp->d_name,dp->d_namlen))); +#else + (void)astore(ary,++sp, + str_2mortal(str_make(dp->d_name,0))); +#endif + } + } + else { + if (!(dp = readdir(stio->dirp))) + goto nope; + st[sp] = str_mortal(&str_undef); +#ifdef DIRNAMLEN + str_nset(st[sp], dp->d_name, dp->d_namlen); +#else + str_set(st[sp], dp->d_name); +#endif + } + break; +#if defined(HAS_TELLDIR) || defined(telldir) + case O_TELLDIR: { +#ifndef telldir + long telldir(); +#endif + st[sp] = str_mortal(&str_undef); + str_numset(st[sp], (double)telldir(stio->dirp)); + break; + } +#endif +#if defined(HAS_SEEKDIR) || defined(seekdir) + case O_SEEKDIR: + st[sp] = str_mortal(&str_undef); + along = (long)str_gnum(st[sp+1]); + (void)seekdir(stio->dirp,along); + break; +#endif +#if defined(HAS_REWINDDIR) || defined(rewinddir) + case O_REWINDDIR: + st[sp] = str_mortal(&str_undef); + (void)rewinddir(stio->dirp); + break; +#endif + case O_CLOSEDIR: + st[sp] = str_mortal(&str_undef); + (void)closedir(stio->dirp); + stio->dirp = 0; + break; + default: + goto phooey; + } + return sp; + +nope: + st[sp] = &str_undef; + if (!errno) + errno = EBADF; + return sp; + +#endif +phooey: + fatal("Unimplemented directory operation"); +} + |