diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2011-01-17 18:40:15 +0000 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2011-01-25 13:18:15 +0000 |
commit | 96a6d143765ae571e29155346cd7ae954e77d89e (patch) | |
tree | 370ee30f1b132045da1896e9b290546e4b724aee | |
parent | a431ced6790c601bbc7a25160b33df3d5d0c852f (diff) |
Make _dbus_directory_get_next_file use readdir, not readdir_r
This isn't thread-safe or reentrant, but it turns out we don't need
either of those properties, and readdir_r is a real pain to use correctly,
particularly in the presence of FUSE filesystems that might implement
statfs() wrong.
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=8284
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=15922
Reviewed-by: Will Thompson <will.thompson@collabora.co.uk>
-rw-r--r-- | dbus/dbus-sysdeps-util-unix.c | 75 |
1 files changed, 10 insertions, 65 deletions
diff --git a/dbus/dbus-sysdeps-util-unix.c b/dbus/dbus-sysdeps-util-unix.c index 00705b36..6e092458 100644 --- a/dbus/dbus-sysdeps-util-unix.c +++ b/dbus/dbus-sysdeps-util-unix.c @@ -608,54 +608,14 @@ _dbus_directory_open (const DBusString *filename, return iter; } -/* Calculate the required buffer size (in bytes) for directory - * entries read from the given directory handle. Return -1 if this - * this cannot be done. - * - * If you use autoconf, include fpathconf and dirfd in your - * AC_CHECK_FUNCS list. Otherwise use some other method to detect - * and use them where available. - */ -static dbus_bool_t -dirent_buf_size(DIR * dirp, size_t *size) -{ - long name_max; -# if defined(HAVE_FPATHCONF) && defined(_PC_NAME_MAX) -# if defined(HAVE_DIRFD) - name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX); -# elif defined(HAVE_DDFD) - name_max = fpathconf(dirp->dd_fd, _PC_NAME_MAX); -# else - name_max = fpathconf(dirp->__dd_fd, _PC_NAME_MAX); -# endif /* HAVE_DIRFD */ - if (name_max == -1) -# if defined(NAME_MAX) - name_max = NAME_MAX; -# else - return FALSE; -# endif -# elif defined(MAXNAMELEN) - name_max = MAXNAMELEN; -# else -# if defined(NAME_MAX) - name_max = NAME_MAX; -# else -# error "buffer size for readdir_r cannot be determined" -# endif -# endif - if (size) - *size = (size_t)offsetof(struct dirent, d_name) + name_max + 1; - else - return FALSE; - - return TRUE; -} - /** * Get next file in the directory. Will not return "." or ".." on * UNIX. If an error occurs, the contents of "filename" are * undefined. The error is never set if the function succeeds. * + * This function is not re-entrant, and not necessarily thread-safe. + * Only use it for test code or single-threaded utilities. + * * @param iter the iterator * @param filename string to be set to the next file in the dir * @param error return location for error @@ -666,37 +626,24 @@ _dbus_directory_get_next_file (DBusDirIter *iter, DBusString *filename, DBusError *error) { - struct dirent *d, *ent; - size_t buf_size; + struct dirent *ent; int err; _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - if (!dirent_buf_size (iter->d, &buf_size)) - { - dbus_set_error (error, DBUS_ERROR_FAILED, - "Can't calculate buffer size when reading directory"); - return FALSE; - } - - d = (struct dirent *)dbus_malloc (buf_size); - if (!d) - { - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, - "No memory to read directory entry"); - return FALSE; - } again: - err = readdir_r (iter->d, d, &ent); - if (err || !ent) + errno = 0; + ent = readdir (iter->d); + + if (!ent) { + err = errno; + if (err != 0) dbus_set_error (error, _dbus_error_from_errno (err), "%s", _dbus_strerror (err)); - dbus_free (d); return FALSE; } else if (ent->d_name[0] == '.' && @@ -710,12 +657,10 @@ _dbus_directory_get_next_file (DBusDirIter *iter, { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, "No memory to read directory entry"); - dbus_free (d); return FALSE; } else { - dbus_free (d); return TRUE; } } |