forked from Mirrors/flatpak-builder
Use gs_dirfd_iterator for xdg_app_remove_dangling_symlinks
parent
b8c29f18ae
commit
0d78d22adb
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue