long len;
long idx;
char scanname[MAX_PATH+3];
- Stat_t sbuf;
WIN32_FIND_DATAA aFindData;
WIN32_FIND_DATAW wFindData;
bool using_wide;
char *ptr;
len = strlen(filename);
- if (len > MAX_PATH)
+ if (len == 0) {
+ errno = ENOENT;
return NULL;
-
- /* check to see if filename is a directory */
- if (win32_stat(filename, &sbuf) < 0 || !S_ISDIR(sbuf.st_mode))
+ }
+ if (len > MAX_PATH) {
+ errno = ENAMETOOLONG;
return NULL;
+ }
+
+#if 0 /* This call to stat is unnecessary. The FindFirstFile() below will
+ * fail with ERROR_PATH_NOT_FOUND if filename is not a directory. */
+ {
+ /* check to see if filename is a directory */
+ Stat_t sbuf;
+ if (win32_stat(filename, &sbuf) < 0 || !S_ISDIR(sbuf.st_mode))
+ return NULL;
+ }
+#endif
/* Get us a DIR structure */
Newxz(dirp, 1, DIR);
char buffer[MAX_PATH*2];
char *ptr;
+ if (dirp->handle == INVALID_HANDLE_VALUE) {
+ res = 0;
+ }
/* finding the next file that matches the wildcard
* (which should be all of them in this directory!).
*/
- if (IsWin2000()) {
+ else if (IsWin2000()) {
WIN32_FIND_DATAW wFindData;
res = FindNextFileW(dirp->handle, &wFindData);
if (res) {
dirp->end = dirp->start + newsize;
dirp->nfiles++;
}
- else
+ else {
dirp->curr = NULL;
+ if (dirp->handle != INVALID_HANDLE_VALUE) {
+ FindClose(dirp->handle);
+ dirp->handle = INVALID_HANDLE_VALUE;
+ }
+ }
}
return &(dirp->dirstr);
}
DllExport long
win32_telldir(DIR *dirp)
{
- return (dirp->curr - dirp->start);
+ return dirp->curr ? (dirp->curr - dirp->start) : -1;
}
DllExport void
win32_seekdir(DIR *dirp, long loc)
{
- dirp->curr = dirp->start + loc;
+ dirp->curr = loc == -1 ? NULL : dirp->start + loc;
}
/* Rewinddir resets the string pointer to the start */
return 1;
}
+/* duplicate a open DIR* for interpreter cloning */
+DllExport DIR *
+win32_dirp_dup(DIR *const dirp, CLONE_PARAMS *const param)
+{
+ dVAR;
+ PerlInterpreter *const from = param->proto_perl;
+ PerlInterpreter *const to = PERL_GET_THX;
+
+ long pos;
+ DIR *dup;
+
+ /* switch back to original interpreter because win32_readdir()
+ * might Renew(dirp->start).
+ */
+ if (from != to) {
+ PERL_SET_THX(from);
+ }
+
+ /* mark current position; read all remaining entries into the
+ * cache, and then restore to current position.
+ */
+ pos = win32_telldir(dirp);
+ while (win32_readdir(dirp)) {
+ /* read all entries into cache */
+ }
+ win32_seekdir(dirp, pos);
+
+ /* switch back to new interpreter to allocate new DIR structure */
+ if (from != to) {
+ PERL_SET_THX(to);
+ }
+
+ Newx(dup, 1, DIR);
+ memcpy(dup, dirp, sizeof(DIR));
+
+ Newx(dup->start, dirp->size, char);
+ memcpy(dup->start, dirp->start, dirp->size);
+
+ dup->end = dup->start + (dirp->end - dirp->start);
+ if (dirp->curr)
+ dup->curr = dup->start + (dirp->curr - dirp->start);
+
+ return dup;
+}
/*
* various stubs
}
DllExport int
+win32_isatty(int fd)
+{
+ /* The Microsoft isatty() function returns true for *all*
+ * character mode devices, including "nul". Our implementation
+ * should only return true if the handle has a console buffer.
+ */
+ DWORD mode;
+ HANDLE fh = (HANDLE)_get_osfhandle(fd);
+ if (fh == (HANDLE)-1) {
+ /* errno is already set to EBADF */
+ return 0;
+ }
+
+ if (GetConsoleMode(fh, &mode))
+ return 1;
+
+ errno = ENOTTY;
+ return 0;
+}
+
+DllExport int
win32_dup(int fd)
{
return dup(fd);