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

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) {
                     48:                return NULL;
                     49:        }
                     50:        dp->offset = 0;
                     51:        dp->finished = 0;
                     52: 
                     53:        if ((handle = FindFirstFile(filespec, &(dp->fileinfo))) == INVALID_HANDLE_VALUE) {
                     54:                DWORD err = GetLastError();
                     55:                if (err == ERROR_NO_MORE_FILES || err == ERROR_FILE_NOT_FOUND) {
                     56:                        dp->finished = 1;
                     57:                } else {
                     58:                        free(dp);
                     59:                        free(filespec);
                     60:                        return NULL;
                     61:                }
                     62:        }
                     63:        dp->dir = strdup(resolved_path_buff);
                     64:        dp->handle = handle;
                     65:        free(filespec);
                     66: 
                     67:        return dp;
                     68: }
                     69: 
                     70: struct dirent *readdir(DIR *dp)
                     71: {
                     72:        if (!dp || dp->finished)
                     73:                return NULL;
                     74: 
                     75:        if (dp->offset != 0) {
                     76:                if (FindNextFile(dp->handle, &(dp->fileinfo)) == 0) {
                     77:                        dp->finished = 1;
                     78:                        return NULL;
                     79:                }
                     80:        }
                     81:        dp->offset++;
                     82: 
                     83:        strlcpy(dp->dent.d_name, dp->fileinfo.cFileName, _MAX_FNAME+1);
                     84:        dp->dent.d_ino = 1;
                     85:        dp->dent.d_reclen = strlen(dp->dent.d_name);
                     86:        dp->dent.d_off = dp->offset;
                     87: 
                     88:        return &(dp->dent);
                     89: }
                     90: 
                     91: int readdir_r(DIR *dp, struct dirent *entry, struct dirent **result)
                     92: {
                     93:        if (!dp || dp->finished) {
                     94:                *result = NULL;
                     95:                return 0;
                     96:        }
                     97: 
                     98:        if (dp->offset != 0) {
                     99:                if (FindNextFile(dp->handle, &(dp->fileinfo)) == 0) {
                    100:                        dp->finished = 1;
                    101:                        *result = NULL;
                    102:                        return 0;
                    103:                }
                    104:        }
                    105:        dp->offset++;
                    106: 
                    107:        strlcpy(dp->dent.d_name, dp->fileinfo.cFileName, _MAX_FNAME+1);
                    108:        dp->dent.d_ino = 1;
                    109:        dp->dent.d_reclen = strlen(dp->dent.d_name);
                    110:        dp->dent.d_off = dp->offset;
                    111: 
                    112:        memcpy(entry, &dp->dent, sizeof(*entry));
                    113: 
                    114:        *result = &dp->dent;
                    115: 
                    116:        return 0;
                    117: }
                    118: 
                    119: int closedir(DIR *dp)
                    120: {
                    121:        if (!dp)
                    122:                return 0;
                    123:        /* It is valid to scan an empty directory but we have an invalid
                    124:           handle in this case (no first file found). */
                    125:        if (dp->handle != INVALID_HANDLE_VALUE) {
                    126:                FindClose(dp->handle);
                    127:        }
                    128:        if (dp->dir)
                    129:                free(dp->dir);
                    130:        if (dp)
                    131:                free(dp);
                    132: 
                    133:        return 0;
                    134: }
                    135: 
                    136: int rewinddir(DIR *dp)
                    137: {
                    138:        /* Re-set to the beginning */
                    139:        char *filespec;
                    140:        HANDLE handle;
                    141:        int index;
                    142: 
                    143:        FindClose(dp->handle);
                    144: 
                    145:        dp->offset = 0;
                    146:        dp->finished = 0;
                    147: 
                    148:        filespec = (char *)malloc(strlen(dp->dir) + 2 + 1);
                    149:        if (filespec == NULL) {
                    150:                return -1;
                    151:        }
                    152: 
                    153:        strcpy(filespec, dp->dir);
                    154:        index = strlen(filespec) - 1;
                    155:        if (index >= 0 && (filespec[index] == '/' || 
                    156:           (filespec[index] == '\\' && (index == 0 || !IsDBCSLeadByte(filespec[index-1])))))
                    157:                filespec[index] = '\0';
                    158:        strcat(filespec, "/*");
                    159: 
                    160:        if ((handle = FindFirstFile(filespec, &(dp->fileinfo))) == INVALID_HANDLE_VALUE) {
                    161:                dp->finished = 1;
                    162:        }
                    163:        
                    164:        dp->handle = handle;
                    165:        free(filespec);
                    166: 
                    167:        return 0;
                    168: }

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