Skip to content
Snippets Groups Projects
Commit 0428fd87 authored by Colin Walters's avatar Colin Walters
Browse files

dirfd: Extend tmpdir API to support optional cleaning

We have a use case in libostree's staging dirs where we try to reuse
them across multiple ostree txns, but we want the fd-relative bits
here.

Extend the tmpdir API to make deletion optional. While here, also extend the API
to support checking for errors when deleting for projects like libostree that
want to do so consistently.

Also while here, add a change to set the fd to `-1` after clearing to be extra
defensive.
parent b59bb2be
No related branches found
No related tags found
No related merge requests found
...@@ -371,25 +371,62 @@ glnx_mkdtemp (const gchar *tmpl, ...@@ -371,25 +371,62 @@ glnx_mkdtemp (const gchar *tmpl,
out_tmpdir, error); out_tmpdir, error);
} }
/* Deallocate a tmpdir, closing the fd and (recursively) deleting the path. This static gboolean
* is normally called by default by the autocleanup attribute, but you can also _glnx_tmpdir_free (GLnxTmpDir *tmpd,
* invoke this directly. gboolean delete_dir,
*/ GCancellable *cancellable,
void GError **error)
glnx_tmpdir_clear (GLnxTmpDir *tmpd)
{ {
/* Support being passed NULL so we work nicely in a GPtrArray */ /* Support being passed NULL so we work nicely in a GPtrArray */
if (!tmpd) if (!(tmpd && tmpd->initialized))
return; return TRUE;
if (!tmpd->initialized)
return;
g_assert_cmpint (tmpd->fd, !=, -1); g_assert_cmpint (tmpd->fd, !=, -1);
(void) close (tmpd->fd); (void) close (tmpd->fd);
tmpd->fd = -1;
g_assert (tmpd->path); g_assert (tmpd->path);
g_assert_cmpint (tmpd->src_dfd, !=, -1); g_assert_cmpint (tmpd->src_dfd, !=, -1);
(void) glnx_shutil_rm_rf_at (tmpd->src_dfd, tmpd->path, NULL, NULL); g_autofree char *path = tmpd->path; /* Take ownership */
g_free (tmpd->path);
tmpd->initialized = FALSE; 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);
}
...@@ -119,8 +119,14 @@ typedef struct { ...@@ -119,8 +119,14 @@ typedef struct {
int fd; int fd;
char *path; char *path;
} GLnxTmpDir; } GLnxTmpDir;
void glnx_tmpdir_clear (GLnxTmpDir *tmpf); gboolean glnx_tmpdir_delete (GLnxTmpDir *tmpf, GCancellable *cancellable, GError **error);
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GLnxTmpDir, glnx_tmpdir_clear) 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, gboolean glnx_mkdtempat (int dfd, const char *tmpl, int mode,
GLnxTmpDir *out_tmpdir, GError **error); GLnxTmpDir *out_tmpdir, GError **error);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment