diff options
author | Sean Whitton <spwhitton@spwhitton.name> | 2021-07-21 11:51:04 -0700 |
---|---|---|
committer | Sean Whitton <spwhitton@spwhitton.name> | 2021-07-24 12:05:31 -0700 |
commit | 4501ebc220774ecd2f6263fd2819898bf6324c50 (patch) | |
tree | 8348d4b1ebb5614458d810c0b5ecabd91042379a /src/connection.lisp | |
parent | 05b39836da2c268920f76113155e6648ec6b99dd (diff) | |
download | consfigurator-4501ebc220774ecd2f6263fd2819898bf6324c50.tar.gz |
MKTEMP: use more complex shell command to avoid hiding stderr
This replaces two recent quick fixes:
58bcd1fa4a00c35492d6886c0f729974e7028136
350be6c791db8c943b284d8e53d768a1a2a1ee50
Thanks to Mark Wooding for help developing the technique used to detect
whether or not m4(1) outputted anything to stderr.
Signed-off-by: Sean Whitton <spwhitton@spwhitton.name>
Diffstat (limited to 'src/connection.lisp')
-rw-r--r-- | src/connection.lisp | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/src/connection.lisp b/src/connection.lisp index c2b235d..747cc2e 100644 --- a/src/connection.lisp +++ b/src/connection.lisp @@ -277,20 +277,44 @@ which will be cleaned up when BODY is finished." "tmp.XXXXXX" (ensure-directory-pathname directory))) "'${TMPDIR:-/tmp}'/tmp.XXXXXX"))) (multiple-value-bind (out exit) - ;; mktemp(1) is not POSIX; the only POSIX way is this M4 way, - ;; apparently, but even though m4(1) is POSIX it seems like it could - ;; often be absent, so have a fallback. It would be better to avoid - ;; passing any arguments to mktemp(1) as these may differ on different - ;; platforms, but hopefully just a template is okay. + ;; mktemp(1) is not POSIX; the only POSIX sh technique at the time of + ;; writing is to use m4(1)'s mkstemp macro. However, m4 is sometimes + ;; not present, so fall back to mktemp(1). Hopefully passing the + ;; template as the only command line option to mktemp(1) is portable. + ;; + ;; Although POSIX.1-2017 says that if m4(1) fails to create a + ;; temporary file it should exit nonzero, many m4(1) implementations + ;; just write to stderr and exit zero. So we examine the stderr, and + ;; if there is any, exit nonzero ourselves. ;; ;; While GNU M4 mkstemp makes the temporary file at most readable and ;; writeable by its owner, POSIX doesn't require this, so set a umask. (connection-run connection -#?"umask 077; echo 'mkstemp(${template})' 2>/dev/null | m4 2>/dev/null || mktemp '${template}'" + #?"umask 077 +if command -v m4 >/dev/null; then + if tmpf=\$(exec 3>&1 + if err=\$(echo 'mkstemp(${template})' | m4 2>&1 1>&3); then + case $err in + ?*) printf >&2 \"%s\\n\" \"$err\"; exit 1 ;; + *) exit 0 ;; + esac + else + case $err in + ?*) printf >&2 \"%s\\n\" \"$err\" ;; + esac + exit 1 + fi); then + echo $tmpf + else + exit 1; + fi +else + mktemp '${template}' +fi" nil) (let ((lines (lines out))) - (if (and (zerop exit) lines (plusp (length (car lines)))) + (if (and (zerop exit) lines) (car lines) (error 'run-failed :cmd "(attempt to make a temporary file on remote)" |