Fossil

Check-in [ea621d75ef]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Always use wide-character Win32 APIs for dirent.h.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ea621d75efeadb6ac8e9840b7b7a4c03e54120e6
User & Date: mistachkin 2012-09-23 23:52:58.975
Context
2012-09-24
07:00
previous commit fixed the MSVC build, but broke the mingw build. Now fix both of them. check-in: 1ef58e5246 user: jan.nijtmans tags: trunk
2012-09-23
23:52
Always use wide-character Win32 APIs for dirent.h. check-in: ea621d75ef user: mistachkin tags: trunk
05:00
Fixes for compilation with MSVC. check-in: bb85c12e10 user: mistachkin tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/file.c.
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
}

/*
** Portable unicode implementation of opendir()
*/
#if INTERFACE

#if defined(_WIN32)
# include <dirent.h>
# define FOSSIL_DIR _WDIR
# define fossil_dirent _wdirent
# define fossil_opendir _wopendir
# define fossil_readdir _wreaddir
# define fossil_closedir _wclosedir
#else
# include <dirent.h>
# define FOSSIL_DIR DIR
# define fossil_dirent dirent
# define fossil_opendir opendir
# define fossil_readdir readdir
# define fossil_closedir closedir
#endif

#endif /* INTERFACE */



/**************************************************************************
** The following routines translate between MBCS and UTF8 on windows.







<
|
<
<
<
<
<
<
<
|
|
|
|
|
<







1006
1007
1008
1009
1010
1011
1012

1013







1014
1015
1016
1017
1018

1019
1020
1021
1022
1023
1024
1025
}

/*
** Portable unicode implementation of opendir()
*/
#if INTERFACE


#include <dirent.h>







#define FOSSIL_DIR DIR
#define fossil_dirent dirent
#define fossil_opendir opendir
#define fossil_readdir readdir
#define fossil_closedir closedir


#endif /* INTERFACE */



