Fossil

Check-in [fb07d869]
Login

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

Overview
Comment:upgrade dirent.h to latest available version (1.11)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:fb07d8693efc99aad3e4a1f659850c4c071e7f71
User & Date: jan.nijtmans 2012-08-30 19:29:41
Context
2012-08-31
08:08
More consistancy in html generation: Use '"' where possible. check-in: 34fcb963 user: jan.nijtmans tags: trunk
2012-08-30
19:41
Attempt to support compiling with MinGW without MSYS. check-in: 773fa5e6 user: mistachkin tags: trunk
19:29
upgrade dirent.h to latest available version (1.11) check-in: fb07d869 user: jan.nijtmans tags: trunk
14:30
typos check-in: 7c0f4eca user: jan.nijtmans tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/file.c.

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
...
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#if defined(_WIN32) && (defined(__MSVCRT__) || defined(_MSC_VER))
# undef stat
# define stat _stati64
#endif
/*
** On Windows S_ISLNK always returns FALSE.
*/
#if defined(_WIN32)
# define S_ISLNK(x) (0)
#endif
static int fileStatValid = 0;
static struct stat fileStat;

/*
** Fill stat buf with information received from stat() or lstat().
................................................................................
**   - PERM_EXE if file is executable;
**   - PERM_LNK on Unix if file is symlink and allow-symlinks option is on;
**   - PERM_REG for all other cases (regular file, directory, fifo, etc).
*/
int file_wd_perm(const char *zFilename){
  if( getStat(zFilename, 1) ) return PERM_REG;
#if defined(_WIN32)
#  if defined(__DMC__) || defined(_MSC_VER)
#    define S_IXUSR  _S_IEXEC
#  endif
  if( S_ISREG(fileStat.st_mode) && ((S_IXUSR)&fileStat.st_mode)!=0 )
    return PERM_EXE;
  else
    return PERM_REG;
#else







|







 







|







47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
...
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#if defined(_WIN32) && (defined(__MSVCRT__) || defined(_MSC_VER))
# undef stat
# define stat _stati64
#endif
/*
** On Windows S_ISLNK always returns FALSE.
*/
#if !defined(S_ISLNK)
# define S_ISLNK(x) (0)
#endif
static int fileStatValid = 0;
static struct stat fileStat;

/*
** Fill stat buf with information received from stat() or lstat().
................................................................................
**   - PERM_EXE if file is executable;
**   - PERM_LNK on Unix if file is symlink and allow-symlinks option is on;
**   - PERM_REG for all other cases (regular file, directory, fifo, etc).
*/
int file_wd_perm(const char *zFilename){
  if( getStat(zFilename, 1) ) return PERM_REG;
#if defined(_WIN32)
#  ifndef S_IXUSR
#    define S_IXUSR  _S_IEXEC
#  endif
  if( S_ISREG(fileStat.st_mode) && ((S_IXUSR)&fileStat.st_mode)!=0 )
    return PERM_EXE;
  else
    return PERM_REG;
#else

Changes to win/include/dirent.h.

18
19
20
21
22
23
24






















25
26
27
28
29
30
31
..
54
55
56
57
58
59
60

61
62



63
64




65






























































66
67
68
69


70
71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90
91
92







93
94
95
96
97
98
99
100
101
102
103


104



105


106

107
108
109








110
111
112
113
114
115
116

117
118
119
120
121
122
123
124
125
126




127










128
129
130
131
132
133
134
135
136
137
138
139
140
...
142
143
144
145
146
147
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
 * 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.
 *






















 * Dec 15, 2009, John Cunningham
 * Added rewinddir member function
 *
 * Jan 18, 2008, Toni Ronkko
 * Using FindFirstFileA and WIN32_FIND_DATAA to avoid converting string
 * between multi-byte and unicode representations.  This makes the
 * code simpler and also allows the code to be compiled under MingW.  Thanks
................................................................................
 *
 * May 28 1998, Toni Ronkko
 * First version.
 *****************************************************************************/
#ifndef DIRENT_H
#define DIRENT_H


#include <windows.h>
#include <string.h>



#include <assert.h>




































































typedef struct _wdirent
{
   wchar_t d_name[MAX_PATH + 1]; /* current dir entry (unicode char string) */
   WIN32_FIND_DATAW data;     /* file attributes */


}  _wdirent;


typedef struct _WDIR
{
   _wdirent current;            /* Current directory entry */
   int    cached;             /* Indicates un-processed entry in memory */
   HANDLE search_handle;      /* File search handle */
   wchar_t   patt[MAX_PATH + 3]; /* search pattern (3 = pattern + "\\*\0") */

} _WDIR;


/* Forward declarations */
static _WDIR *_wopendir (const wchar_t *dirname);
static struct _wdirent *_wreaddir (_WDIR *dirp);
static int _wclosedir (_WDIR *dirp);


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







#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 _WDIR *_wopendir(const wchar_t *dirname)
{
   _WDIR *dirp;


   assert (dirname != NULL);



   assert (wcslen (dirname) < MAX_PATH);




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








      wchar_t *p;

      /* take directory name... */
      STRNCPY (dirp->patt, dirname, sizeof(dirp->patt));
      dirp->patt[MAX_PATH] = '\0';

      /* ... and append search pattern to it */

      p = wcschr (dirp->patt, '\0');
      if (dirp->patt < p  &&  *(p-1) != '\\'  &&  *(p-1) != ':') {
         *p++ = '\\';
      }
      *p++ = '*';
      *p = '\0';

      /* open stream and retrieve first file */
      dirp->search_handle = FindFirstFileW (dirp->patt, &dirp->current.data);
      if (dirp->search_handle == INVALID_HANDLE_VALUE) {




         /* invalid search pattern? */










         free (dirp);
         return NULL;
      }

      /* there is an un-processed directory entry in memory now */
      dirp->cached = 1;
   }

   return dirp;
}


/*****************************************************************************
................................................................................
 * containing the name of the entry in d_name field.  Individual directory
 * entries returned by this very function include regular files,
 * sub-directories, pseudo-directories "." and "..", but also volume labels,
 * hidden files and system files may be returned.
 */
static struct _wdirent *_wreaddir(_WDIR *dirp)
{
   assert (dirp != NULL);

   if (dirp->search_handle == INVALID_HANDLE_VALUE) {
      /* directory stream was opened/rewound incorrectly or ended normally */
      return NULL;
   }

   /* get next directory entry */
   if (dirp->cached != 0) {
      /* a valid directory entry already in memory */
      dirp->cached = 0;
   } else {
      /* read next directory entry from disk */



      if (FindNextFileW (dirp->search_handle, &dirp->current.data) == FALSE) {
         /* the very last file has been processed or an error occured */
         FindClose (dirp->search_handle);
         dirp->search_handle = INVALID_HANDLE_VALUE;
         return NULL;
      }
   }

   /* copy as a multibyte character string */
   STRNCPY ( dirp->current.d_name,
             dirp->current.data.cFileName,
             sizeof(dirp->current.d_name) );
   dirp->current.d_name[MAX_PATH] = '\0';













   return &dirp->current;
}


/*****************************************************************************
 * Close directory stream opened by opendir() function.  Close of the
 * directory stream invalidates the DIR structure as well as any previously
 * read directory entry.
 */
static int _wclosedir(_WDIR *dirp)
{
   assert (dirp != NULL);





   /* release search handle */
   if (dirp->search_handle != INVALID_HANDLE_VALUE) {
      FindClose (dirp->search_handle);
      dirp->search_handle = INVALID_HANDLE_VALUE;
   }

   /* release directory handle */
   free (dirp);
   return 0;
}





#endif /*DIRENT_H*/







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>


>
>
>
|

>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
<
>
>
|




|
|
|
|
>




|
|
|




|

|
>
>
>
>
>
>
>











>
>
|
>
>
>
|
>
>
|
>
|


>
>
>
>
>
>
>
>
|

<
<
<
<
<
>
|
|
|
|
|
|

|
|
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>

|

<
<
<







 







|
|
|
|








|
>
>
>
|
|






|
|
|
|
|

>
>
>
>
>
>
>
>
>
>
>
>
|










|
>
>
>
>







|




>
>
>
>

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
..
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
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
248
249
250
251
252
253
254
255
256
257



258
259
260
261
262
263
264
...
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
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
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
 * 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.
 *
 * Aug 30, 2012, Jan Nijtmans
 * Remove rewinddir() (not necessary for fossil)
 * Replace everything with its wide-character variant.
 *
 * Mar 15, 2011, Toni Ronkko
 * Defined FILE_ATTRIBUTE_DEVICE for MSVC 6.0.
 *
 * Aug 11, 2010, Toni Ronkko
 * Added d_type and d_namlen fields to dirent structure.  The former is
 * especially useful for determining whether directory entry represents a
 * file or a directory.  For more information, see
 * http://www.delorie.com/gnu/docs/glibc/libc_270.html
 *
 * Aug 11, 2010, Toni Ronkko
 * Improved conformance to the standards.  For example, errno is now set
 * properly on failure and assert() is never used.  Thanks to Peter Brockam
 * for suggestions.
 *
 * Aug 11, 2010, Toni Ronkko
 * Fixed a bug in rewinddir(): when using relative directory names, change
 * of working directory no longer causes rewinddir() to fail.
 *
 * Dec 15, 2009, John Cunningham
 * Added rewinddir member function
 *
 * Jan 18, 2008, Toni Ronkko
 * Using FindFirstFileA and WIN32_FIND_DATAA to avoid converting string
 * between multi-byte and unicode representations.  This makes the
 * code simpler and also allows the code to be compiled under MingW.  Thanks
................................................................................
 *
 * May 28 1998, Toni Ronkko
 * First version.
 *****************************************************************************/
#ifndef DIRENT_H
#define DIRENT_H

#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() */
#if defined(_MSC_VER)  &&  !defined(S_IREAD)
# define S_IFMT   _S_IFMT                      /* file type mask */
# define S_IFDIR  _S_IFDIR                     /* directory */
# define S_IFCHR  _S_IFCHR                     /* character device */
# define S_IFFIFO _S_IFFIFO                    /* pipe */
# define S_IFREG  _S_IFREG                     /* regular file */
# define S_IREAD  _S_IREAD                     /* read permission */
# define S_IWRITE _S_IWRITE                    /* write permission */
# define S_IEXEC  _S_IEXEC                     /* execute permission */
#endif
#define S_IFBLK   0                            /* block device */
#define S_IFLNK   0                            /* link */
#define S_IFSOCK  0                            /* socket */

#if defined(_MSC_VER)
# define S_IRUSR  S_IREAD                      /* read, user */
# define S_IWUSR  S_IWRITE                     /* write, user */
# define S_IXUSR  0                            /* execute, user */
# define S_IRGRP  0                            /* read, group */
# define S_IWGRP  0                            /* write, group */
# define S_IXGRP  0                            /* execute, group */
# define S_IROTH  0                            /* read, others */
# define S_IWOTH  0                            /* write, others */
# define S_IXOTH  0                            /* execute, others */
#endif

/* Indicates that d_type field is available in dirent structure */
#define _DIRENT_HAVE_D_TYPE

/* File type flags for d_type */
#define DT_UNKNOWN  0
#define DT_REG      S_IFREG
#define DT_DIR      S_IFDIR
#define DT_FIFO     S_IFFIFO
#define DT_SOCK     S_IFSOCK
#define DT_CHR      S_IFCHR
#define DT_BLK      S_IFBLK

/* Macros for converting between st_mode and d_type */
#define IFTODT(mode) ((mode) & S_IFMT)
#define DTTOIF(type) (type)

/*
 * File type macros.  Note that block devices, sockets and links cannot be
 * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
 * only defined for compatibility.  These macros should always return false
 * on Windows.
 */
#define	S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO)
#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 _wdirent
{
   wchar_t d_name[MAX_PATH + 1];               /* File name */

   size_t d_namlen;                            /* Length of name without \0 */
   int d_type;                                 /* File type */
} _wdirent;


typedef struct _WDIR
{
   _wdirent         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_t          patt[MAX_PATH + 3];        /* Initial directory name */
} _WDIR;


/* Forward declarations */
static _WDIR *_wopendir(const wchar_t *dirname);
static struct _wdirent *_wreaddir(_WDIR *dirp);
static int _wclosedir(_WDIR *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 _WDIR *_wopendir(const wchar_t *dirname)
{
   _WDIR *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 = (_WDIR*) malloc (sizeof (struct _WDIR));
   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_t *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);
            error = 1;
         }
      } else {
         /* buffer too small */
         DIRENT_SET_ERRNO (ENOMEM);
         error = 1;
      }

      if (error) {
         free (dirp);
         dirp = NULL;
      }



   }

   return dirp;
}


