Commit f82bdd3a authored by John Palmieri's avatar John Palmieri

* dbus/dbus-sysdeps-util-unix.c (_dbus_directory_get_next_file):

  use threadsafe readdir_r instead of readdir
parent 642335f6
2006-09-13 John (J5) Palmieri <johnp@redhat.com>
* dbus/dbus-sysdeps-util-unix.c (_dbus_directory_get_next_file):
use threadsafe readdir_r instead of readdir
2006-09-13 John (J5) Palmieri <johnp@redhat.com>
* dbus-threads.c (dbus_threads_init_default): New method for
......
......@@ -489,7 +489,7 @@ fi
AC_CHECK_LIB(socket,socket)
AC_CHECK_LIB(nsl,gethostbyname)
AC_CHECK_FUNCS(vsnprintf vasprintf nanosleep usleep poll setenv unsetenv socketpair getgrouplist)
AC_CHECK_FUNCS(vsnprintf vasprintf nanosleep usleep poll setenv unsetenv socketpair getgrouplist fpathconf dirfd)
AC_CHECK_HEADERS(execinfo.h, [AC_CHECK_FUNCS(backtrace)])
......
......@@ -490,14 +490,47 @@ _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(HAVE_DIRFD) \
&& defined(_PC_NAME_MAX)
name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX);
if (name_max == -1)
# if defined(NAME_MAX)
name_max = NAME_MAX;
# else
return FALSE;
# endif
# 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.
*
* @todo 1.0 for thread safety, I think we have to use
* readdir_r(). (GLib has the same issue, should file a bug.)
*
* @param iter the iterator
* @param filename string to be set to the next file in the dir
* @param error return location for error
......@@ -508,19 +541,37 @@ _dbus_directory_get_next_file (DBusDirIter *iter,
DBusString *filename,
DBusError *error)
{
struct dirent *ent;
struct dirent *d, *ent;
size_t buf_size;
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:
errno = 0;
ent = readdir (iter->d);
if (ent == NULL)
err = readdir_r (iter->d, d, &ent);
if (err || !ent)
{
if (errno != 0)
if (err != 0)
dbus_set_error (error,
_dbus_error_from_errno (errno),
"%s", _dbus_strerror (errno));
_dbus_error_from_errno (err),
"%s", _dbus_strerror (err));
dbus_free (d);
return FALSE;
}
else if (ent->d_name[0] == '.' &&
......@@ -534,10 +585,14 @@ _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
return TRUE;
{
dbus_free (d);
return TRUE;
}
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment