Skip to content
Snippets Groups Projects
Commit 1ea9158c authored by Rebecca Turner's avatar Rebecca Turner
Browse files

glnx-fdio: try $TMPDIR if /var/tmp doesn't exist

`glnx_open_anonymous_tmpfile` attempts to create an fd in `/var/tmp`
regardless of the value of `$TMPDIR`.

This is _usually_ okay, but can fail in some contexts, such as in the
[NixOS][1] build environment, which doesn't have `/var` mapped at all.

To avoid failing in this case, if the inner call to
`glnx_open_anonymous_tmpfile_full` fails, we retrieve the value of
`$TMPDIR` and try calling `glnx_open_anonymous_tmpfile_full` again with
that directory instead.

In the fast path (i.e. where `/var/tmp` exists), functionality is
unchanged.

[1]: https://nixos.org/
parent 5ef78bb9
No related branches found
No related tags found
No related merge requests found
...@@ -303,8 +303,8 @@ glnx_open_anonymous_tmpfile_full (int flags, ...@@ -303,8 +303,8 @@ glnx_open_anonymous_tmpfile_full (int flags,
} }
/* A variant of `glnx_open_tmpfile_linkable_at()` which doesn't support linking. /* A variant of `glnx_open_tmpfile_linkable_at()` which doesn't support linking.
* Useful for true temporary storage. The fd will be allocated in /var/tmp to * Useful for true temporary storage. The fd will be allocated in `/var/tmp`
* ensure maximum storage space. * (or `$TMPDIR` if `/var/tmp` doesn't exist) to ensure maximum storage space.
* *
* If you need the file on a specific filesystem use glnx_open_anonymous_tmpfile_full() * If you need the file on a specific filesystem use glnx_open_anonymous_tmpfile_full()
* which lets you pass a directory. * which lets you pass a directory.
...@@ -314,7 +314,37 @@ glnx_open_anonymous_tmpfile (int flags, ...@@ -314,7 +314,37 @@ glnx_open_anonymous_tmpfile (int flags,
GLnxTmpfile *out_tmpf, GLnxTmpfile *out_tmpf,
GError **error) GError **error)
{ {
return glnx_open_anonymous_tmpfile_full (flags, "/var/tmp", out_tmpf, error); if (glnx_open_anonymous_tmpfile_full (flags, "/var/tmp", out_tmpf, error))
return TRUE;
else if ((*error)->code == G_IO_ERROR_NOT_FOUND)
{
/* If /var/tmp doesn't exist, such as in a NixOS build or
* other constrained systems, this will fail.
*
* Therefore, we try again using the directory in $TMPDIR if possible.
*/
const char *tmpdir = getenv("TMPDIR");
if (tmpdir == NULL)
return FALSE;
GError *tmp_error;
tmp_error = NULL;
if (!glnx_open_anonymous_tmpfile_full (flags, tmpdir,
out_tmpf, &tmp_error))
{
g_propagate_error (error, tmp_error);
return FALSE;
}
else
{
// Don't leave the error from the first call to
// glnx_open_anonymous_tmpfile_full in `error`.
g_clear_error(error);
return TRUE;
}
}
else
return FALSE;
} }
/* Use this after calling glnx_open_tmpfile_linkable_at() to give /* Use this after calling glnx_open_tmpfile_linkable_at() to give
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment