/**
* Reads the next file name from an open directory.
*
- * @param dir The directory that is being read
+ * @param dir directory handle as returned by vlc_opendir()
+ * (must not be used by another thread concurrently)
*
- * @return a UTF-8 string of the directory entry. Use free() to release it.
+ * @return a UTF-8 string of the directory entry. The string is valid until
+ * the next call to vlc_readdir() or closedir() on the handle.
* If there are no more entries in the directory, NULL is returned.
* If an error occurs, errno is set and NULL is returned.
*/
char *vlc_readdir( DIR *dir )
{
- /* Beware that readdir_r() assumes <buf> is large enough to hold the result
- * dirent including the file name. A buffer overflow could occur otherwise.
- * In particular, pathconf() and _POSIX_NAME_MAX cannot be used here. */
- struct dirent *ent;
- char *path = NULL;
-
- long len = fpathconf (dirfd (dir), _PC_NAME_MAX);
- /* POSIX says there shall we room for NAME_MAX bytes at all times */
- if (len == -1 || len < NAME_MAX)
- len = NAME_MAX;
- len += sizeof (*ent) + 1 - sizeof (ent->d_name);
-
- struct dirent *buf = malloc (len);
- if (unlikely(buf == NULL))
- return NULL;
-
- int val = readdir_r (dir, buf, &ent);
- if (val != 0)
- errno = val;
- else if (ent != NULL)
- path = strdup (ent->d_name);
- free (buf);
- return path;
+ struct dirent *ent = readdir (dir);
+ return (ent != NULL) ? ent->d_name : NULL;
}
/**
*/
char *vlc_getcwd (void)
{
- /* Try $PWD */
- const char *pwd = getenv ("PWD");
- if (pwd != NULL)
- {
- struct stat s1, s2;
- /* Make sure $PWD is correct */
- if (stat (pwd, &s1) == 0 && stat (".", &s2) == 0
- && s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino)
- return strdup (pwd);
- }
-
- /* Otherwise iterate getcwd() until the buffer is big enough */
long path_max = pathconf (".", _PC_PATH_MAX);
size_t size = (path_max == -1 || path_max > 4096) ? 4096 : path_max;
int newfd;
#ifdef F_DUPFD_CLOEXEC
- newfd = fcntl (oldfd, F_DUPFD_CLOEXEC);
+ newfd = fcntl (oldfd, F_DUPFD_CLOEXEC, 0);
if (unlikely(newfd == -1 && errno == EINVAL))
#endif
{