Update dirent.h win32 implementation
This commit is contained in:
		
							parent
							
								
									8655c4b007
								
							
						
					
					
						commit
						8a9d3e21f2
					
				
					 1 changed files with 392 additions and 198 deletions
				
			
		| 
						 | 
					@ -23,16 +23,19 @@
 | 
				
			||||||
 * OTHER DEALINGS IN THE SOFTWARE.
 | 
					 * OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 | 
					 * Version 1.13, Dec 12 2012, Toni Ronkko
 | 
				
			||||||
 | 
					 * Use traditional 8+3 file name if the name cannot be represented in the
 | 
				
			||||||
 | 
					 * default ANSI code page.  Now compiles again with MSVC 6.0.  Thanks to
 | 
				
			||||||
 | 
					 * Konstantin Khomoutov for testing.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * Version 1.12.1, Oct 1 2012, Toni Ronkko
 | 
					 * Version 1.12.1, Oct 1 2012, Toni Ronkko
 | 
				
			||||||
 * Bug fix: renamed wide-character DIR structure _wDIR to _WDIR (with
 | 
					 * Bug fix: renamed wide-character DIR structure _wDIR to _WDIR (with
 | 
				
			||||||
 * capital W) in order to maintain compatibility with MingW.
 | 
					 * capital W) in order to maintain compatibility with MingW.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Version 1.12, Sep 30 2012, Toni Ronkko
 | 
					 * Version 1.12, Sep 30 2012, Toni Ronkko
 | 
				
			||||||
 * Define PATH_MAX and NAME_MAX.
 | 
					 * Define PATH_MAX and NAME_MAX.  Added wide-character variants _wDIR, 
 | 
				
			||||||
 *
 | 
					 * _wdirent, _wopendir(), _wreaddir(), _wclosedir() and _wrewinddir().
 | 
				
			||||||
 * Added wide-character variants _wDIR, _wdirent, _wopendir(),
 | 
					 * Thanks to Edgar Buerkle and Jan Nijtmans for ideas and code.
 | 
				
			||||||
 * _wreaddir(), _wclosedir() and _wrewinddir().  Thanks to Edgar Buerkle
 | 
					 | 
				
			||||||
 * and Jan Nijtmans for ideas and code.
 | 
					 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Do not include windows.h.  This allows dirent.h to be integrated more
 | 
					 * Do not include windows.h.  This allows dirent.h to be integrated more
 | 
				
			||||||
 * easily into programs using winsock.  Thanks to Fernando Azaldegui.
 | 
					 * easily into programs using winsock.  Thanks to Fernando Azaldegui.
 | 
				
			||||||
| 
						 | 
					@ -90,44 +93,68 @@
 | 
				
			||||||
#define DIRENT_H
 | 
					#define DIRENT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
 | 
					#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
 | 
				
			||||||
#define _X86_
 | 
					#   define _X86_
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdarg.h>
 | 
					#include <stdarg.h>
 | 
				
			||||||
#include <windef.h>
 | 
					#include <windef.h>
 | 
				
			||||||
#include <winbase.h>
 | 
					#include <winbase.h>
 | 
				
			||||||
#include <wchar.h>
 | 
					#include <wchar.h>
 | 
				
			||||||
#include <winnls.h>
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <malloc.h>
 | 
				
			||||||
#include <sys/types.h>
 | 
					#include <sys/types.h>
 | 
				
			||||||
#include <sys/stat.h>
 | 
					#include <sys/stat.h>
 | 
				
			||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Windows 8 wide-character string functions */
 | 
					/* Indicates that d_type field is available in dirent structure */
 | 
				
			||||||
#if (_WIN32_WINNT >= 0x0602)
 | 
					#define _DIRENT_HAVE_D_TYPE
 | 
				
			||||||
#   include <stringapiset.h>
 | 
					
 | 
				
			||||||
#endif
 | 
					/* Indicates that d_namlen field is available in dirent structure */
 | 
				
			||||||
 | 
					#define _DIRENT_HAVE_D_NAMLEN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Entries missing from MSVC 6.0 */
 | 
					/* Entries missing from MSVC 6.0 */
 | 
				
			||||||
#if !defined(FILE_ATTRIBUTE_DEVICE)
 | 
					#if !defined(FILE_ATTRIBUTE_DEVICE)
 | 
				
			||||||
# define FILE_ATTRIBUTE_DEVICE 0x40
 | 
					#   define FILE_ATTRIBUTE_DEVICE 0x40
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* File type and permission flags for stat() */
 | 
					/* File type and permission flags for stat() */
 | 
				
			||||||
#if defined(_MSC_VER)  &&  !defined(S_IREAD)
 | 
					#if !defined(S_IFMT)
 | 
				
			||||||
#   define S_IFMT   _S_IFMT                     /* File type mask */
 | 
					#   define S_IFMT   _S_IFMT                     /* File type mask */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if !defined(S_IFDIR)
 | 
				
			||||||
#   define S_IFDIR  _S_IFDIR                    /* Directory */
 | 
					#   define S_IFDIR  _S_IFDIR                    /* Directory */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if !defined(S_IFCHR)
 | 
				
			||||||
#   define S_IFCHR  _S_IFCHR                    /* Character device */
 | 
					#   define S_IFCHR  _S_IFCHR                    /* Character device */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if !defined(S_IFFIFO)
 | 
				
			||||||
