6f4c0b6a12e2c88e1b1a062d99b6f967361fc2d1
[perl.git] / do / dirop
1 int
2 do_dirop(optype,stab,gimme,arglast)
3 int optype;
4 STAB *stab;
5 int gimme;
6 int *arglast;
7 {
8 #if defined(DIRENT) && defined(HAS_READDIR)
9     register ARRAY *ary = stack;
10     register STR **st = ary->ary_array;
11     register int sp = arglast[1];
12     register STIO *stio;
13     long along;
14 #ifndef apollo
15     struct DIRENT *readdir();
16 #endif
17     register struct DIRENT *dp;
18
19     if (!stab)
20         goto nope;
21     if (!(stio = stab_io(stab)))
22         stio = stab_io(stab) = stio_new();
23     if (!stio->dirp && optype != O_OPEN_DIR)
24         goto nope;
25     st[sp] = &str_yes;
26     switch (optype) {
27     case O_OPEN_DIR:
28         if (stio->dirp)
29             closedir(stio->dirp);
30         if (!(stio->dirp = opendir(str_get(st[sp+1]))))
31             goto nope;
32         break;
33     case O_READDIR:
34         if (gimme == G_ARRAY) {
35             --sp;
36             /*SUPPRESS 560*/
37             while (dp = readdir(stio->dirp)) {
38 #ifdef DIRNAMLEN
39                 (void)astore(ary,++sp,
40                   str_2mortal(str_make(dp->d_name,dp->d_namlen)));
41 #else
42                 (void)astore(ary,++sp,
43                   str_2mortal(str_make(dp->d_name,0)));
44 #endif
45             }
46         }
47         else {
48             if (!(dp = readdir(stio->dirp)))
49                 goto nope;
50             st[sp] = str_mortal(&str_undef);
51 #ifdef DIRNAMLEN
52             str_nset(st[sp], dp->d_name, dp->d_namlen);
53 #else
54             str_set(st[sp], dp->d_name);
55 #endif
56         }
57         break;
58 #if defined(HAS_TELLDIR) || defined(telldir)
59     case O_TELLDIR: {
60 #ifndef telldir
61             long telldir();
62 #endif
63             st[sp] = str_mortal(&str_undef);
64             str_numset(st[sp], (double)telldir(stio->dirp));
65             break;
66         }
67 #endif
68 #if defined(HAS_SEEKDIR) || defined(seekdir)
69     case O_SEEKDIR:
70         st[sp] = str_mortal(&str_undef);
71         along = (long)str_gnum(st[sp+1]);
72         (void)seekdir(stio->dirp,along);
73         break;
74 #endif
75 #if defined(HAS_REWINDDIR) || defined(rewinddir)
76     case O_REWINDDIR:
77         st[sp] = str_mortal(&str_undef);
78         (void)rewinddir(stio->dirp);
79         break;
80 #endif
81     case O_CLOSEDIR:
82         st[sp] = str_mortal(&str_undef);
83         (void)closedir(stio->dirp);
84         stio->dirp = 0;
85         break;
86     default:
87         goto phooey;
88     }
89     return sp;
90
91 nope:
92     st[sp] = &str_undef;
93     if (!errno)
94         errno = EBADF;
95     return sp;
96
97 #endif
98 phooey:
99     fatal("Unimplemented directory operation");
100 }
101