Below I provide my version of readdir.c file
unified diff ============cut=========== --- readdir.c Tue Jan 28 04:51:26 2003 +++ readdir_new.c Tue Jun 15 13:35:43 2004 @@ -22,40 +22,80 @@ DIR *opendir(const char *dir) { DIR *dp; - char *filespec; + char *filespec, *tmp_ptr; long handle; - int index; - - filespec = malloc(strlen(dir) + 2 + 1); - strcpy(filespec, dir); - index = strlen(filespec) - 1; - if (index >= 0 && (filespec[index] == '/' || - (filespec[index] == '\\' && !IsDBCSLeadByte(filespec[index-1])))) - filespec[index] = '\0'; - strcat(filespec, "/*"); + size_t dir_len;
- dp = (DIR *) malloc(sizeof(DIR)); + /* skip trailing slashes in the [dir] */ + tmp_ptr = dir + strlen(dir) - 1; + while (tmp_ptr > dir && (*tmp_ptr == '/' || + *tmp_ptr == '\\' && !IsDBCSLeadByte(*(tmp_ptr - 1)))) { + tmp_ptr--; + } + if (tmp_ptr == dir && *tmp_ptr == '/') { + tmp_ptr--; + } + + /* create file specification [filespec] from the [dir] */ + dir_len = tmp_ptr - dir + 1; + filespec = (char *) emalloc(dir_len + 3); + if (filespec == NULL) { + /* out of memory */ + return NULL; + } + memcpy(filespec, dir, dir_len); + tmp_ptr = filespec + dir_len; + *tmp_ptr++ = '/'; + *tmp_ptr++ = '*'; + *tmp_ptr = '\0'; + + /* init DIR structure [dp] */ + dp = (DIR *) emalloc(sizeof(DIR)); + if (dp == NULL) { + /* out of memory */ + efree(filespec); + return NULL; + } dp->offset = 0; dp->finished = 0; - dp->dir = strdup(dir); + dp->dir = (char *) emalloc(dir_len + 2); + if (dp->dir == NULL) { + /* out of memory */ + efree(dp); + efree(filespec); + return NULL; + } + memcpy(dp->dir, filespec, dir_len + 1); + dp->dir[dir_len + 1] = '\0';
+ /* init dir handle */ if ((handle = _findfirst(filespec, &(dp->fileinfo))) < 0) { - if (errno == ENOENT) + if (errno == ENOENT) { + /* file specification could not be matched */ dp->finished = 1; - else + } else { + /* invalid filename specification (errno == EINVAL) */ + efree(dp->dir); + efree(dp); + efree(filespec); return NULL; } + } dp->handle = handle; - free(filespec); + efree(filespec);
return dp; }
struct dirent *readdir(DIR *dp) { - if (!dp || dp->finished) + size_t str_len; + + if (dp == NULL || dp->finished) { return NULL; + }
+ /* read the next dir entry */ if (dp->offset != 0) { if (_findnext(dp->handle, &(dp->fileinfo)) < 0) { dp->finished = 1; @@ -64,9 +104,13 @@ } dp->offset++;
- strlcpy(dp->dent.d_name, dp->fileinfo.name, _MAX_FNAME+1); + /* copy dir entry to struct [dp->dent] */ + str_len = strlen(dp->fileinfo.name); + str_len = str_len > _MAX_FNAME ? _MAX_FNAME : str_len; + memcpy(dp->dent.d_name, dp->fileinfo.name, str_len); + dp->dent.d_name[str_len] = '\0'; dp->dent.d_ino = 1; - dp->dent.d_reclen = strlen(dp->dent.d_name); + dp->dent.d_reclen = str_len; dp->dent.d_off = dp->offset;
return &(dp->dent); @@ -74,11 +118,14 @@
int readdir_r(DIR *dp, struct dirent *entry, struct dirent **result) { - if (!dp || dp->finished) { + size_t str_len; + + if (dp == NULL || dp->finished) { *result = NULL; return 0; }
+ /* read the next dir entry */ if (dp->offset != 0) { if (_findnext(dp->handle, &(dp->fileinfo)) < 0) { dp->finished = 1; @@ -88,11 +135,16 @@ } dp->offset++;
- strlcpy(dp->dent.d_name, dp->fileinfo.name, _MAX_FNAME+1); + /* copy dir entry to struct [dp->dent] */ + str_len = strlen(dp->fileinfo.name); + str_len = str_len > _MAX_FNAME ? _MAX_FNAME : str_len; + memcpy(dp->dent.d_name, dp->fileinfo.name, str_len); + dp->dent.d_name[str_len] = '\0'; dp->dent.d_ino = 1; - dp->dent.d_reclen = strlen(dp->dent.d_name); + dp->dent.d_reclen = str_len; dp->dent.d_off = dp->offset;
+ /* copy struct [dp->dent] to [entry] point */ memcpy(entry, &dp->dent, sizeof(*entry));
*result = &dp->dent; @@ -102,42 +154,61 @@
int closedir(DIR *dp) { - if (!dp) + if (dp == NULL) { return 0; + } + + /* close dir handle */ _findclose(dp->handle); - if (dp->dir) - free(dp->dir); - if (dp) - free(dp); + + /* free allocated memory */ + if (dp->dir != NULL) { + efree(dp->dir); + } + if (dp != NULL) { + efree(dp); + }
return 0; }
int rewinddir(DIR *dp) { - /* Re-set to the beginning */ char *filespec; long handle; - int index; + size_t dir_len; + + if (dp == NULL) { + /* invalid pointer */ + return -1; + } + + /* create file specification [filespec] */ + dir_len = strlen(dp->dir); + filespec = emalloc(dir_len + 3); + if (filespec == NULL) { + /* out of memory */ + return -2; + } + memcpy(filespec, dp->dir, dir_len); + filespec[dir_len++] = '/'; + filespec[dir_len++] = '*'; + filespec[dir_len] = '\0';
+ /* close old dir handle */ _findclose(dp->handle);
+ /* init dir handle */ dp->offset = 0; dp->finished = 0; - - filespec = malloc(strlen(dp->dir) + 2 + 1); - strcpy(filespec, dp->dir); - index = strlen(filespec) - 1; - if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\')) - filespec[index] = '\0'; - strcat(filespec, "/*"); - if ((handle = _findfirst(filespec, &(dp->fileinfo))) < 0) { - if (errno == ENOENT) + if (errno == ENOENT) { + /* file specification could not be matched */ dp->finished = 1; } + } dp->handle = handle; - free(filespec); + efree(filespec);
return 0; }
============cut===========
-- Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php