Add gsu_make_tempfile() and fix bug in gui module.
authorAndre Noll <maan@tuebingen.mpg.de>
Wed, 20 Jan 2016 09:54:35 +0000 (10:54 +0100)
committerAndre Noll <maan@tuebingen.mpg.de>
Fri, 4 Mar 2016 12:28:04 +0000 (13:28 +0100)
While mkstemp(3) is required by POSIX.1-2001, mktemp(1) is not in POSIX
and the various Unixes ship different and incompatible implementations
of this command line utility.

This commit adds the new public gsu_make_tempfile() helper to the
common part of gsu and changes the gui module to use it.

The mktemp invocation in the gui module was buggy because it ran
mktemp with a relative template (no slash). Hence the temporary file
was created in the current working directory. Of course this fails
if $CWD is not writable. The new public function gets this right.

common
gui

diff --git a/common b/common
index d418095..4e1d115 100644 (file)
--- a/common
+++ b/common
@@ -90,3 +90,35 @@ _gsu_setup()
        gsu_banner_txt="${gsu_banner_txt:-set \$gsu_banner_txt to customize this message}"
        _gsu_init_errors
 }
+
+# We'd love to use mktemp -t here, but on Linux -t is deprecated in favor of
+# --tempdir, which is not supported on *BSD. Hence we have to implement our own
+# logic for -t.
+#
+# The second parameter to this function is optional. It is ignored if the
+# template ($1) is an absolute path. Conversely, if the template is a relative
+# path and a second parameter is given, $2 is assumed to be the directory in
+# which the temporary file should be created.
+gsu_make_tempfile()
+{
+       local template="$1"
+       local dir
+
+       if [[ "${template:0:1}" != '/' ]]; then # relative path
+               if (($# > 1)); then
+                       dir="$2"
+               elif [[ -n "$TMPDIR" ]]; then
+                       dir="$TMPDIR"
+               else
+                       dir="/tmp"
+               fi
+               template="$dir/$template"
+       fi
+       result="$(mktemp "$template")"
+       if (($? != 0)); then
+               ret=-$E_GSU_MKTEMP
+               result="template: $template"
+               return
+       fi
+       ret=$GSU_SUCCESS
+}
diff --git a/gui b/gui
index fa3ae48..34f732e 100644 (file)
--- a/gui
+++ b/gui
@@ -80,15 +80,13 @@ gsu_textbox()
 # This is like gsu_textbox() but the text is passed as a string.
 gsu_msgbox()
 {
+       local tmp
+
        # Some versions of dialog segfault if the text is too long. Hence we
        # always use a temporary file.
-       local tmp="$(mktemp gsu_msgbox.XXXXXXXXXX)"
-
-       if (($? != 0)); then
-               ret=-$E_GSU_MKTEMP
-               result='temp file for textbox'
-               return
-       fi
+       gsu_make_tempfile 'gsu_msgbox.XXXXXXXXXX'
+       (($ret < 0)) && return
+       tmp="$result"
        trap "rm -f $tmp" EXIT
        echo "$1" > "$tmp"
        gsu_textbox "$tmp"