Annotation of embedaddon/php/win32/readdir.c, revision 1.1.1.2

1.1       misho       1: #include <malloc.h>
                      2: #include <string.h>
                      3: #include <errno.h>
                      4: 
                      5: #include "php.h"
                      6: #include "readdir.h"
                      7: #include "TSRM.h"
                      8: /**********************************************************************
                      9:  * Implement dirent-style opendir/readdir/rewinddir/closedir on Win32
                     10:  *
                     11:  * Functions defined are opendir(), readdir(), rewinddir() and
                     12:  * closedir() with the same prototypes as the normal dirent.h
                     13:  * implementation.
                     14:  *
                     15:  * Does not implement telldir(), seekdir(), or scandir().  The dirent
                     16:  * struct is compatible with Unix, except that d_ino is always 1 and
                     17:  * d_off is made up as we go along.
                     18:  *
                     19:  * The DIR typedef is not compatible with Unix.
                     20:  **********************************************************************/
                     21: 
                     22: DIR *opendir(const char *dir)
                     23: {
                     24:        DIR *dp;
                     25:        char *filespec;
                     26:        HANDLE handle;
                     27:        int index;
                     28:        char resolved_path_buff[MAXPATHLEN];
                     29:        TSRMLS_FETCH();
                     30: 
                     31:        if (!VCWD_REALPATH(dir, resolved_path_buff)) {
                     32:                return NULL;
                     33:        }
                     34: 
                     35:        filespec = (char *)malloc(strlen(resolved_path_buff) + 2 + 1);
                     36:        if (filespec == NULL) {
                     37:                return NULL;
                     38:        }
                     39:        strcpy(filespec, resolved_path_buff);
                     40:        index = strlen(filespec) - 1;
                     41:        if (index >= 0 && (filespec[index] == '/' || 
                     42:           (filespec[index] == '\\' && (index == 0 || !IsDBCSLeadByte(filespec[index-1])))))
                     43:                filespec[index] = '\0';
                     44:        strcat(filespec, "\\*");
                     45: 
                     46:        dp = (DIR *) malloc(sizeof(DIR));
                     47:        if (dp == NULL) {
1.1.1.2 ! misho      48:                free(filespec);
1.1       misho      49:                return NULL;
                     50:        }
                     51:        dp->offset = 0;
                     52:        dp->finished = 0;
                     53: 
                     54:        if ((handle = FindFirstFile(filespec, &(dp->fileinfo))) == INVALID_HANDLE_VALUE) {
                     55:                DWORD err = GetLastError();
                     56:                if (err == ERROR_NO_MORE_FILES || err == ERROR_FILE_NOT_FOUND) {
                     57:                        dp->finished = 1;
                     58:                } else {
                     59:                        free(dp);
                     60:                        free(filespec);
                     61:                        return NULL;
                     62:                }
                     63:        }
                     64:        dp->dir = strdup(resolved_path_buff);
                     65:        dp->handle = handle;
                     66:        free(filespec);
                     67: 
                     68:        return dp;
                     69: }
                     70: 
                     71: struct dirent *readdir(DIR *dp)
                     72: {
                     73:        if (!dp || dp->finished)
                     74:                return NULL;
                     75: 
                     76:        if (dp->offset != 0) {
                     77:                if (FindNextFile(dp->handle, &(dp->fileinfo)) == 0) {
                     78:                        dp->finished = 1;
                     79:                        return NULL;
                     80:                }
                     81:        }
                     82:        dp->offset++;
                     83: 
                     84:        strlcpy(dp->dent.d_name, dp->fileinfo.cFileName, _MAX_FNAME+1);
                     85:        dp->dent.d_ino = 1;
                     86:        dp->dent.d_reclen = strlen(dp->dent.d_name);
                     87:        dp->dent.d_off = dp->offset;
                     88: 
                     89:        return &(dp->dent);
                     90: }
                     91: 
                     92: int readdir_r(DIR *dp, struct dirent *entry, struct dirent **result)
                     93: {
                     94:        if (!dp || dp->finished) {
                     95:                *result = NULL;
                     96:                return 0;
                     97:        }
                     98: 
                     99:        if (dp->offset != 0) {
                    100:                if (FindNextFile(dp->handle, &(dp->fileinfo)) == 0) {
                    101:                        dp->finished = 1;
                    102:                        *result = NULL;
                    103:                        return 0;
                    104:                }
                    105:        }
                    106:        dp->offset++;
                    107: 
                    108:        strlcpy(dp->dent.d_name, dp->fileinfo.cFileName, _MAX_FNAME+1);
                    109:        dp->dent.d_ino = 1;
                    110:        dp->dent.d_reclen = strlen(dp->dent.d_name);
                    111:        dp->dent.d_off = dp->offset;
                    112: 
                    113:        memcpy(entry, &dp->dent, sizeof(*entry));
                    114: 
                    115:        *result = &dp->dent;
                    116: 
                    117:        return 0;
                    118: }
                    119: 
                    120: int closedir(DIR *dp)
                    121: {
                    122:        if (!dp)
                    123:                return 0;
                    124:        /* It is valid to scan an empty directory but we have an invalid
                    125:           handle in this case (no first file found). */
                    126:        if (dp->handle != INVALID_HANDLE_VALUE) {
                    127:                FindClose(dp->handle);
                    128:        }
                    129:        if (dp->dir)
                    130:                free(dp->dir);
                    131:        if (dp)
                    132:                free(dp);
                    133: 
                    134:        return 0;
                    135: }
                    136: 
                    137: int rewinddir(DIR *dp)
                    138: {
                    139:        /* Re-set to the beginning */
                    140:        char *filespec;
                    141:        HANDLE handle;
                    142:        int index;
                    143: 
                    144:        FindClose(dp->handle);
                    145: 
                    146:        dp->offset = 0;
                    147:        dp->finished = 0;
                    148: 
                    149:        filespec = (char *)malloc(strlen(dp->dir) + 2 + 1);
                    150:        if (filespec == NULL) {
                    151:                return -1;
                    152:        }
                    153: 
                    154:        strcpy(filespec, dp->dir);
                    155:        index = strlen(filespec) - 1;
                    156:        if (index >= 0 && (filespec[index] == '/' || 
                    157:           (filespec[index] == '\\' && (index == 0 || !IsDBCSLeadByte(filespec[index-1])))))
                    158:                filespec[index] = '\0';
                    159:        strcat(filespec, "/*");
                    160: 
                    161:        if ((handle = FindFirstFile(filespec, &(dp->fileinfo))) == INVALID_HANDLE_VALUE) {
                    162:                dp->finished = 1;
                    163:        }
                    164:        
                    165:        dp->handle = handle;
                    166:        free(filespec);
                    167: 
                    168:        return 0;
                    169: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>