VirtualBox

source: kBuild/trunk/src/kmk/w32/compat/dirent.c@ 1920

Last change on this file since 1920 was 1557, checked in by bird, 17 years ago

fixed opendir with trailing slash (stat failed).

  • Property svn:eol-style set to native
File size: 4.5 KB
Line 
1/* Directory entry code for Window platforms.
2Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
32006 Free Software Foundation, Inc.
4This file is part of GNU Make.
5
6GNU Make is free software; you can redistribute it and/or modify it under the
7terms of the GNU General Public License as published by the Free Software
8Foundation; either version 2, or (at your option) any later version.
9
10GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
11WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License along with
15GNU Make; see the file COPYING. If not, write to the Free Software
16Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */
17
18
19#ifdef KMK
20# include "config.h" /* my_stat */
21#endif
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <errno.h>
25#include <string.h>
26#include <stdlib.h>
27#ifdef KMK_PRF
28# include <stdio.h>
29#endif
30#include "dirent.h"
31
32
33DIR*
34opendir(const char* pDirName)
35{
36 struct stat sb;
37 DIR* pDir;
38 char* pEndDirName;
39 int nBufferLen;
40
41 /* sanity checks */
42 if (!pDirName) {
43 errno = EINVAL;
44 return NULL;
45 }
46 if (stat(pDirName, &sb) != 0) {
47 errno = ENOENT;
48 return NULL;
49 }
50 if ((sb.st_mode & S_IFMT) != S_IFDIR) {
51 errno = ENOTDIR;
52 return NULL;
53 }
54
55 /* allocate a DIR structure to return */
56 pDir = (DIR *) malloc(sizeof (DIR));
57
58 if (!pDir)
59 return NULL;
60
61 /* input directory name length */
62 nBufferLen = strlen(pDirName);
63
64 /* copy input directory name to DIR buffer */
65 strcpy(pDir->dir_pDirectoryName, pDirName);
66
67 /* point to end of the copied directory name */
68 pEndDirName = &pDir->dir_pDirectoryName[nBufferLen - 1];
69
70 /* if directory name did not end in '/' or '\', add '/' */
71 if ((*pEndDirName != '/') && (*pEndDirName != '\\')) {
72 pEndDirName++;
73 *pEndDirName = '/';
74 }
75
76 /* now append the wildcard character to the buffer */
77 pEndDirName++;
78 *pEndDirName = '*';
79 pEndDirName++;
80 *pEndDirName = '\0';
81
82 /* other values defaulted */
83 pDir->dir_nNumFiles = 0;
84 pDir->dir_hDirHandle = INVALID_HANDLE_VALUE;
85 pDir->dir_ulCookie = __DIRENT_COOKIE;
86
87#ifdef KMK_PRF
88 fprintf(stderr, "opendir(%s) -> %p\n", pDirName, pDir);
89#endif
90 return pDir;
91}
92
93void
94closedir(DIR *pDir)
95{
96 /* got a valid pointer? */
97 if (!pDir) {
98 errno = EINVAL;
99 return;
100 }
101
102 /* sanity check that this is a DIR pointer */
103 if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
104 errno = EINVAL;
105 return;
106 }
107
108 /* close the WINDOWS32 directory handle */
109 if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE)
110 FindClose(pDir->dir_hDirHandle);
111
112 free(pDir);
113
114 return;
115}
116
117struct dirent *
118readdir(DIR* pDir)
119{
120 WIN32_FIND_DATA wfdFindData;
121
122 if (!pDir) {
123 errno = EINVAL;
124 return NULL;
125 }
126
127 /* sanity check that this is a DIR pointer */
128 if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
129 errno = EINVAL;
130 return NULL;
131 }
132
133 if (pDir->dir_nNumFiles == 0) {
134 pDir->dir_hDirHandle = FindFirstFile(pDir->dir_pDirectoryName, &wfdFindData);
135 if (pDir->dir_hDirHandle == INVALID_HANDLE_VALUE)
136 return NULL;
137 } else if (!FindNextFile(pDir->dir_hDirHandle, &wfdFindData))
138 return NULL;
139
140 /* bump count for next call to readdir() or telldir() */
141 pDir->dir_nNumFiles++;
142
143 /* fill in struct dirent values */
144 pDir->dir_sdReturn.d_ino = -1;
145 strcpy(pDir->dir_sdReturn.d_name, wfdFindData.cFileName);
146
147 return &pDir->dir_sdReturn;
148}
149
150void
151rewinddir(DIR* pDir)
152{
153 if (!pDir) {
154 errno = EINVAL;
155 return;
156 }
157
158 /* sanity check that this is a DIR pointer */
159 if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
160 errno = EINVAL;
161 return;
162 }
163
164 /* close the WINDOWS32 directory handle */
165 if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE)
166 if (!FindClose(pDir->dir_hDirHandle))
167 errno = EBADF;
168
169 /* reset members which control readdir() */
170 pDir->dir_hDirHandle = INVALID_HANDLE_VALUE;
171 pDir->dir_nNumFiles = 0;
172
173 return;
174}
175
176int
177telldir(DIR* pDir)
178{
179 if (!pDir) {
180 errno = EINVAL;
181 return -1;
182 }
183
184 /* sanity check that this is a DIR pointer */
185 if (pDir->dir_ulCookie != __DIRENT_COOKIE) {
186 errno = EINVAL;
187 return -1;
188 }
189
190 /* return number of times readdir() called */
191 return pDir->dir_nNumFiles;
192}
193
194void
195seekdir(DIR* pDir, long nPosition)
196{
197 if (!pDir)
198 return;
199
200 /* sanity check that this is a DIR pointer */
201 if (pDir->dir_ulCookie != __DIRENT_COOKIE)
202 return;
203
204 /* go back to beginning of directory */
205 rewinddir(pDir);
206
207 /* loop until we have found position we care about */
208 for (--nPosition; nPosition && readdir(pDir); nPosition--);
209
210 /* flag invalid nPosition value */
211 if (nPosition)
212 errno = EINVAL;
213
214 return;
215}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette