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