diff options
| -rw-r--r-- | Changes | 3 | ||||
| -rw-r--r-- | eio.c | 13 | 
2 files changed, 10 insertions, 6 deletions
| @@ -36,4 +36,5 @@ TODO: openbsd requires stdint.h for intptr_t - why posix?          - use _POSIX_MEMLOCK_RANGE for mlock.          - do not (errornously) overwrite CFLAGS in configure.ac.          - mknod used int3 for dev_t (ยง2 bit), not offs (64 bit). - +        - fix memory corruption in eio_readdirx for the flags +          combination EIO_READDIR_STAT_ORDER | EIO_READDIR_DIRS_FIRST. @@ -1062,8 +1062,10 @@ eio__sendfile (int ofd, int ifd, off_t offset, size_t count, etp_worker *self)  static signed char  eio_dent_cmp (const eio_dirent *a, const eio_dirent *b)  { -    return a->score - b->score ? a->score - b->score /* works because our signed char is always 0..100 */ -              : a->inode < b->inode ? -1 : a->inode > b->inode ? 1 : 0; +  return a->score - b->score ? a->score - b->score /* works because our signed char is always 0..100 */ +       : a->inode < b->inode ? -1 +       : a->inode > b->inode ?  1 +       :                        0;  }  #define EIO_DENT_CMP(i,op,j) eio_dent_cmp (&i, &j) op 0 @@ -1079,8 +1081,8 @@ eio_dent_radix_sort (eio_dirent *dents, int size, signed char score_bits, ino_t    assert (CHAR_BIT == 8);    assert (sizeof (eio_dirent) * 8 < 256); -  assert (offsetof (eio_dirent, inode)); /* we use 0 as sentinel */ -  assert (offsetof (eio_dirent, score)); /* we use 0 as sentinel */ +  assert (offsetof (eio_dirent, inode)); /* we use bit #0 as sentinel */ +  assert (offsetof (eio_dirent, score)); /* we use bit #0 as sentinel */    if (size <= EIO_SORT_FAST)      return; @@ -1245,6 +1247,7 @@ eio__scandir (eio_req *req, etp_worker *self)    X_LOCK (wrklock);    /* the corresponding closedir is in ETP_WORKER_CLEAR */    self->dirp = dirp = opendir (req->ptr1); +    req->flags |= EIO_FLAG_PTR1_FREE | EIO_FLAG_PTR2_FREE;    req->ptr1 = dents = flags ? malloc (dentalloc * sizeof (eio_dirent)) : 0;    req->ptr2 = names = malloc (namesalloc); @@ -1266,7 +1269,7 @@ eio__scandir (eio_req *req, etp_worker *self)              req->result = dentoffs;              if (flags & EIO_READDIR_STAT_ORDER) -              eio_dent_sort (dents, dentoffs, 0, inode_bits); /* sort by inode exclusively */ +              eio_dent_sort (dents, dentoffs, flags & EIO_READDIR_DIRS_FIRST ? 7 : 0, inode_bits);              else if (flags & EIO_READDIR_DIRS_FIRST)                if (flags & EIO_READDIR_FOUND_UNKNOWN)                  eio_dent_sort (dents, dentoffs, 7, inode_bits); /* sort by score and inode */ | 