/*****************************************************************************
................................................................................
 * containing the name of the entry in d_name field.  Individual directory
 * entries returned by this very function include regular files,
 * sub-directories, pseudo-directories "." and "..", but also volume labels,
 * hidden files and system files may be returned.
 */
static struct _wdirent *_wreaddir(_WDIR *dirp)
{
   DWORD attr;
   if (dirp == NULL) {
      /* directory stream did not open */
      DIRENT_SET_ERRNO (EBADF);
      return NULL;
   }

   /* get next directory entry */
   if (dirp->cached != 0) {
      /* 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 unicode character string */
   DIRENT_STRNCPY ( dirp->curentry.d_name,
             dirp->find_data.cFileName,
             sizeof(dirp->curentry.d_name)/sizeof(dirp->curentry.d_name[0]) );
   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;
   } else {
      dirp->curentry.d_type = DT_REG;
   }
   return &dirp->curentry;
}


/*****************************************************************************
 * Close directory stream opened by opendir() function.  Close of the
 * directory stream invalidates the DIR structure as well as any previously
 * read directory entry.
 */
static int _wclosedir(_WDIR *dirp)
{
   if (dirp == NULL) {
      /* invalid directory stream */
      DIRENT_SET_ERRNO (EBADF);
      return -1;
   }

   /* release search handle */
   if (dirp->search_handle != INVALID_HANDLE_VALUE) {
      FindClose (dirp->search_handle);
      dirp->search_handle = INVALID_HANDLE_VALUE;
   }

   /* release directory structure */
   free (dirp);
   return 0;
}


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