#   define S_IFFIFO _S_IFFIFO                   /* Pipe */
 | 
					#   define S_IFFIFO _S_IFFIFO                   /* Pipe */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if !defined(S_IFREG)
 | 
				
			||||||
#   define S_IFREG  _S_IFREG                    /* Regular file */
 | 
					#   define S_IFREG  _S_IFREG                    /* Regular file */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if !defined(S_IREAD)
 | 
				
			||||||
#   define S_IREAD  _S_IREAD                    /* Read permission */
 | 
					#   define S_IREAD  _S_IREAD                    /* Read permission */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if !defined(S_IWRITE)
 | 
				
			||||||
#   define S_IWRITE _S_IWRITE                   /* Write permission */
 | 
					#   define S_IWRITE _S_IWRITE                   /* Write permission */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if !defined(S_IEXEC)
 | 
				
			||||||
#   define S_IEXEC  _S_IEXEC                    /* Execute permission */
 | 
					#   define S_IEXEC  _S_IEXEC                    /* Execute permission */
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#define S_IFBLK   0                             /* Block device */
 | 
					#if !defined(S_IFIFO)
 | 
				
			||||||
#define S_IFLNK   0                             /* Link */
 | 
					#   define S_IFIFO _S_IFIFO                     /* Pipe */
 | 
				
			||||||
#define S_IFSOCK  0                             /* Socket */
 | 
					#endif
 | 
				
			||||||
 | 
					#if !defined(S_IFBLK)
 | 
				
			||||||
 | 
					#   define S_IFBLK   0                          /* Block device */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if !defined(S_IFLNK)
 | 
				
			||||||
 | 
					#   define S_IFLNK   0                          /* Link */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if !defined(S_IFSOCK)
 | 
				
			||||||
 | 
					#   define S_IFSOCK  0                          /* Socket */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(_MSC_VER)
 | 
					#if defined(_MSC_VER)
 | 
				
			||||||
#   define S_IRUSR  S_IREAD                     /* Read user */
 | 
					#   define S_IRUSR  S_IREAD                     /* Read user */
 | 
				
			||||||
| 
						 | 
					@ -141,14 +168,22 @@
 | 
				
			||||||
#   define S_IXOTH  0                           /* Execute others */
 | 
					#   define S_IXOTH  0                           /* Execute others */
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Indicates that d_type field is available in dirent structure */
 | 
					/* Maximum length of file name */
 | 
				
			||||||
#define _DIRENT_HAVE_D_TYPE
 | 
					#if !defined(PATH_MAX)
 | 
				
			||||||
 | 
					#   define PATH_MAX MAX_PATH
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if !defined(FILENAME_MAX)
 | 
				
			||||||
 | 
					#   define FILENAME_MAX MAX_PATH
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if !defined(NAME_MAX)
 | 
				
			||||||
 | 
					#   define NAME_MAX FILENAME_MAX
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* File type flags for d_type */
 | 
					/* File type flags for d_type */
 | 
				
			||||||
#define DT_UNKNOWN  0
 | 
					#define DT_UNKNOWN  0
 | 
				
			||||||
#define DT_REG      S_IFREG
 | 
					#define DT_REG      S_IFREG
 | 
				
			||||||
#define DT_DIR      S_IFDIR
 | 
					#define DT_DIR      S_IFDIR
 | 
				
			||||||
#define DT_FIFO     S_IFFIFO
 | 
					#define DT_FIFO     S_IFIFO
 | 
				
			||||||
#define DT_SOCK     S_IFSOCK
 | 
					#define DT_SOCK     S_IFSOCK
 | 
				
			||||||
#define DT_CHR      S_IFCHR
 | 
					#define DT_CHR      S_IFCHR
 | 
				
			||||||
#define DT_BLK      S_IFBLK
 | 
					#define DT_BLK      S_IFBLK
 | 
				
			||||||
| 
						 | 
					@ -163,7 +198,7 @@
 | 
				
			||||||
 * only defined for compatibility.  These macros should always return false
 | 
					 * only defined for compatibility.  These macros should always return false
 | 
				
			||||||
 * on Windows.
 | 
					 * on Windows.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define	S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO)
 | 
					#define	S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
 | 
				
			||||||
#define	S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
 | 
					#define	S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
 | 
				
			||||||
#define	S_ISREG(mode)  (((mode) & S_IFMT) == S_IFREG)
 | 
					#define	S_ISREG(mode)  (((mode) & S_IFMT) == S_IFREG)
 | 
				
			||||||
#define	S_ISLNK(mode)  (((mode) & S_IFMT) == S_IFLNK)
 | 
					#define	S_ISLNK(mode)  (((mode) & S_IFMT) == S_IFLNK)
 | 
				
			||||||
| 
						 | 
					@ -171,29 +206,19 @@
 | 
				
			||||||
#define	S_ISCHR(mode)  (((mode) & S_IFMT) == S_IFCHR)
 | 
					#define	S_ISCHR(mode)  (((mode) & S_IFMT) == S_IFCHR)
 | 
				
			||||||
#define	S_ISBLK(mode)  (((mode) & S_IFMT) == S_IFBLK)
 | 
					#define	S_ISBLK(mode)  (((mode) & S_IFMT) == S_IFBLK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* For compatiblity with Unix */
 | 
					/* Return the exact length of d_namlen without zero terminator */
 | 
				
			||||||
#if !defined(PATH_MAX)
 | 
					#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
 | 
				
			||||||
