4 Interface for perl directory functions
10 class CPerlDir : public IPerlDir
13 CPerlDir() { pPerl = NULL; };
14 virtual int MKdir(const char *dirname, int mode, int &err);
15 virtual int Chdir(const char *dirname, int &err);
16 virtual int Rmdir(const char *dirname, int &err);
17 virtual int Close(DIR *dirp, int &err);
18 virtual DIR *Open(char *filename, int &err);
19 virtual struct direct *Read(DIR *dirp, int &err);
20 virtual void Rewind(DIR *dirp, int &err);
21 virtual void Seek(DIR *dirp, long loc, int &err);
22 virtual long Tell(DIR *dirp, int &err);
24 inline void SetPerlObj(CPerlObj *p) { pPerl = p; };
29 int CPerlDir::MKdir(const char *dirname, int mode, int &err)
31 return mkdir(dirname); /* just ignore mode */
34 int CPerlDir::Chdir(const char *dirname, int &err)
36 return chdir(dirname);
39 int CPerlDir::Rmdir(const char *dirname, int &err)
41 return rmdir(dirname);
45 // The idea here is to read all the directory names into a string table
46 // (separated by nulls) and when one of the other dir functions is called
47 // return the pointer to the current file name.
48 DIR *CPerlDir::Open(char *filename, int &err)
53 char scannamespc[PATHLEN];
54 char *scanname = scannamespc;
56 WIN32_FIND_DATA FindData;
59 // Create the search pattern
60 strcpy(scanname, filename);
62 len = strlen(scanname);
63 if(len > 1 && ((scanname[len-1] == '/') || (scanname[len-1] == '\\')))
65 // allow directory names of 'x:\' to pass
66 if(!(len == 3 && scanname[1] == ':'))
67 scanname[len-1] = '\0';
70 // check to see if filename is a directory
71 if(stat(scanname, &sbuf) < 0 || sbuf.st_mode & _S_IFDIR == 0)
73 DWORD dTemp = GetFileAttributes(scanname);
74 if(dTemp == 0xffffffff || !(dTemp & FILE_ATTRIBUTE_DIRECTORY))
80 if((scanname[len-1] == '/') || (scanname[len-1] == '\\'))
81 scanname[len-1] = '\0';
83 strcat(scanname, "/*");
85 // Get a DIR structure
86 Newz(1501, p, 1, DIR);
90 // do the FindFirstFile call
91 fh = FindFirstFile(scanname, &FindData);
92 if(fh == INVALID_HANDLE_VALUE)
98 // now allocate the first part of the string table for the filenames that we find.
99 idx = strlen(FindData.cFileName)+1;
100 New(1502, p->start, idx, char);
104 croak("opendir: malloc failed!\n");
106 strcpy(p->start, FindData.cFileName);
109 // loop finding all the files that match the wildcard
110 // (which should be all of them in this directory!).
111 // the variable idx should point one past the null terminator
112 // of the previous string found.
114 while(FindNextFile(fh, &FindData))
116 len = strlen(FindData.cFileName);
117 // bump the string table size by enough for the
118 // new name and it's null terminator
119 Renew(p->start, idx+len+1, char);
123 croak("opendir: malloc failed!\n");
125 strcpy(&p->start[idx], FindData.cFileName);
135 int CPerlDir::Close(DIR *dirp, int &err)
137 Safefree(dirp->start);
142 // Readdir just returns the current string pointer and bumps the
143 // string pointer to the next entry.
144 struct direct *CPerlDir::Read(DIR *dirp, int &err)
147 static int dummy = 0;
150 { // first set up the structure to return
151 len = strlen(dirp->curr);
152 strcpy(dirp->dirstr.d_name, dirp->curr);
153 dirp->dirstr.d_namlen = len;
156 dirp->dirstr.d_ino = dummy++;
158 // Now set up for the next call to readdir
159 dirp->curr += len + 1;
160 if(dirp->curr >= (dirp->start + dirp->size))
165 return &(dirp->dirstr);
171 void CPerlDir::Rewind(DIR *dirp, int &err)
173 dirp->curr = dirp->start;
176 void CPerlDir::Seek(DIR *dirp, long loc, int &err)
178 dirp->curr = (char *)loc;
181 long CPerlDir::Tell(DIR *dirp, int &err)
183 return (long) dirp->curr;