diff options
author | Rebecca Turner <rbt@sent.as> | 2020-09-23 13:33:43 -0400 |
---|---|---|
committer | Rebecca Turner <rbt@sent.as> | 2020-09-23 13:33:43 -0400 |
commit | 1ea9158c24ab0c775c23403e853cc27bb0155d27 (patch) | |
tree | e6fea126406dbd076b6bc5013bb379310d33cb8d | |
parent | 5ef78bb9d968e5f589eba1de31dbae8f9909cd08 (diff) | |
download | libglnx-1ea9158c24ab0c775c23403e853cc27bb0155d27.tar.gz |
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/
-rw-r--r-- | glnx-fdio.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/glnx-fdio.c b/glnx-fdio.c index e537a9b..9cf595e 100644 --- a/glnx-fdio.c +++ b/glnx-fdio.c @@ -303,8 +303,8 @@ glnx_open_anonymous_tmpfile_full (int flags, } /* 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 - * ensure maximum storage space. + * Useful for true temporary storage. The fd will be allocated in `/var/tmp` + * (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() * which lets you pass a directory. @@ -314,7 +314,37 @@ glnx_open_anonymous_tmpfile (int flags, GLnxTmpfile *out_tmpf, 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 |