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



Reply via email to