summaryrefslogtreecommitdiff
path: root/do/dirop
diff options
context:
space:
mode:
Diffstat (limited to 'do/dirop')
-rw-r--r--do/dirop101
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");
+}
+