/**************************************************************************
** The following routines translate between MBCS and UTF8 on windows.
Changes to src/makemake.tcl.
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
ZLIBDIR = $(MSCDIR)\extra\lib
ZLIB    = zlib.lib

INCL   = -I. -I$(SRCDIR) -I$B\win\include -I$(MSCDIR)\extra\include -I$(ZINCDIR)

CFLAGS = -nologo -MT -O2
BCC    = $(CC) $(CFLAGS)
TCC    = $(CC) -c $(CFLAGS) -DDIRENT_UNICODE=1 $(MSCDEF) $(SSL) $(INCL)
LIBS   = $(ZLIB) ws2_32.lib advapi32.lib $(SSLLIB)
LIBDIR = -LIBPATH:$(MSCDIR)\extra\lib -LIBPATH:$(ZLIBDIR)
}
regsub -all {[-]D} $SQLITE_OPTIONS {/D} MSC_SQLITE_OPTIONS
writeln "SQLITE_OPTIONS = $MSC_SQLITE_OPTIONS\n"
writeln -nonewline "SRC   = "
foreach s [lsort $src] {







|







901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
ZLIBDIR = $(MSCDIR)\extra\lib
ZLIB    = zlib.lib

INCL   = -I. -I$(SRCDIR) -I$B\win\include -I$(MSCDIR)\extra\include -I$(ZINCDIR)

CFLAGS = -nologo -MT -O2
BCC    = $(CC) $(CFLAGS)
TCC    = $(CC) -c $(CFLAGS) $(MSCDEF) $(SSL) $(INCL)
LIBS   = $(ZLIB) ws2_32.lib advapi32.lib $(SSLLIB)
LIBDIR = -LIBPATH:$(MSCDIR)\extra\lib -LIBPATH:$(ZLIBDIR)
}
regsub -all {[-]D} $SQLITE_OPTIONS {/D} MSC_SQLITE_OPTIONS
writeln "SQLITE_OPTIONS = $MSC_SQLITE_OPTIONS\n"
writeln -nonewline "SRC   = "
foreach s [lsort $src] {
Changes to win/Makefile.msc.
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
ZLIBDIR = $(MSCDIR)\extra\lib
ZLIB    = zlib.lib

INCL   = -I. -I$(SRCDIR) -I$B\win\include -I$(MSCDIR)\extra\include -I$(ZINCDIR)

CFLAGS = -nologo -MT -O2
BCC    = $(CC) $(CFLAGS)
TCC    = $(CC) -c $(CFLAGS) -DDIRENT_UNICODE=1 $(MSCDEF) $(SSL) $(INCL)
LIBS   = $(ZLIB) ws2_32.lib advapi32.lib $(SSLLIB)
LIBDIR = -LIBPATH:$(MSCDIR)\extra\lib -LIBPATH:$(ZLIBDIR)

SQLITE_OPTIONS = /DSQLITE_OMIT_LOAD_EXTENSION=1 /DSQLITE_THREADSAFE=0 /DSQLITE_DEFAULT_FILE_FORMAT=4 /DSQLITE_ENABLE_STAT3 /Dlocaltime=fossil_localtime /DSQLITE_ENABLE_LOCKING_STYLE=0

SRC   = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c main_.c manifest_.c md5_.c merge_.c merge3_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c update_.c url_.c user_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c 








|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
ZLIBDIR = $(MSCDIR)\extra\lib
ZLIB    = zlib.lib

INCL   = -I. -I$(SRCDIR) -I$B\win\include -I$(MSCDIR)\extra\include -I$(ZINCDIR)

CFLAGS = -nologo -MT -O2
BCC    = $(CC) $(CFLAGS)
TCC    = $(CC) -c $(CFLAGS) $(MSCDEF) $(SSL) $(INCL)
LIBS   = $(ZLIB) ws2_32.lib advapi32.lib $(SSLLIB)
LIBDIR = -LIBPATH:$(MSCDIR)\extra\lib -LIBPATH:$(ZLIBDIR)

SQLITE_OPTIONS = /DSQLITE_OMIT_LOAD_EXTENSION=1 /DSQLITE_THREADSAFE=0 /DSQLITE_DEFAULT_FILE_FORMAT=4 /DSQLITE_ENABLE_STAT3 /Dlocaltime=fossil_localtime /DSQLITE_ENABLE_LOCKING_STYLE=0

SRC   = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c main_.c manifest_.c md5_.c merge_.c merge3_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c update_.c url_.c user_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c 

Changes to win/Makefile.msc.mistachkin.
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
ZLIBDIR = $(SRCDIR)\..\zlib-1.2.7
ZLIB    = zlib.lib

INCL   = -I. -I$(SRCDIR) -I$B\win\include -I$(ZINCDIR)

CFLAGS = -nologo -MT -O2
BCC    = $(CC) $(CFLAGS)
TCC    = $(CC) -c $(CFLAGS) -DDIRENT_UNICODE=1 $(MSCDEF) $(SSL) $(INCL)
LIBS   = $(ZLIB) ws2_32.lib advapi32.lib $(SSLLIB)
LIBDIR = -LIBPATH:$(ZLIBDIR)

SQLITE_OPTIONS = /DSQLITE_OMIT_LOAD_EXTENSION=1 /DSQLITE_THREADSAFE=0 /DSQLITE_DEFAULT_FILE_FORMAT=4 /DSQLITE_ENABLE_STAT3 /Dlocaltime=fossil_localtime /DSQLITE_ENABLE_LOCKING_STYLE=0

SRC   = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c main_.c manifest_.c md5_.c merge_.c merge3_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c update_.c url_.c user_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c 








|







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
ZLIBDIR = $(SRCDIR)\..\zlib-1.2.7
ZLIB    = zlib.lib

INCL   = -I. -I$(SRCDIR) -I$B\win\include -I$(ZINCDIR)

CFLAGS = -nologo -MT -O2
BCC    = $(CC) $(CFLAGS)
TCC    = $(CC) -c $(CFLAGS) $(MSCDEF) $(SSL) $(INCL)
LIBS   = $(ZLIB) ws2_32.lib advapi32.lib $(SSLLIB)
LIBDIR = -LIBPATH:$(ZLIBDIR)

SQLITE_OPTIONS = /DSQLITE_OMIT_LOAD_EXTENSION=1 /DSQLITE_THREADSAFE=0 /DSQLITE_DEFAULT_FILE_FORMAT=4 /DSQLITE_ENABLE_STAT3 /Dlocaltime=fossil_localtime /DSQLITE_ENABLE_LOCKING_STYLE=0

SRC   = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c main_.c manifest_.c md5_.c merge_.c merge3_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c update_.c url_.c user_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c 

Changes to win/include/dirent.h.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Sept 22, 2012, Joe Mistachkin
 * Check for DIRENT_UNICODE define in addition to UNICODE.
 *
 * Sept 12, 2012, Jan Nijtmans
 * Switchable wide-character variant.
 *
 * Mar 15, 2011, Toni Ronkko
 * Defined FILE_ATTRIBUTE_DEVICE for MSVC 6.0.
 *







|
|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Sept 23, 2012, Joe Mistachkin
 * Modified to use wide-character APIs.
 *
 * Sept 12, 2012, Jan Nijtmans
 * Switchable wide-character variant.
 *
 * Mar 15, 2011, Toni Ronkko
 * Defined FILE_ATTRIBUTE_DEVICE for MSVC 6.0.
 *
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <tchar.h>

/* Entries missing from MSVC 6.0 */
#if !defined(FILE_ATTRIBUTE_DEVICE)
# define FILE_ATTRIBUTE_DEVICE 0x40
#endif

