This commit was manufactured by cvs2svn to create tag
[kbuild-mirror.git] / src / gmake / w32 / compat / dirent.c
blob566fba971c662a7bf0773b69dc751b2f7a010938
1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <errno.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include "dirent.h"
9 DIR*
10 opendir(const char* pDirName)
12 struct stat sb;
13 DIR* pDir;
14 char* pEndDirName;
15 int nBufferLen;
17 /* sanity checks */
18 if (!pDirName) {
19 errno = EINVAL;
20 return NULL;
22 if (stat(pDirName, &sb) != 0) {
23 errno = ENOENT;
24 return NULL;
26 if ((sb.st_mode & S_IFMT) != S_IFDIR) {
27 errno = ENOTDIR;
28 return NULL;
31 /* allocate a DIR structure to return */
32 pDir = (DIR *) malloc(sizeof (DIR));
34 if (!pDir)
35 return NULL;
37 /* input directory name length */
38 nBufferLen = strlen(pDirName);
40 /* copy input directory name to DIR buffer */
41 strcpy(pDir->dir_pDirectoryName, pDirName);
43 /* point to end of the copied directory name */
44 pEndDirName = &pDir->dir_pDirectoryName[nBufferLen - 1];
46 /* if directory name did not end in '/' or '\', add '/' */
47 if ((*pEndDirName != '/') && (*pEndDirName != '\\')) {
48 pEndDirName++;
49 *pEndDirName = '/';
52 /* now append the wildcard character to the buffer */
53 pEndDirName++;
54 *pEndDirName = '*';
55 pEndDirName++;
56 *pEndDirName = '\0';
58 /* other values defaulted */
59 pDir->dir_nNumFiles = 0;
60 pDir->dir_hDirHandle = INVALID_HANDLE_VALUE;
61 pDir->dir_ulCookie = __DIRENT_COOKIE;
63 return pDir;
66 void
67 closedir(DIR *pDir)
69 /* got a valid pointer? */
70 if (!pDir) {
71 errno = EINVAL;
72 return;
75 /* sanity check that this is a DIR pointer */
76 if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
77 errno = EINVAL;
78 return;
81 /* close the WINDOWS32 directory handle */
82 if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE)
83 FindClose(pDir->dir_hDirHandle);
85 free(pDir);
87 return;
90 struct dirent *
91 readdir(DIR* pDir)
93 WIN32_FIND_DATA wfdFindData;
95 if (!pDir) {
96 errno = EINVAL;
97 return NULL;
100 /* sanity check that this is a DIR pointer */
101 if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
102 errno = EINVAL;
103 return NULL;
106 if (pDir->dir_nNumFiles == 0) {
107 pDir->dir_hDirHandle = FindFirstFile(pDir->dir_pDirectoryName, &wfdFindData);
108 if (pDir->dir_hDirHandle == INVALID_HANDLE_VALUE)
109 return NULL;
110 } else if (!FindNextFile(pDir->dir_hDirHandle, &wfdFindData))
111 return NULL;
113 /* bump count for next call to readdir() or telldir() */
114 pDir->dir_nNumFiles++;
116 /* fill in struct dirent values */
117 pDir->dir_sdReturn.d_ino = -1;
118 strcpy(pDir->dir_sdReturn.d_name, wfdFindData.cFileName);
120 return &pDir->dir_sdReturn;
123 void
124 rewinddir(DIR* pDir)
126 if (!pDir) {
127 errno = EINVAL;
128 return;
131 /* sanity check that this is a DIR pointer */
132 if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
133 errno = EINVAL;
134 return;
137 /* close the WINDOWS32 directory handle */
138 if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE)
139 if (!FindClose(pDir->dir_hDirHandle))
140 errno = EBADF;
142 /* reset members which control readdir() */
143 pDir->dir_hDirHandle = INVALID_HANDLE_VALUE;
144 pDir->dir_nNumFiles = 0;
146 return;
150 telldir(DIR* pDir)
152 if (!pDir) {
153 errno = EINVAL;
154 return -1;
157 /* sanity check that this is a DIR pointer */
158 if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
159 errno = EINVAL;
160 return -1;
163 /* return number of times readdir() called */
164 return pDir->dir_nNumFiles;
167 void
168 seekdir(DIR* pDir, long nPosition)
170 if (!pDir)
171 return;
173 /* sanity check that this is a DIR pointer */
174 if (pDir->dir_ulCookie != __DIRENT_COOKIE)
175 return;
177 /* go back to beginning of directory */
178 rewinddir(pDir);
180 /* loop until we have found position we care about */
181 for (--nPosition; nPosition && readdir(pDir); nPosition--);
183 /* flag invalid nPosition value */
184 if (nPosition)
185 errno = EINVAL;
187 return;