Use gs_dirfd_iterator for xdg_app_remove_dangling_symlinks

tingping/wmclass
Alexander Larsson 2015-01-12 16:44:47 +01:00
parent b8c29f18ae
commit 0d78d22adb
1 changed files with 37 additions and 42 deletions

View File

@ -216,53 +216,56 @@ remove_dangling_symlinks (int parent_fd,
GError **error) GError **error)
{ {
gboolean ret = FALSE; gboolean ret = FALSE;
int dfd = -1;
DIR *d = NULL;
struct dirent *dent; struct dirent *dent;
GSDirFdIterator iter;
if (name == NULL) if (!gs_dirfd_iterator_init_at (parent_fd, name, FALSE, &iter, error))
dfd = parent_fd; /* We take ownership of the passed fd and close it */ goto out;
else
while (TRUE)
{ {
if (!gs_file_open_dir_fd_at (parent_fd, name, gboolean is_dir = FALSE;
&dfd, gboolean is_link = FALSE;
cancellable, error))
if (!gs_dirfd_iterator_next_dent (&iter, &dent, cancellable, error))
goto out; goto out;
}
d = fdopendir (dfd); if (dent == NULL)
if (!d) break;
{
gs_set_error_from_errno (error, errno);
goto out;
}
while ((dent = readdir (d)) != NULL) if (dent->d_type == DT_DIR)
{ is_dir = TRUE;
const char *name = dent->d_name; else if (dent->d_type == DT_LNK)
struct stat child_stbuf; is_link = TRUE;
else if (dent->d_type == DT_UNKNOWN)
if (strcmp (name, ".") == 0 ||
strcmp (name, "..") == 0)
continue;
if (fstatat (dfd, name, &child_stbuf,
AT_SYMLINK_NOFOLLOW) != 0)
{ {
gs_set_error_from_errno (error, errno); struct stat stbuf;
goto out; if (fstatat (iter.fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW) == -1)
{
int errsv = errno;
if (errsv == ENOENT)
continue;
else
{
gs_set_error_from_errno (error, errsv);
goto out;
}
}
is_dir = S_ISDIR (stbuf.st_mode);
is_link = S_ISLNK (stbuf.st_mode);
} }
if (S_ISDIR (child_stbuf.st_mode)) if (is_dir)
{ {
if (!remove_dangling_symlinks (dfd, name, cancellable, error)) if (!remove_dangling_symlinks (iter.fd, dent->d_name, cancellable, error))
goto out; goto out;
} }
else if (S_ISLNK (child_stbuf.st_mode)) else if (is_link)
{ {
if (fstatat (dfd, name, &child_stbuf, 0) != 0 && errno == ENOENT) struct stat stbuf;
if (fstatat (iter.fd, dent->d_name, &stbuf, 0) != 0 && errno == ENOENT)
{ {
if (unlinkat (dfd, name, 0) != 0) if (unlinkat (iter.fd, dent->d_name, 0) != 0)
{ {
gs_set_error_from_errno (error, errno); gs_set_error_from_errno (error, errno);
goto out; goto out;
@ -273,10 +276,6 @@ remove_dangling_symlinks (int parent_fd,
ret = TRUE; ret = TRUE;
out: out:
if (d != NULL)
closedir (d); /* This closes dfd */
else if (dfd != -1)
close (dfd);
return ret; return ret;
} }
@ -287,13 +286,9 @@ xdg_app_remove_dangling_symlinks (GFile *dir,
GError **error) GError **error)
{ {
gboolean ret = FALSE; gboolean ret = FALSE;
int dfd = -1;
if (!gs_file_open_dir_fd (dir, &dfd, cancellable, error))
goto out;
/* The fd is closed by this call */ /* The fd is closed by this call */
if (!remove_dangling_symlinks (dfd, NULL, if (!remove_dangling_symlinks (AT_FDCWD, gs_file_get_path_cached (dir),
cancellable, error)) cancellable, error))
goto out; goto out;