diff --git a/glnx-dirfd.c b/glnx-dirfd.c index b745e280992ea1f8e788ad1573adf02e158f546a..cbc31f9f4cb1bc2be789dd113546234a6bf577e0 100644 --- a/glnx-dirfd.c +++ b/glnx-dirfd.c @@ -371,25 +371,62 @@ glnx_mkdtemp (const gchar *tmpl, out_tmpdir, error); } -/* Deallocate a tmpdir, closing the fd and (recursively) deleting the path. This - * is normally called by default by the autocleanup attribute, but you can also - * invoke this directly. - */ -void -glnx_tmpdir_clear (GLnxTmpDir *tmpd) +static gboolean +_glnx_tmpdir_free (GLnxTmpDir *tmpd, + gboolean delete_dir, + GCancellable *cancellable, + GError **error) { /* Support being passed NULL so we work nicely in a GPtrArray */ - if (!tmpd) - return; - if (!tmpd->initialized) - return; + if (!(tmpd && tmpd->initialized)) + return TRUE; g_assert_cmpint (tmpd->fd, !=, -1); (void) close (tmpd->fd); + tmpd->fd = -1; g_assert (tmpd->path); g_assert_cmpint (tmpd->src_dfd, !=, -1); - (void) glnx_shutil_rm_rf_at (tmpd->src_dfd, tmpd->path, NULL, NULL); - g_free (tmpd->path); + g_autofree char *path = tmpd->path; /* Take ownership */ tmpd->initialized = FALSE; + if (delete_dir) + { + if (!glnx_shutil_rm_rf_at (tmpd->src_dfd, path, cancellable, error)) + return FALSE; + } + return TRUE; } +/** + * glnx_tmpdir_delete: + * @tmpf: Temporary dir + * @cancellable: Cancellable + * @error: Error + * + * Deallocate a tmpdir, closing the fd and recursively deleting the path. This + * is normally called indirectly via glnx_tmpdir_cleanup() by the autocleanup + * attribute, but you can also invoke this directly. + * + * If an error occurs while deleting the filesystem path, @tmpf will still have + * been deallocated and should not be reused. + * + * See also `glnx_tmpdir_unset` to avoid deleting the path. + */ +gboolean +glnx_tmpdir_delete (GLnxTmpDir *tmpf, GCancellable *cancellable, GError **error) +{ + return _glnx_tmpdir_free (tmpf, TRUE, cancellable, error); +} +/** + * glnx_tmpdir_unset: + * @tmpf: Temporary dir + * @cancellable: Cancellable + * @error: Error + * + * Deallocate a tmpdir, but do not delete the filesystem path. See also + * `glnx_tmpdir_delete()`. + */ +void +glnx_tmpdir_unset (GLnxTmpDir *tmpf) +{ + (void) _glnx_tmpdir_free (tmpf, FALSE, NULL, NULL); +} diff --git a/glnx-dirfd.h b/glnx-dirfd.h index 5e362fab27e297cbd654cdcbebd5ccb3c5205b57..11d791e88ff9f8a6e69982c1786600ae451f97ab 100644 --- a/glnx-dirfd.h +++ b/glnx-dirfd.h @@ -119,8 +119,14 @@ typedef struct { int fd; char *path; } GLnxTmpDir; -void glnx_tmpdir_clear (GLnxTmpDir *tmpf); -G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GLnxTmpDir, glnx_tmpdir_clear) +gboolean glnx_tmpdir_delete (GLnxTmpDir *tmpf, GCancellable *cancellable, GError **error); +void glnx_tmpdir_unset (GLnxTmpDir *tmpf); +static inline void +glnx_tmpdir_cleanup (GLnxTmpDir *tmpf) +{ + (void)glnx_tmpdir_delete (tmpf, NULL, NULL); +} +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GLnxTmpDir, glnx_tmpdir_cleanup) gboolean glnx_mkdtempat (int dfd, const char *tmpl, int mode, GLnxTmpDir *out_tmpdir, GError **error);