/* File type and permission flags for stat() */







<







85
86
87
88
89
90
91

92
93
94
95
96
97
98
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>


/* Entries missing from MSVC 6.0 */
#if !defined(FILE_ATTRIBUTE_DEVICE)
# define FILE_ATTRIBUTE_DEVICE 0x40
#endif

/* File type and permission flags for stat() */
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
#define	S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
#define	S_ISREG(mode)  (((mode) & S_IFMT) == S_IFREG)
#define	S_ISLNK(mode)  (((mode) & S_IFMT) == S_IFLNK)
#define	S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
#define	S_ISCHR(mode)  (((mode) & S_IFMT) == S_IFCHR)
#define	S_ISBLK(mode)  (((mode) & S_IFMT) == S_IFBLK)

#if defined(UNICODE) || defined(DIRENT_UNICODE)
#  define dirent _wdirent
#  define opendir _wopendir
#  define readdir _wreaddir
#  define closedir _wclosedir
#  define rewinddir _wrewinddir
#  define DIR _WDIR
#endif

#ifdef __cplusplus
extern "C" {
#endif

typedef struct dirent
{
   TCHAR d_name[MAX_PATH + 1];                 /* File name */
   size_t d_namlen;                            /* Length of name without \0 */
   int d_type;                                 /* File type */
} dirent;


typedef struct DIR
{
   dirent           curentry;                  /* Current directory entry */
   WIN32_FIND_DATA  find_data;                 /* Private file data */
   int              cached;                    /* True if data is valid */
   HANDLE           search_handle;             /* Win32 search handle */
   TCHAR            patt[MAX_PATH + 3];        /* Initial directory name */
} DIR;


/* Forward declarations */
static DIR *opendir(const TCHAR *dirname);
static struct dirent *readdir(DIR *dirp);
static int closedir(DIR *dirp);
static void rewinddir(DIR* dirp);


/* Use the new safe string functions introduced in Visual Studio 2005 */
#if defined(_MSC_VER) && _MSC_VER >= 1400
# define DIRENT_STRNCPY(dest,src,size) _tcsncpy_s((dest),(size),(src),_TRUNCATE)
#else
# define DIRENT_STRNCPY(dest,src,size) _tcsncpy((dest),(src),(size))
#endif

/* Set errno variable */
#if defined(_MSC_VER)
#define DIRENT_SET_ERRNO(x) _set_errno (x)
#else
#define DIRENT_SET_ERRNO(x) (errno = (x))
#endif


/*****************************************************************************
 * Open directory stream DIRNAME for read and return a pointer to the
 * internal working area that is used to retrieve individual directory
 * entries.
 */
static DIR *opendir(const TCHAR *dirname)
{
   DIR *dirp;

   /* ensure that the resulting search pattern will be a valid file name */
   if (dirname == NULL) {
      DIRENT_SET_ERRNO (ENOENT);
      return NULL;
   }
   if (_tcslen (dirname) + 3 >= MAX_PATH) {
      DIRENT_SET_ERRNO (ENAMETOOLONG);
      return NULL;
   }

   /* construct new DIR structure */
   dirp = (DIR*) malloc (sizeof (struct DIR));
   if (dirp != NULL) {
      int error;

      /*
       * Convert relative directory name to an absolute one.  This
       * allows rewinddir() to function correctly when the current working
       * directory is changed between opendir() and rewinddir().
       */
      if (GetFullPathName (dirname, MAX_PATH, dirp->patt, NULL)) {
         TCHAR *p;

         /* append the search pattern "\\*\0" to the directory name */
         p = _tcschr (dirp->patt, '\0');
         if (dirp->patt < p  &&  *(p-1) != '\\'  &&  *(p-1) != ':') {
           *p++ = '\\';
         }
         *p++ = '*';
         *p = '\0';

         /* open directory stream and retrieve the first entry */
         dirp->search_handle = FindFirstFile (dirp->patt, &dirp->find_data);
         if (dirp->search_handle != INVALID_HANDLE_VALUE) {
            /* a directory entry is now waiting in memory */
            dirp->cached = 1;
            error = 0;
         } else {
            /* search pattern is not a directory name? */
            DIRENT_SET_ERRNO (ENOENT);







<
<
<
<
<
<
<
<
<






|








|


|




|







|

|















|








|














|
|


|







|







148
149
150
151
152
153
154









155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
#define	S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
#define	S_ISREG(mode)  (((mode) & S_IFMT) == S_IFREG)
#define	S_ISLNK(mode)  (((mode) & S_IFMT) == S_IFLNK)
#define	S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
#define	S_ISCHR(mode)  (((mode) & S_IFMT) == S_IFCHR)
#define	S_ISBLK(mode)  (((mode) & S_IFMT) == S_IFBLK)










#ifdef __cplusplus
extern "C" {
#endif

typedef struct dirent
{
   WCHAR d_name[MAX_PATH + 1];                 /* File name */
   size_t d_namlen;                            /* Length of name without \0 */
   int d_type;                                 /* File type */
} dirent;


typedef struct DIR
{
   dirent           curentry;                  /* Current directory entry */
   WIN32_FIND_DATAW find_data;                 /* Private file data */
   int              cached;                    /* True if data is valid */
   HANDLE           search_handle;             /* Win32 search handle */
   WCHAR            patt[MAX_PATH + 3];        /* Initial directory name */
} DIR;


/* Forward declarations */
static DIR *opendir(const WCHAR *dirname);
static struct dirent *readdir(DIR *dirp);
static int closedir(DIR *dirp);
static void rewinddir(DIR* dirp);


/* Use the new safe string functions introduced in Visual Studio 2005 */
#if defined(_MSC_VER) && _MSC_VER >= 1400
# define DIRENT_STRNCPY(dest,src,size) wcsncpy_s((dest),(size),(src),_TRUNCATE)
#else
# define DIRENT_STRNCPY(dest,src,size) wcsncpy((dest),(src),(size))
#endif

/* Set errno variable */
#if defined(_MSC_VER)
#define DIRENT_SET_ERRNO(x) _set_errno (x)
#else
#define DIRENT_SET_ERRNO(x) (errno = (x))
#endif


/*****************************************************************************
 * Open directory stream DIRNAME for read and return a pointer to the
 * internal working area that is used to retrieve individual directory
 * entries.
 */
static DIR *opendir(const WCHAR *dirname)
{
   DIR *dirp;

   /* ensure that the resulting search pattern will be a valid file name */
   if (dirname == NULL) {
      DIRENT_SET_ERRNO (ENOENT);
      return NULL;
   }
   if (wcslen (dirname) + 3 >= MAX_PATH) {
      DIRENT_SET_ERRNO (ENAMETOOLONG);
      return NULL;
   }

   /* construct new DIR structure */
   dirp = (DIR*) malloc (sizeof (struct DIR));
   if (dirp != NULL) {
      int error;

      /*
       * Convert relative directory name to an absolute one.  This
       * allows rewinddir() to function correctly when the current working
       * directory is changed between opendir() and rewinddir().
       */
      if (GetFullPathNameW (dirname, MAX_PATH, dirp->patt, NULL)) {
         WCHAR *p;

         /* append the search pattern "\\*\0" to the directory name */
         p = wcschr (dirp->patt, '\0');
         if (dirp->patt < p  &&  *(p-1) != '\\'  &&  *(p-1) != ':') {
           *p++ = '\\';
         }
         *p++ = '*';
         *p = '\0';

         /* open directory stream and retrieve the first entry */
         dirp->search_handle = FindFirstFileW (dirp->patt, &dirp->find_data);
         if (dirp->search_handle != INVALID_HANDLE_VALUE) {
            /* a directory entry is now waiting in memory */
            dirp->cached = 1;
            error = 0;
         } else {
            /* search pattern is not a directory name? */
            DIRENT_SET_ERRNO (ENOENT);
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
      /* a valid directory entry already in memory */
      dirp->cached = 0;
   } else {
      /* get the next directory entry from stream */
      if (dirp->search_handle == INVALID_HANDLE_VALUE) {
         return NULL;
      }
      if (FindNextFile (dirp->search_handle, &dirp->find_data) == FALSE) {
         /* the very last entry has been processed or an error occured */
         FindClose (dirp->search_handle);
         dirp->search_handle = INVALID_HANDLE_VALUE;
         return NULL;
      }
   }

   /* copy as a multibyte/unicode character string */
   DIRENT_STRNCPY ( dirp->curentry.d_name,
             dirp->find_data.cFileName,
             sizeof(dirp->curentry.d_name)/sizeof(TCHAR) );
   dirp->curentry.d_name[MAX_PATH] = '\0';

   /* compute the length of name */
   dirp->curentry.d_namlen = _tcslen (dirp->curentry.d_name);

   /* determine file type */
   attr = dirp->find_data.dwFileAttributes;
   if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
      dirp->curentry.d_type = DT_CHR;
   } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
      dirp->curentry.d_type = DT_DIR;







|














|







284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
      /* a valid directory entry already in memory */
      dirp->cached = 0;
   } else {
      /* get the next directory entry from stream */
      if (dirp->search_handle == INVALID_HANDLE_VALUE) {
         return NULL;
      }
      if (FindNextFileW (dirp->search_handle, &dirp->find_data) == FALSE) {
         /* the very last entry has been processed or an error occured */
         FindClose (dirp->search_handle);
         dirp->search_handle = INVALID_HANDLE_VALUE;
         return NULL;
      }
   }

   /* copy as a multibyte/unicode character string */
   DIRENT_STRNCPY ( dirp->curentry.d_name,
             dirp->find_data.cFileName,
             sizeof(dirp->curentry.d_name)/sizeof(TCHAR) );
   dirp->curentry.d_name[MAX_PATH] = '\0';

   /* compute the length of name */
   dirp->curentry.d_namlen = wcslen (dirp->curentry.d_name);

   /* determine file type */
   attr = dirp->find_data.dwFileAttributes;
   if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
      dirp->curentry.d_type = DT_CHR;
   } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
      dirp->curentry.d_type = DT_DIR;
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
   if (dirp != NULL) {
      /* release search handle */
      if (dirp->search_handle != INVALID_HANDLE_VALUE) {
         FindClose (dirp->search_handle);
      }

      /* open new search handle and retrieve the first entry */
      dirp->search_handle = FindFirstFile (dirp->patt, &dirp->find_data);
      if (dirp->search_handle != INVALID_HANDLE_VALUE) {
         /* a directory entry is now waiting in memory */
         dirp->cached = 1;
      } else {
         /* failed to re-open directory: no directory entry in memory */
         dirp->cached = 0;
      }
   }
}

#ifdef UNICODE
#  undef dirent
#  undef opendir
#  undef readdir
#  undef closedir
#  undef DIR
#endif

#ifdef __cplusplus
}
#endif
#endif /*DIRENT_H*/







|










<
<
<
<
<
<
<
<




354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371








372
373
374
375
   if (dirp != NULL) {
      /* release search handle */
      if (dirp->search_handle != INVALID_HANDLE_VALUE) {
         FindClose (dirp->search_handle);
      }

      /* open new search handle and retrieve the first entry */
      dirp->search_handle = FindFirstFileW (dirp->patt, &dirp->find_data);
      if (dirp->search_handle != INVALID_HANDLE_VALUE) {
         /* a directory entry is now waiting in memory */
         dirp->cached = 1;
      } else {
         /* failed to re-open directory: no directory entry in memory */
         dirp->cached = 0;
      }
   }
}









#ifdef __cplusplus
}
#endif
#endif /*DIRENT_H*/