1 /*-------------------------------------------------------------------------
4 * opendir/readdir/closedir for win32/msvc
6 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
13 *-------------------------------------------------------------------------
19 #include "postgres_fe.h"
28 struct dirent ret
; /* Used to return to caller */
33 opendir(const char *dirname
)
38 /* Make sure it is a directory */
39 attr
= GetFileAttributes(dirname
);
40 if (attr
== INVALID_FILE_ATTRIBUTES
)
45 if ((attr
& FILE_ATTRIBUTE_DIRECTORY
) != FILE_ATTRIBUTE_DIRECTORY
)
51 d
= malloc(sizeof(DIR));
57 d
->dirname
= malloc(strlen(dirname
) + 4);
64 strcpy(d
->dirname
, dirname
);
65 if (d
->dirname
[strlen(d
->dirname
) - 1] != '/' &&
66 d
->dirname
[strlen(d
->dirname
) - 1] != '\\')
67 strcat(d
->dirname
, "\\"); /* Append backslash if not already there */
68 strcat(d
->dirname
, "*"); /* Search for entries named anything */
69 d
->handle
= INVALID_HANDLE_VALUE
;
70 d
->ret
.d_ino
= 0; /* no inodes on win32 */
71 d
->ret
.d_reclen
= 0; /* not used on win32 */
72 d
->ret
.d_type
= DT_UNKNOWN
;
82 if (d
->handle
== INVALID_HANDLE_VALUE
)
84 d
->handle
= FindFirstFile(d
->dirname
, &fd
);
85 if (d
->handle
== INVALID_HANDLE_VALUE
)
87 /* If there are no files, force errno=0 (unlike mingw) */
88 if (GetLastError() == ERROR_FILE_NOT_FOUND
)
91 _dosmaperr(GetLastError());
97 if (!FindNextFile(d
->handle
, &fd
))
99 /* If there are no more files, force errno=0 (like mingw) */
100 if (GetLastError() == ERROR_NO_MORE_FILES
)
103 _dosmaperr(GetLastError());
107 strcpy(d
->ret
.d_name
, fd
.cFileName
); /* Both strings are MAX_PATH long */
108 d
->ret
.d_namlen
= strlen(d
->ret
.d_name
);
109 /* The only identified types are: directory, regular file or symbolic link */
110 if ((fd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) != 0)
111 d
->ret
.d_type
= DT_DIR
;
112 /* For reparse points dwReserved0 field will contain the ReparseTag */
113 else if ((fd
.dwFileAttributes
& FILE_ATTRIBUTE_REPARSE_POINT
) != 0 &&
114 (fd
.dwReserved0
== IO_REPARSE_TAG_MOUNT_POINT
))
115 d
->ret
.d_type
= DT_LNK
;
117 d
->ret
.d_type
= DT_REG
;
127 if (d
->handle
!= INVALID_HANDLE_VALUE
)
128 ret
= !FindClose(d
->handle
);