File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / win32 / readdir.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:48:06 2012 UTC (12 years, 4 months ago) by misho
Branches: php, MAIN
CVS tags: v5_4_3elwix, v5_4_29p0, v5_4_20p0, v5_4_20, v5_4_17p0, v5_4_17, v5_3_10, HEAD
php

    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>