Add xdg_app_remove_dangling_symlinks helper

tingping/wmclass
Alexander Larsson 2015-01-09 12:18:54 +01:00
parent 0c28aab49a
commit 15642f471d
2 changed files with 97 additions and 0 deletions

View File

@ -242,3 +242,97 @@ xdg_app_overlay_symlink_tree (GFile *source,
out:
return ret;
}
static gboolean
remove_dangling_symlinks (int parent_fd,
const char *name,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
int dfd = -1;
DIR *d = NULL;
struct dirent *dent;
if (name == NULL)
dfd = parent_fd; /* We take ownership of the passed fd and close it */
else
{
if (!gs_file_open_dir_fd_at (parent_fd, name,
&dfd,
cancellable, error))
goto out;
}
d = fdopendir (dfd);
if (!d)
{
set_error_from_errno (error, errno);
goto out;
}
while ((dent = readdir (d)) != NULL)
{
const char *name = dent->d_name;
struct stat child_stbuf;
if (strcmp (name, ".") == 0 ||
strcmp (name, "..") == 0)
continue;
if (fstatat (dfd, name, &child_stbuf,
AT_SYMLINK_NOFOLLOW) != 0)
{
set_error_from_errno (error, errno);
goto out;
}
if (S_ISDIR (child_stbuf.st_mode))
{
if (!remove_dangling_symlinks (dfd, name, cancellable, error))
goto out;
}
else if (S_ISLNK (child_stbuf.st_mode))
{
if (fstatat (dfd, name, &child_stbuf, 0) != 0 && errno == ENOENT)
{
if (unlinkat (dfd, name, 0) != 0)
{
set_error_from_errno (error, errno);
goto out;
}
}
}
}
ret = TRUE;
out:
if (d != NULL)
closedir (d); /* This closes dfd */
else if (dfd != -1)
close (dfd);
return ret;
}
gboolean
xdg_app_remove_dangling_symlinks (GFile *dir,
GCancellable *cancellable,
GError **error)
{
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 */
if (!remove_dangling_symlinks (dfd, NULL,
cancellable, error))
goto out;
ret = TRUE;
out:
return ret;
}

View File

@ -23,5 +23,8 @@ gboolean xdg_app_overlay_symlink_tree (GFile *source,
const char *symlink_prefix,
GCancellable *cancellable,
GError **error);
gboolean xdg_app_remove_dangling_symlinks (GFile *dir,
GCancellable *cancellable,
GError **error);
#endif /* __XDG_APP_UTILS_H__ */