mirror of
https://github.com/flatpak/flatpak.git
synced 2026-03-27 11:22:00 -04:00
Import directory iteration, errno handling, and shutil from libgsystem
This commit is contained in:
@@ -20,6 +20,14 @@ EXTRA_DIST += $(libglnx_srcpath)/README $(libglnx_srcpath)/COPYING
|
||||
libglnx_la_SOURCES = \
|
||||
$(libglnx_srcpath)/glnx-backport-autocleanups.h \
|
||||
$(libglnx_srcpath)/glnx-backport-autoptr.h \
|
||||
$(libglnx_srcpath)/glnx-local-alloc.h \
|
||||
$(libglnx_srcpath)/glnx-local-alloc.c \
|
||||
$(libglnx_srcpath)/glnx-errors.h \
|
||||
$(libglnx_srcpath)/glnx-errors.c \
|
||||
$(libglnx_srcpath)/glnx-dirfd.h \
|
||||
$(libglnx_srcpath)/glnx-dirfd.c \
|
||||
$(libglnx_srcpath)/glnx-shutil.h \
|
||||
$(libglnx_srcpath)/glnx-shutil.c \
|
||||
$(libglnx_srcpath)/libglnx.h \
|
||||
$(NULL)
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include <glnx-backport-autoptr.h>
|
||||
|
||||
#if !GLIB_CHECK_VERSION(2, 44, 0)
|
||||
#if !GLIB_CHECK_VERSION(2, 43, 3)
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GAsyncQueue, g_async_queue_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GBookmarkFile, g_bookmark_file_free)
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#if !GLIB_CHECK_VERSION(2, 44, 0)
|
||||
#if !GLIB_CHECK_VERSION(2, 43, 4)
|
||||
|
||||
#define _GLIB_AUTOPTR_FUNC_NAME(TypeName) glib_autoptr_cleanup_##TypeName
|
||||
#define _GLIB_AUTOPTR_TYPENAME(TypeName) TypeName##_autoptr
|
||||
@@ -127,6 +127,6 @@ static inline gpointer
|
||||
#define g_steal_pointer(pp) \
|
||||
(0 ? (*(pp)) : (g_steal_pointer) (pp))
|
||||
|
||||
#endif /* !GLIB_CHECK_VERSION(2, 44, 0) */
|
||||
#endif /* !GLIB_CHECK_VERSION(2, 43, 3) */
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
165
glnx-dirfd.c
Normal file
165
glnx-dirfd.c
Normal file
@@ -0,0 +1,165 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2014,2015 Colin Walters <walters@verbum.org>.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glnx-dirfd.h>
|
||||
#include <glnx-errors.h>
|
||||
#include <glnx-local-alloc.h>
|
||||
|
||||
/**
|
||||
* glnx_opendirat_with_errno:
|
||||
* @dfd: File descriptor for origin directory
|
||||
* @name: Pathname, relative to @dfd
|
||||
* @follow: Whether or not to follow symbolic links
|
||||
*
|
||||
* Use openat() to open a directory, using a standard set of flags.
|
||||
* This function sets errno.
|
||||
*/
|
||||
int
|
||||
glnx_opendirat_with_errno (int dfd,
|
||||
const char *path,
|
||||
gboolean follow)
|
||||
{
|
||||
int flags = O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY;
|
||||
if (!follow)
|
||||
flags |= O_NOFOLLOW;
|
||||
return openat (dfd, path, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* glnx_opendirat:
|
||||
* @dfd: File descriptor for origin directory
|
||||
* @path: Pathname, relative to @dfd
|
||||
* @follow: Whether or not to follow symbolic links
|
||||
* @error: Error
|
||||
*
|
||||
* Use openat() to open a directory, using a standard set of flags.
|
||||
*/
|
||||
gboolean
|
||||
glnx_opendirat (int dfd,
|
||||
const char *path,
|
||||
gboolean follow,
|
||||
int *out_fd,
|
||||
GError **error)
|
||||
{
|
||||
int ret = glnx_opendirat_with_errno (dfd, path, follow);
|
||||
if (ret == -1)
|
||||
{
|
||||
glnx_set_prefix_error_from_errno (error, "%s", "openat");
|
||||
return FALSE;
|
||||
}
|
||||
*out_fd = ret;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
struct GLnxRealDirfdIterator
|
||||
{
|
||||
gboolean initialized;
|
||||
int fd;
|
||||
DIR *d;
|
||||
};
|
||||
typedef struct GLnxRealDirfdIterator GLnxRealDirfdIterator;
|
||||
|
||||
gboolean
|
||||
glnx_dirfd_iterator_init_at (int dfd,
|
||||
const char *path,
|
||||
gboolean follow,
|
||||
GLnxDirFdIterator *dfd_iter,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
glnx_fd_close int fd = -1;
|
||||
|
||||
if (!glnx_opendirat (dfd, path, follow, &fd, error))
|
||||
goto out;
|
||||
|
||||
if (!glnx_dirfd_iterator_init_take_fd (fd, dfd_iter, error))
|
||||
goto out;
|
||||
fd = -1; /* Transfer ownership */
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
glnx_dirfd_iterator_init_take_fd (int dfd,
|
||||
GLnxDirFdIterator *dfd_iter,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GLnxRealDirfdIterator *real_dfd_iter = (GLnxRealDirfdIterator*) dfd_iter;
|
||||
DIR *d = NULL;
|
||||
|
||||
d = fdopendir (dfd);
|
||||
if (!d)
|
||||
{
|
||||
glnx_set_prefix_error_from_errno (error, "%s", "fdopendir");
|
||||
goto out;
|
||||
}
|
||||
|
||||
real_dfd_iter->fd = dfd;
|
||||
real_dfd_iter->d = d;
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
glnx_dirfd_iterator_next_dent (GLnxDirFdIterator *dfd_iter,
|
||||
struct dirent **out_dent,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GLnxRealDirfdIterator *real_dfd_iter = (GLnxRealDirfdIterator*) dfd_iter;
|
||||
|
||||
if (g_cancellable_set_error_if_cancelled (cancellable, error))
|
||||
goto out;
|
||||
|
||||
do
|
||||
{
|
||||
errno = 0;
|
||||
*out_dent = readdir (real_dfd_iter->d);
|
||||
if (*out_dent == NULL && errno != 0)
|
||||
{
|
||||
glnx_set_prefix_error_from_errno (error, "%s", "fdopendir");
|
||||
goto out;
|
||||
}
|
||||
} while (*out_dent &&
|
||||
(strcmp ((*out_dent)->d_name, ".") == 0 ||
|
||||
strcmp ((*out_dent)->d_name, "..") == 0));
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
glnx_dirfd_iterator_clear (GLnxDirFdIterator *dfd_iter)
|
||||
{
|
||||
GLnxRealDirfdIterator *real_dfd_iter = (GLnxRealDirfdIterator*) dfd_iter;
|
||||
/* fd is owned by dfd_iter */
|
||||
(void) closedir (real_dfd_iter->d);
|
||||
}
|
||||
60
glnx-dirfd.h
Normal file
60
glnx-dirfd.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2014,2015 Colin Walters <walters@verbum.org>.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glnx-backport-autoptr.h>
|
||||
#include <limits.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct GLnxDirFdIterator {
|
||||
gboolean initialized;
|
||||
int fd;
|
||||
gpointer padding_data[4];
|
||||
};
|
||||
|
||||
typedef struct GLnxDirFdIterator GLnxDirFdIterator;
|
||||
gboolean glnx_dirfd_iterator_init_at (int dfd, const char *path,
|
||||
gboolean follow,
|
||||
GLnxDirFdIterator *dfd_iter, GError **error);
|
||||
gboolean glnx_dirfd_iterator_init_take_fd (int dfd, GLnxDirFdIterator *dfd_iter, GError **error);
|
||||
gboolean glnx_dirfd_iterator_next_dent (GLnxDirFdIterator *dfd_iter,
|
||||
struct dirent **out_dent,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
void glnx_dirfd_iterator_clear (GLnxDirFdIterator *dfd_iter);
|
||||
|
||||
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GLnxDirFdIterator, glnx_dirfd_iterator_clear)
|
||||
|
||||
int glnx_opendirat_with_errno (int dfd,
|
||||
const char *path,
|
||||
gboolean follow);
|
||||
|
||||
gboolean glnx_opendirat (int dfd,
|
||||
const char *path,
|
||||
gboolean follow,
|
||||
int *out_fd,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
53
glnx-errors.c
Normal file
53
glnx-errors.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2014,2015 Colin Walters <walters@verbum.org>.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glnx-backport-autoptr.h>
|
||||
#include <glnx-errors.h>
|
||||
|
||||
void
|
||||
glnx_real_set_prefix_error_from_errno (GError **error,
|
||||
gint errsv,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
if (!error)
|
||||
return;
|
||||
else
|
||||
{
|
||||
GString *buf = g_string_new ("");
|
||||
va_list args;
|
||||
|
||||
va_start (args, format);
|
||||
g_string_append_vprintf (buf, format, args);
|
||||
va_end (args);
|
||||
|
||||
g_string_append (buf, ": ");
|
||||
g_string_append (buf, g_strerror (errsv));
|
||||
|
||||
g_set_error_literal (error,
|
||||
G_IO_ERROR,
|
||||
g_io_error_from_errno (errsv),
|
||||
buf->str);
|
||||
g_string_free (buf, TRUE);
|
||||
errno = errsv;
|
||||
}
|
||||
}
|
||||
49
glnx-errors.h
Normal file
49
glnx-errors.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2014,2015 Colin Walters <walters@verbum.org>.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glnx-backport-autoptr.h>
|
||||
#include <errno.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define glnx_set_error_from_errno(error) \
|
||||
do { \
|
||||
int errsv = errno; \
|
||||
g_set_error_literal (error, G_IO_ERROR, \
|
||||
g_io_error_from_errno (errsv), \
|
||||
g_strerror (errsv)); \
|
||||
errno = errsv; \
|
||||
} while (0);
|
||||
|
||||
#define glnx_set_prefix_error_from_errno(error, format, args...) \
|
||||
do { \
|
||||
int errsv = errno; \
|
||||
glnx_real_set_prefix_error_from_errno (error, errsv, format, args); \
|
||||
errno = errsv; \
|
||||
} while (0);
|
||||
|
||||
void glnx_real_set_prefix_error_from_errno (GError **error,
|
||||
gint errsv,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF (3,4);
|
||||
|
||||
G_END_DECLS
|
||||
188
glnx-shutil.c
Normal file
188
glnx-shutil.c
Normal file
@@ -0,0 +1,188 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2014,2015 Colin Walters <walters@verbum.org>.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glnx-shutil.h>
|
||||
#include <glnx-errors.h>
|
||||
#include <glnx-local-alloc.h>
|
||||
|
||||
static unsigned char
|
||||
struct_stat_to_dt (struct stat *stbuf)
|
||||
{
|
||||
if (S_ISDIR (stbuf->st_mode))
|
||||
return DT_DIR;
|
||||
if (S_ISREG (stbuf->st_mode))
|
||||
return DT_REG;
|
||||
if (S_ISCHR (stbuf->st_mode))
|
||||
return DT_CHR;
|
||||
if (S_ISBLK (stbuf->st_mode))
|
||||
return DT_BLK;
|
||||
if (S_ISFIFO (stbuf->st_mode))
|
||||
return DT_FIFO;
|
||||
if (S_ISLNK (stbuf->st_mode))
|
||||
return DT_LNK;
|
||||
if (S_ISSOCK (stbuf->st_mode))
|
||||
return DT_SOCK;
|
||||
return DT_UNKNOWN;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
glnx_shutil_rm_rf_children (GLnxDirFdIterator *dfd_iter,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
struct dirent *dent;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (!glnx_dirfd_iterator_next_dent (dfd_iter, &dent, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (dent == NULL)
|
||||
break;
|
||||
|
||||
if (dent->d_type == DT_UNKNOWN)
|
||||
{
|
||||
struct stat stbuf;
|
||||
if (fstatat (dfd_iter->fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW) == -1)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
continue;
|
||||
else
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
dent->d_type = struct_stat_to_dt (&stbuf);
|
||||
/* Assume unknown types are just treated like regular files */
|
||||
if (dent->d_type == DT_UNKNOWN)
|
||||
dent->d_type = DT_REG;
|
||||
}
|
||||
|
||||
if (dent->d_type == DT_DIR)
|
||||
{
|
||||
g_auto(GLnxDirFdIterator) child_dfd_iter = { 0, };
|
||||
|
||||
if (!glnx_dirfd_iterator_init_at (dfd_iter->fd, dent->d_name, FALSE,
|
||||
&child_dfd_iter, error))
|
||||
goto out;
|
||||
|
||||
if (!glnx_shutil_rm_rf_children (&child_dfd_iter, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (unlinkat (dfd_iter->fd, dent->d_name, AT_REMOVEDIR) == -1)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (unlinkat (dfd_iter->fd, dent->d_name, 0) == -1)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* glnx_shutil_rm_rf_at:
|
||||
* @dfd: A directory file descriptor, or -1 for current
|
||||
* @path: Path
|
||||
* @cancellable: Cancellable
|
||||
* @error: Error
|
||||
*
|
||||
* Recursively delete the filename referenced by the combination of
|
||||
* the directory fd @dfd and @path; it may be a file or directory. No
|
||||
* error is thrown if @path does not exist.
|
||||
*/
|
||||
gboolean
|
||||
glnx_shutil_rm_rf_at (int dfd,
|
||||
const char *path,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
glnx_fd_close int target_dfd = -1;
|
||||
g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
|
||||
|
||||
/* With O_NOFOLLOW first */
|
||||
target_dfd = openat (dfd, path,
|
||||
O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW);
|
||||
|
||||
if (target_dfd == -1)
|
||||
{
|
||||
int errsv = errno;
|
||||
if (errsv == ENOENT)
|
||||
{
|
||||
;
|
||||
}
|
||||
else if (errsv == ENOTDIR || errsv == ELOOP)
|
||||
{
|
||||
if (unlinkat (dfd, path, 0) != 0)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!glnx_dirfd_iterator_init_take_fd (target_dfd, &dfd_iter, error))
|
||||
goto out;
|
||||
target_dfd = -1;
|
||||
|
||||
if (!glnx_shutil_rm_rf_children (&dfd_iter, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (unlinkat (dfd, path, AT_REMOVEDIR) == -1)
|
||||
{
|
||||
int errsv = errno;
|
||||
if (errsv != ENOENT)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
33
glnx-shutil.h
Normal file
33
glnx-shutil.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2014,2015 Colin Walters <walters@verbum.org>.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glnx-dirfd.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean
|
||||
glnx_shutil_rm_rf_at (int dfd,
|
||||
const char *path,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
Reference in New Issue
Block a user