#   define PATH_MAX MAX_PATH
 | 
					
 | 
				
			||||||
#endif
 | 
					/* Return number of bytes needed to store d_namlen */
 | 
				
			||||||
#if !defined(FILENAME_MAX)
 | 
					#define _D_ALLOC_NAMLEN(p) (PATH_MAX + 1)
 | 
				
			||||||
#   define FILENAME_MAX MAX_PATH
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#if !defined(NAME_MAX)
 | 
					 | 
				
			||||||
#   define NAME_MAX FILENAME_MAX
 | 
					 | 
				
			||||||
#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
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
extern "C" {
 | 
					extern "C" {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Wide-character versions */
 | 
					
 | 
				
			||||||
 | 
					/* Wide-character version */
 | 
				
			||||||
struct _wdirent {
 | 
					struct _wdirent {
 | 
				
			||||||
    long d_ino;                                 /* Always zero */
 | 
					    long d_ino;                                 /* Always zero */
 | 
				
			||||||
    unsigned short d_reclen;                    /* Structure size */
 | 
					    unsigned short d_reclen;                    /* Structure size */
 | 
				
			||||||
| 
						 | 
					@ -205,7 +230,7 @@ typedef struct _wdirent _wdirent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct _WDIR {
 | 
					struct _WDIR {
 | 
				
			||||||
    struct _wdirent ent;                        /* Current directory entry */
 | 
					    struct _wdirent ent;                        /* Current directory entry */
 | 
				
			||||||
    WIN32_FIND_DATAW find_data;                 /* Private file data */
 | 
					    WIN32_FIND_DATAW data;                      /* Private file data */
 | 
				
			||||||
    int cached;                                 /* True if data is valid */
 | 
					    int cached;                                 /* True if data is valid */
 | 
				
			||||||
    HANDLE handle;                              /* Win32 search handle */
 | 
					    HANDLE handle;                              /* Win32 search handle */
 | 
				
			||||||
    wchar_t *patt;                              /* Initial directory name */
 | 
					    wchar_t *patt;                              /* Initial directory name */
 | 
				
			||||||
| 
						 | 
					@ -217,6 +242,7 @@ static struct _wdirent *_wreaddir (_WDIR *dirp);
 | 
				
			||||||
static int _wclosedir (_WDIR *dirp);
 | 
					static int _wclosedir (_WDIR *dirp);
 | 
				
			||||||
static void _wrewinddir (_WDIR* dirp);
 | 
					static void _wrewinddir (_WDIR* dirp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* For compatibility with Symbian */
 | 
					/* For compatibility with Symbian */
 | 
				
			||||||
#define wdirent _wdirent
 | 
					#define wdirent _wdirent
 | 
				
			||||||
#define WDIR _WDIR
 | 
					#define WDIR _WDIR
 | 
				
			||||||
| 
						 | 
					@ -248,6 +274,26 @@ static int closedir (DIR *dirp);
 | 
				
			||||||
static void rewinddir (DIR* dirp);
 | 
					static void rewinddir (DIR* dirp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Internal utility functions */
 | 
				
			||||||
 | 
					static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
 | 
				
			||||||
 | 
					static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dirent_mbstowcs_s(
 | 
				
			||||||
 | 
					    size_t *pReturnValue,
 | 
				
			||||||
 | 
					    wchar_t *wcstr,
 | 
				
			||||||
 | 
					    size_t sizeInWords,
 | 
				
			||||||
 | 
					    const char *mbstr,
 | 
				
			||||||
 | 
					    size_t count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dirent_wcstombs_s(
 | 
				
			||||||
 | 
					    size_t *pReturnValue,
 | 
				
			||||||
 | 
					    char *mbstr,
 | 
				
			||||||
 | 
					    size_t sizeInBytes,
 | 
				
			||||||
 | 
					    const wchar_t *wcstr,
 | 
				
			||||||
 | 
					    size_t count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void dirent_set_errno (int error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Open directory stream DIRNAME for read and return a pointer to the
 | 
					 * Open directory stream DIRNAME for read and return a pointer to the
 | 
				
			||||||
 * internal working area that is used to retrieve individual directory
 | 
					 * internal working area that is used to retrieve individual directory
 | 
				
			||||||
| 
						 | 
					@ -258,7 +304,13 @@ _wopendir(
 | 
				
			||||||
    const wchar_t *dirname)
 | 
					    const wchar_t *dirname)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _WDIR *dirp = NULL;
 | 
					    _WDIR *dirp = NULL;
 | 
				
			||||||
    int error = 0;
 | 
					    int error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Must have directory name */
 | 
				
			||||||
 | 
					    if (dirname == NULL  ||  dirname[0] == '\0') {
 | 
				
			||||||
 | 
					        dirent_set_errno (ENOENT);
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Allocate new _WDIR structure */
 | 
					    /* Allocate new _WDIR structure */
 | 
				
			||||||
    dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
 | 
					    dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
 | 
				
			||||||
| 
						 | 
					@ -268,17 +320,18 @@ _wopendir(
 | 
				
			||||||
        /* Reset _WDIR structure */
 | 
					        /* Reset _WDIR structure */
 | 
				
			||||||
        dirp->handle = INVALID_HANDLE_VALUE;
 | 
					        dirp->handle = INVALID_HANDLE_VALUE;
 | 
				
			||||||
        dirp->patt = NULL;
 | 
					        dirp->patt = NULL;
 | 
				
			||||||
 | 
					        dirp->cached = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Compute the length of full path plus zero terminator */
 | 
					        /* Compute the length of full path plus zero terminator */
 | 
				
			||||||
        n = GetFullPathNameW (dirname, 0, NULL, NULL);
 | 
					        n = GetFullPathNameW (dirname, 0, NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Allocate room for full path and search patterns */
 | 
					        /* Allocate room for absolute directory name and search pattern */
 | 
				
			||||||
        dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
 | 
					        dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
 | 
				
			||||||
        if (dirp->patt) {
 | 
					        if (dirp->patt) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /*
 | 
					            /*
 | 
				
			||||||
             * Convert relative directory name to an absolute one.  This
 | 
					             * Convert relative directory name to an absolute one.  This
 | 
				
			||||||
             * allows rewinddir() to function correctly when the current
 | 
					             * allows rewinddir() to function correctly even when current
 | 
				
			||||||
             * working directory is changed between opendir() and rewinddir().
 | 
					             * working directory is changed between opendir() and rewinddir().
 | 
				
			||||||
             */
 | 
					             */
 | 
				
			||||||
            n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
 | 
					            n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
 | 
				
			||||||
| 
						 | 
					@ -305,21 +358,18 @@ _wopendir(
 | 
				
			||||||
                *p = '\0';
 | 
					                *p = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                /* Open directory stream and retrieve the first entry */
 | 
					                /* Open directory stream and retrieve the first entry */
 | 
				
			||||||
                dirp->handle = FindFirstFileW (dirp->patt, &dirp->find_data);
 | 
					                if (dirent_first (dirp)) {
 | 
				
			||||||
                if (dirp->handle != INVALID_HANDLE_VALUE) {
 | 
					                    /* Directory stream opened successfully */
 | 
				
			||||||
 | 
					                    error = 0;
 | 
				
			||||||
                    /* Directory entry is now waiting in memory */
 | 
					 | 
				
			||||||
                    dirp->cached = 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    /* Search pattern is not a directory name? */
 | 
					                    /* Cannot retrieve first entry */
 | 
				
			||||||
                    DIRENT_SET_ERRNO (ENOENT);
 | 
					 | 
				
			||||||
                    error = 1;
 | 
					                    error = 1;
 | 
				
			||||||
 | 
					                    dirent_set_errno (ENOENT);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                /* Cannot convert directory name to wide character string */
 | 
					                /* Cannot retrieve full path name */
 | 
				
			||||||
                DIRENT_SET_ERRNO (ENOENT);
 | 
					                dirent_set_errno (ENOENT);
 | 
				
			||||||
                error = 1;
 | 
					                error = 1;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -352,66 +402,55 @@ static struct _wdirent*
 | 
				
			||||||
_wreaddir(
 | 
					_wreaddir(
 | 
				
			||||||
    _WDIR *dirp)
 | 
					    _WDIR *dirp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    DWORD attr;
 | 
					    WIN32_FIND_DATAW *datap;
 | 
				
			||||||
    errno_t error;
 | 
					    struct _wdirent *entp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Get next directory entry */
 | 
					    /* Read next directory entry */
 | 
				
			||||||
    if (dirp->cached != 0) {
 | 
					    datap = dirent_next (dirp);
 | 
				
			||||||
        /* A valid directory entry already in memory */
 | 
					    if (datap) {
 | 
				
			||||||
        dirp->cached = 0;
 | 
					        size_t n;
 | 
				
			||||||
    } else {
 | 
					        DWORD attr;
 | 
				
			||||||
        /* Get the next directory entry from stream */
 | 
					        
 | 
				
			||||||
        if (dirp->handle == INVALID_HANDLE_VALUE) {
 | 
					        /* Pointer to directory entry to return */
 | 
				
			||||||
            return NULL;
 | 
					        entp = &dirp->ent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* 
 | 
				
			||||||
 | 
					         * Copy file name as wide-character string.  If the file name is too
 | 
				
			||||||
 | 
					         * long to fit in to the destination buffer, then truncate file name
 | 
				
			||||||
 | 
					         * to PATH_MAX characters and zero-terminate the buffer.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        n = 0;
 | 
				
			||||||
 | 
					        while (n < PATH_MAX  &&  datap->cFileName[n] != 0) {
 | 
				
			||||||
 | 
					            entp->d_name[n] = datap->cFileName[n];
 | 
				
			||||||
 | 
					            n++;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (FindNextFileW (dirp->handle, &dirp->find_data) == FALSE) {
 | 
					        dirp->ent.d_name[n] = 0;
 | 
				
			||||||
            /* The very last entry has been processed or an error occured */
 | 
					 | 
				
			||||||
            FindClose (dirp->handle);
 | 
					 | 
				
			||||||
            dirp->handle = INVALID_HANDLE_VALUE;
 | 
					 | 
				
			||||||
            return NULL;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Copy file name as a wide-character string */
 | 
					        /* Length of file name excluding zero terminator */
 | 
				
			||||||
    error = wcsncpy_s(
 | 
					        entp->d_namlen = n;
 | 
				
			||||||
        dirp->ent.d_name,                       /* Destination string */
 | 
					 | 
				
			||||||
        PATH_MAX,                               /* Size of dest in words */
 | 
					 | 
				
			||||||
        dirp->find_data.cFileName,              /* Source string */
 | 
					 | 
				
			||||||
        PATH_MAX + 1);                          /* Max # of chars to copy */
 | 
					 | 
				
			||||||
    if (!error) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Compute the length of name */
 | 
					        /* File type */
 | 
				
			||||||
        dirp->ent.d_namlen = wcsnlen (dirp->ent.d_name, PATH_MAX);
 | 
					        attr = datap->dwFileAttributes;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* Determine file type */
 | 
					 | 
				
			||||||
        attr = dirp->find_data.dwFileAttributes;
 | 
					 | 
				
			||||||
        if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
 | 
					        if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
 | 
				
			||||||
            dirp->ent.d_type = DT_CHR;
 | 
					            entp->d_type = DT_CHR;
 | 
				
			||||||
        } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
 | 
					        } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
 | 
				
			||||||
            dirp->ent.d_type = DT_DIR;
 | 
					            entp->d_type = DT_DIR;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            dirp->ent.d_type = DT_REG;
 | 
					            entp->d_type = DT_REG;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Reset dummy fields */
 | 
					        /* Reset dummy fields */
 | 
				
			||||||
        dirp->ent.d_ino = 0;
 | 
					        entp->d_ino = 0;
 | 
				
			||||||
        dirp->ent.d_reclen = sizeof (dirp->ent);
 | 
					        entp->d_reclen = sizeof (struct _wdirent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* 
 | 
					        /* Last directory entry read */
 | 
				
			||||||
         * Cannot copy file name from find_data to ent.  Construct a
 | 
					        entp = NULL;
 | 
				
			||||||
         * dummy _wdirent structure to pass error to caller.
 | 
					
 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        dirp->ent.d_name[0] = '?';
 | 
					 | 
				
			||||||
        dirp->ent.d_name[1] = '\0';
 | 
					 | 
				
			||||||
        dirp->ent.d_namlen = 1;
 | 
					 | 
				
			||||||
        dirp->ent.d_type = DT_UNKNOWN;
 | 
					 | 
				
			||||||
        dirp->ent.d_ino = 0;
 | 
					 | 
				
			||||||
        dirp->ent.d_reclen = 0;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return &dirp->ent;
 | 
					    return entp;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -444,7 +483,7 @@ _wclosedir(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        /* Invalid directory stream */
 | 
					        /* Invalid directory stream */
 | 
				
			||||||
        DIRENT_SET_ERRNO (EBADF);
 | 
					        dirent_set_errno (EBADF);
 | 
				
			||||||
        ok = /*failure*/-1;
 | 
					        ok = /*failure*/-1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return ok;
 | 
					    return ok;
 | 
				
			||||||
| 
						 | 
					@ -458,24 +497,79 @@ static void
 | 
				
			||||||
_wrewinddir(
 | 
					_wrewinddir(
 | 
				
			||||||
    _WDIR* dirp)
 | 
					    _WDIR* dirp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (dirp != NULL) {
 | 
					    if (dirp) {
 | 
				
			||||||
        /* release search handle */
 | 
					        /* Release existing search handle */
 | 
				
			||||||
        if (dirp->handle != INVALID_HANDLE_VALUE) {
 | 
					        if (dirp->handle != INVALID_HANDLE_VALUE) {
 | 
				
			||||||
            FindClose (dirp->handle);
 | 
					            FindClose (dirp->handle);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Open new search handle and retrieve the first directory entry */
 | 
					        /* Open new search handle */
 | 
				
			||||||
        dirp->handle = FindFirstFileW (dirp->patt, &dirp->find_data);
 | 
					        dirent_first (dirp);
 | 
				
			||||||
        if (dirp->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;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Get first directory entry (internal) */
 | 
				
			||||||
 | 
					static WIN32_FIND_DATAW*
 | 
				
			||||||
 | 
					dirent_first(
 | 
				
			||||||
 | 
					    _WDIR *dirp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    WIN32_FIND_DATAW *datap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Open directory and retrieve the first entry */
 | 
				
			||||||
 | 
					    dirp->handle = FindFirstFileW (dirp->patt, &dirp->data);
 | 
				
			||||||
 | 
					    if (dirp->handle != INVALID_HANDLE_VALUE) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* a directory entry is now waiting in memory */
 | 
				
			||||||
 | 
					        datap = &dirp->data;
 | 
				
			||||||
 | 
					        dirp->cached = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Failed to re-open directory: no directory entry in memory */
 | 
				
			||||||
 | 
					        dirp->cached = 0;
 | 
				
			||||||
 | 
					        datap = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return datap;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Get next directory entry (internal) */
 | 
				
			||||||
 | 
					static WIN32_FIND_DATAW*
 | 
				
			||||||
 | 
					dirent_next(
 | 
				
			||||||
 | 
					    _WDIR *dirp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    WIN32_FIND_DATAW *p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Get next directory entry */
 | 
				
			||||||
 | 
					    if (dirp->cached != 0) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* A valid directory entry already in memory */
 | 
				
			||||||
 | 
					        p = &dirp->data;
 | 
				
			||||||
 | 
					        dirp->cached = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    } else if (dirp->handle != INVALID_HANDLE_VALUE) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Get the next directory entry from stream */
 | 
				
			||||||
 | 
					        if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
 | 
				
			||||||
 | 
					            /* Got a file */
 | 
				
			||||||
 | 
					            p = &dirp->data;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            /* The very last entry has been processed or an error occured */
 | 
				
			||||||
 | 
					            FindClose (dirp->handle);
 | 
				
			||||||
 | 
					            dirp->handle = INVALID_HANDLE_VALUE;
 | 
				
			||||||
 | 
					            p = NULL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* End of directory stream reached */
 | 
				
			||||||
 | 
					        p = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return p;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 
 | 
					/* 
 | 
				
			||||||
 * Open directory stream using plain old C-string.
 | 
					 * Open directory stream using plain old C-string.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -484,54 +578,30 @@ opendir(
 | 
				
			||||||
    const char *dirname) 
 | 
					    const char *dirname) 
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    struct DIR *dirp;
 | 
					    struct DIR *dirp;
 | 
				
			||||||
    errno_t error = 0;
 | 
					    int error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Must have directory name */
 | 
					    /* Must have directory name */
 | 
				
			||||||
    if (dirname == NULL) {
 | 
					    if (dirname == NULL  ||  dirname[0] == '\0') {
 | 
				
			||||||
        DIRENT_SET_ERRNO (ENOENT);
 | 
					        dirent_set_errno (ENOENT);
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Allocate memory for multi-byte string directory structures */
 | 
					    /* Allocate memory for DIR structure */
 | 
				
			||||||
    dirp = (DIR*) malloc (sizeof (struct DIR));
 | 
					    dirp = (DIR*) malloc (sizeof (struct DIR));
 | 
				
			||||||
    if (dirp) {
 | 
					    if (dirp) {
 | 
				
			||||||
        wchar_t wname[PATH_MAX + 1];
 | 
					        wchar_t wname[PATH_MAX + 1];
 | 
				
			||||||
        size_t n;
 | 
					        size_t n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* 
 | 
					        /* Convert directory name to wide-character string */
 | 
				
			||||||
         * Convert directory name to wide-character string.
 | 
					        error = dirent_mbstowcs_s(
 | 
				
			||||||
         *
 | 
					            &n, wname, PATH_MAX + 1, dirname, PATH_MAX);
 | 
				
			||||||
         * Be ware of the return schemantics of MultiByteToWideChar() --
 | 
					        if (!error) {
 | 
				
			||||||
         * the function basically returns the number of characters written to
 | 
					 | 
				
			||||||
         * output buffer or zero if the conversion fails.  However, the
 | 
					 | 
				
			||||||
         * function does not necessarily zero-terminate the output
 | 
					 | 
				
			||||||
         * buffer and may return 0xFFFD if the string contains invalid
 | 
					 | 
				
			||||||
         * characters!
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        n = MultiByteToWideChar(
 | 
					 | 
				
			||||||
                CP_ACP,                         /* Input code page */
 | 
					 | 
				
			||||||
                MB_PRECOMPOSED,                 /* Conversion flags */
 | 
					 | 
				
			||||||
                dirname,                        /* Input string */
 | 
					 | 
				
			||||||
                -1,                             /* Length of input string */
 | 
					 | 
				
			||||||
                wname,                          /* Output buffer */
 | 
					 | 
				
			||||||
                PATH_MAX);                      /* Size of output buffer */
 | 
					 | 
				
			||||||
        if (n > 0  &&  n < PATH_MAX) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* Zero-terminate output buffer */
 | 
					            /* Open directory stream using wide-character name */
 | 
				
			||||||
            wname[n] = '\0';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            /* Open directory stream with wide-character string file name */
 | 
					 | 
				
			||||||
            dirp->wdirp = _wopendir (wname);
 | 
					            dirp->wdirp = _wopendir (wname);
 | 
				
			||||||
            if (dirp->wdirp) {
 | 
					            if (dirp->wdirp) {
 | 
				
			||||||
 | 
					                /* Directory stream opened */
 | 
				
			||||||
                /* Initialize directory structure */
 | 
					                error = 0;
 | 
				
			||||||
                dirp->ent.d_name[0] = '\0';
 | 
					 | 
				
			||||||
                dirp->ent.d_namlen = 0;
 | 
					 | 
				
			||||||
                dirp->ent.d_type = 0;
 | 
					 | 
				
			||||||
                dirp->ent.d_ino = 0;
 | 
					 | 
				
			||||||
                dirp->ent.d_reclen = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                /* Failed to open directory stream */
 | 
					                /* Failed to open directory stream */
 | 
				
			||||||
                error = 1;
 | 
					                error = 1;
 | 
				
			||||||
| 
						 | 
					@ -564,91 +634,95 @@ opendir(
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Read next directory entry.
 | 
					 * Read next directory entry.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * When working with console, please note that file names returned by
 | 
					 * When working with text consoles, please note that file names returned by
 | 
				
			||||||
 * readdir() are represented in the default ANSI code page while the
 | 
					 * readdir() are represented in the default ANSI code page while any output to
 | 
				
			||||||
 * console typically runs on another code page.  Thus, non-ASCII characters
 | 
					 * console is typically formatted on another code page.  Thus, non-ASCII
 | 
				
			||||||
 * will not usually display correctly.  The problem can be fixed in two ways:
 | 
					 * characters in file names will not usually display correctly on console.  The
 | 
				
			||||||
 * (1) change the character set of console to 1252 using chcp utility and use
 | 
					 * problem can be fixed in two ways: (1) change the character set of console
 | 
				
			||||||
 * Lucida Console font, or (2) always use _cprintf function when writing to
 | 
					 * to 1252 using chcp utility and use Lucida Console font, or (2) use
 | 
				
			||||||
 * console.  The _cprinf() will re-encode ANSI strings to the console code
 | 
					 * _cprintf function when writing to console.  The _cprinf() will re-encode
 | 
				
			||||||
 * page so non-ASCII characters will display correcly.
 | 
					 * ANSI strings to the console code page so many non-ASCII characters will
 | 
				
			||||||
 | 
					 * display correcly.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static struct dirent*
 | 
					static struct dirent*
 | 
				
			||||||
readdir(
 | 
					readdir(
 | 
				
			||||||
    DIR *dirp) 
 | 
					    DIR *dirp) 
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    struct dirent *p;
 | 
					    WIN32_FIND_DATAW *datap;
 | 
				
			||||||
    struct _wdirent *wp;
 | 
					    struct dirent *entp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Read next directory entry using wide-character string functions */
 | 
					    /* Read next directory entry */
 | 
				
			||||||
    wp = _wreaddir (dirp->wdirp);
 | 
					    datap = dirent_next (dirp->wdirp);
 | 
				
			||||||
    if (wp) {
 | 
					    if (datap) {
 | 
				
			||||||
        size_t n;
 | 
					        size_t n;
 | 
				
			||||||
 | 
					        int error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Attempt to convert file name to multi-byte string */
 | 
				
			||||||
 | 
					        error = dirent_wcstombs_s(
 | 
				
			||||||
 | 
					            &n, dirp->ent.d_name, MAX_PATH + 1, datap->cFileName, MAX_PATH);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* 
 | 
					        /* 
 | 
				
			||||||
         * Convert file name to multi-byte string.
 | 
					         * If the file name cannot be represented by a multi-byte string,
 | 
				
			||||||
 | 
					         * then attempt to use old 8+3 file name.  This allows traditional
 | 
				
			||||||
 | 
					         * Unix-code to access some file names despite of unicode
 | 
				
			||||||
 | 
					         * characters, although file names may seem unfamiliar to the user.
 | 
				
			||||||
         *
 | 
					         *
 | 
				
			||||||
         * Be ware of the return schemantics of WideCharToMultiByte() --
 | 
					         * Be ware that the code below cannot come up with a short file
 | 
				
			||||||
         * the function basically returns the number of bytes
 | 
					         * name unless the file system provides one.  At least
 | 
				
			||||||
         * written to output buffer or zero if the conversion fails.
 | 
					         * VirtualBox shared folders fail to do this.
 | 
				
			||||||
         * However, the function does not necessarily zero-terminate the
 | 
					 | 
				
			||||||
         * buffer and it may even return 0xFFFD the string contains
 | 
					 | 
				
			||||||
         * invalid characters!
 | 
					 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        n = WideCharToMultiByte(
 | 
					        if (error  &&  datap->cAlternateFileName[0] != '\0') {
 | 
				
			||||||
                CP_ACP,                         /* Output code page */
 | 
					            error = dirent_wcstombs_s(
 | 
				
			||||||
                0,                              /* Conversion flags */
 | 
					                &n, dirp->ent.d_name, MAX_PATH + 1, datap->cAlternateFileName,
 | 
				
			||||||
                wp->d_name,                     /* Input string */
 | 
					                sizeof (datap->cAlternateFileName) / 
 | 
				
			||||||
                wp->d_namlen,                   /* Length of input string */
 | 
					                    sizeof (datap->cAlternateFileName[0]));
 | 
				
			||||||
                dirp->ent.d_name,               /* Output buffer */
 | 
					        }
 | 
				
			||||||
                PATH_MAX,                       /* Size of output buffer */
 | 
					 | 
				
			||||||
                NULL,                           /* Replacement character */
 | 
					 | 
				
			||||||
                NULL);                          /* If chars were replaced */
 | 
					 | 
				
			||||||
        if (n > 0  &&  n < PATH_MAX) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* Zero-terminate buffer */
 | 
					        if (!error) {
 | 
				
			||||||
            dirp->ent.d_name[n] = '\0';
 | 
					            DWORD attr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* Initialize directory entry for return */
 | 
					            /* Initialize directory entry for return */
 | 
				
			||||||
            p = &dirp->ent;
 | 
					            entp = &dirp->ent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* Compute length */
 | 
					            /* Length of file name excluding zero terminator */
 | 
				
			||||||
            p->d_namlen = strnlen (dirp->ent.d_name, PATH_MAX);
 | 
					            entp->d_namlen = n - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* Copy file attributes */
 | 
					            /* File attributes */
 | 
				
			||||||
            p->d_type = wp->d_type;
 | 
					            attr = datap->dwFileAttributes;
 | 
				
			||||||
 | 
					            if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
 | 
				
			||||||
 | 
					                entp->d_type = DT_CHR;
 | 
				
			||||||
 | 
					            } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
 | 
				
			||||||
 | 
					                entp->d_type = DT_DIR;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                entp->d_type = DT_REG;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* Reset dummy fields */
 | 
					            /* Reset dummy fields */
 | 
				
			||||||
            p->d_ino = 0;
 | 
					            entp->d_ino = 0;
 | 
				
			||||||
            p->d_reclen = sizeof (dirp->ent);
 | 
					            entp->d_reclen = sizeof (struct dirent);
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
 | 
					 | 
				
			||||||
            /* 
 | 
					            /* 
 | 
				
			||||||
             * Cannot convert file name to multi-byte string so construct
 | 
					             * Cannot convert file name to multi-byte string so construct
 | 
				
			||||||
             * an errornous directory entry and return that.  Note that
 | 
					             * an errornous directory entry and return that.  Note that
 | 
				
			||||||
             * we cannot return NULL as that would stop the processing
 | 
					             * we cannot return NULL as that would stop the processing
 | 
				
			||||||
             * of directory entries completely.
 | 
					             * of directory entries completely.
 | 
				
			||||||
             */
 | 
					             */
 | 
				
			||||||
            p = &dirp->ent;
 | 
					            entp = &dirp->ent;
 | 
				
			||||||
            p->d_name[0] = '?';
 | 
					            entp->d_name[0] = '?';
 | 
				
			||||||
            p->d_name[1] = '\0';
 | 
					            entp->d_name[1] = '\0';
 | 
				
			||||||
            p->d_namlen = 1;
 | 
					            entp->d_namlen = 1;
 | 
				
			||||||
            p->d_type = DT_UNKNOWN;
 | 
					            entp->d_type = DT_UNKNOWN;
 | 
				
			||||||
            p->d_ino = 0;
 | 
					            entp->d_ino = 0;
 | 
				
			||||||
            p->d_reclen = 0;
 | 
					            entp->d_reclen = 0;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
    
 | 
					        /* No more directory entries */
 | 
				
			||||||
        /* End of directory stream */
 | 
					        entp = NULL;
 | 
				
			||||||
        p = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return p;
 | 
					    return entp;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -669,9 +743,11 @@ closedir(
 | 
				
			||||||
        free (dirp);
 | 
					        free (dirp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Invalid directory stream */
 | 
					        /* Invalid directory stream */
 | 
				
			||||||
        DIRENT_SET_ERRNO (EBADF);
 | 
					        dirent_set_errno (EBADF);
 | 
				
			||||||
        ok = /*failure*/-1;
 | 
					        ok = /*failure*/-1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return ok;
 | 
					    return ok;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -687,6 +763,124 @@ rewinddir(
 | 
				
			||||||
    _wrewinddir (dirp->wdirp);
 | 
					    _wrewinddir (dirp->wdirp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Convert multi-byte string to wide character string */
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					dirent_mbstowcs_s(
 | 
				
			||||||
 | 
					    size_t *pReturnValue,
 | 
				
			||||||
 | 
					    wchar_t *wcstr,
 | 
				
			||||||
 | 
					    size_t sizeInWords,
 | 
				
			||||||
 | 
					    const char *mbstr,
 | 
				
			||||||
 | 
					    size_t count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(_MSC_VER)  &&  _MSC_VER >= 1400
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Microsoft Visual Studio 2005 or later */
 | 
				
			||||||
 | 
					    error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Older Visual Studio or non-Microsoft compiler */
 | 
				
			||||||
 | 
					    size_t n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Convert to wide-character string */
 | 
				
			||||||
 | 
					    n = mbstowcs (wcstr, mbstr, count);
 | 
				
			||||||
 | 
					    if (n < sizeInWords) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Zero-terminate output buffer */
 | 
				
			||||||
 | 
					        if (wcstr) {
 | 
				
			||||||
 | 
					            wcstr[n] = 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Length of resuting multi-byte string WITH zero terminator */
 | 
				
			||||||
 | 
					        if (pReturnValue) {
 | 
				
			||||||
 | 
					            *pReturnValue = n + 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Success */
 | 
				
			||||||
 | 
					        error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Could not convert string */
 | 
				
			||||||
 | 
					        error = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return error;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Convert wide-character string to multi-byte string */
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					dirent_wcstombs_s(
 | 
				
			||||||
 | 
					    size_t *pReturnValue,
 | 
				
			||||||
 | 
					    char *mbstr,
 | 
				
			||||||
 | 
					    size_t sizeInBytes,
 | 
				
			||||||
 | 
					    const wchar_t *wcstr,
 | 
				
			||||||
 | 
					    size_t count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(_MSC_VER)  &&  _MSC_VER >= 1400
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Microsoft Visual Studio 2005 or later */
 | 
				
			||||||
 | 
					    error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Older Visual Studio or non-Microsoft compiler */
 | 
				
			||||||
 | 
					    size_t n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Convert to multi-byte string */
 | 
				
			||||||
 | 
					    n = wcstombs (mbstr, wcstr, count);
 | 
				
			||||||
 | 
					    if (n < sizeInBytes) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Zero-terminate output buffer */
 | 
				
			||||||
 | 
					        if (mbstr) {
 | 
				
			||||||
 | 
					            mbstr[n] = '\0';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Lenght of resulting multi-bytes string WITH zero-terminator */
 | 
				
			||||||
 | 
					        if (pReturnValue) {
 | 
				
			||||||
 | 
					            *pReturnValue = n + 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Success */
 | 
				
			||||||
 | 
					        error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Cannot convert string */
 | 
				
			||||||
 | 
					        error = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return error;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Set errno variable */
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					dirent_set_errno(
 | 
				
			||||||
 | 
					    int error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined(_MSC_VER)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Microsoft Visual Studio */
 | 
				
			||||||
 | 
					    _set_errno (error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Non-Microsoft compiler */
 | 
				
			||||||
 | 
					    errno = error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue