summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--doc/posix-functions/tmpfile.texi3
-rw-r--r--lib/tmpfile.c65
-rw-r--r--m4/tmpfile.m440
-rw-r--r--modules/argv-iter-tests1
-rw-r--r--modules/tmpfile1
6 files changed, 104 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 6134044422..64e0b27e94 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2019-01-27 Bruno Haible <bruno@clisp.org>
+
+ tmpfile: Add support for Android.
+ * m4/tmpfile.m4 (gl_FUNC_TMPFILE): Add a runtime test whether tmpfile()
+ works.
+ * lib/tmpfile.c (tmpfile): Add an alternative implementation for
+ Android.
+ * modules/tmpfile (Depends-on): Add 'stdbool'.
+ * doc/posix-functions/tmpfile.texi: Mention the Android bug.
+ * modules/argv-iter-tests (Depends-on): Add 'tmpfile'.
+
2019-01-27 Akim Demaille <akim@lrde.epita.fr>
bitsetv: allow free on NULL.
diff --git a/doc/posix-functions/tmpfile.texi b/doc/posix-functions/tmpfile.texi
index c5510aff53..2792458189 100644
--- a/doc/posix-functions/tmpfile.texi
+++ b/doc/posix-functions/tmpfile.texi
@@ -9,6 +9,9 @@ Gnulib module: tmpfile
Portability problems fixed by Gnulib:
@itemize
@item
+This function always fails on some platforms:
+Android 4.3.
+@item
This function often fails for trivial reasons on some platforms:
mingw, MSVC 14.
@item
diff --git a/lib/tmpfile.c b/lib/tmpfile.c
index 1a6cef7eff..45d652d725 100644
--- a/lib/tmpfile.c
+++ b/lib/tmpfile.c
@@ -21,24 +21,36 @@
/* Specification. */
#include <stdio.h>
-/* This replacement is used only on native Windows platforms. */
+#include <stdbool.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/stat.h>
+#if defined _WIN32 && ! defined __CYGWIN__
+/* A native Windows platforms. */
-#include <io.h>
+# include <errno.h>
+# include <fcntl.h>
+# include <string.h>
+# include <sys/stat.h>
-#define WIN32_LEAN_AND_MEAN /* avoid including junk */
-#include <windows.h>
+# include <io.h>
+
+# define WIN32_LEAN_AND_MEAN /* avoid including junk */
+# include <windows.h>
+
+#else
+
+# include <unistd.h>
+
+#endif
#include "pathmax.h"
#include "tempname.h"
#include "tmpdir.h"
/* PATH_MAX is guaranteed to be defined, because this replacement is only
- used on native Windows. */
+ used on native Windows and Android. */
+
+#if defined _WIN32 && ! defined __CYGWIN__
+/* A native Windows platforms. */
/* On Windows, opening a file with _O_TEMPORARY has the effect of passing
the FILE_FLAG_DELETE_ON_CLOSE flag to CreateFile(), which has the effect
@@ -130,3 +142,38 @@ tmpfile (void)
return NULL;
}
+
+#else
+
+FILE *
+tmpfile (void)
+{
+ char buf[PATH_MAX];
+ int fd;
+ FILE *fp;
+
+ /* Try $TMPDIR first, not /tmp nor P_tmpdir, because we need this replacement
+ on Android, and /tmp does not exist on Android. */
+
+ if (path_search (buf, sizeof buf, NULL, "tmpf", true))
+ return NULL;
+
+ fd = gen_tempname (buf, 0, 0, GT_FILE);
+ if (fd < 0)
+ return NULL;
+
+ /* Note that this relies on the Unix semantics that
+ a file is not really removed until it is closed. */
+ (void) unlink (buf);
+
+ if ((fp = fdopen (fd, "w+b")) == NULL)
+ {
+ int saved_errno = errno;
+ close (fd);
+ errno = saved_errno;
+ }
+
+ return fp;
+}
+
+#endif
diff --git a/m4/tmpfile.m4 b/m4/tmpfile.m4
index faef23ee22..e648d37986 100644
--- a/m4/tmpfile.m4
+++ b/m4/tmpfile.m4
@@ -1,4 +1,4 @@
-# tmpfile.m4 serial 3
+# tmpfile.m4 serial 4
# Copyright (C) 2007, 2009-2019 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -18,20 +18,44 @@
# directory, even though tmpfile wouldn't work in general. Instead,
# just test for a Windows platform (excluding Cygwin).
+# On Android 4.3, tmpfile() always returns NULL, even if TMPDIR is set
+# to a writable directory.
+
AC_DEFUN([gl_FUNC_TMPFILE], [
AC_REQUIRE([gl_STDIO_H_DEFAULTS])
- AC_CACHE_CHECK([whether tmpfile should be overridden],
- [gl_cv_func_tmpfile_unusable],
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether tmpfile works],
+ [gl_cv_func_tmpfile_works],
[AC_EGREP_CPP([choke me], [
#if defined _WIN32 && !defined __CYGWIN__
choke me
#endif
],
- [gl_cv_func_tmpfile_unusable=yes],
- [gl_cv_func_tmpfile_unusable=no])])
- if test $gl_cv_func_tmpfile_unusable = yes; then
- REPLACE_TMPFILE=1
- fi
+ [gl_cv_func_tmpfile_works=no],
+ [AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+#include <stdio.h>
+#include <stdlib.h>
+int
+main (void)
+{
+ return tmpfile () == NULL;
+}]])],
+ [gl_cv_func_tmpfile_works=yes],
+ [gl_cv_func_tmpfile_works=no],
+ [case "$host_os" in
+ # Guess no on Android.
+ linux*-android*) gl_cv_func_tmpfile_works="guessing no" ;;
+ # Guess yes otherwise.
+ *) gl_cv_func_tmpfile_works="guessing yes" ;;
+ esac
+ ])
+ ])
+ ])
+ case "$gl_cv_func_tmpfile_works" in
+ *yes) ;;
+ *) REPLACE_TMPFILE=1 ;;
+ esac
])
# Prerequisites of lib/tmpfile.c.
diff --git a/modules/argv-iter-tests b/modules/argv-iter-tests
index 92c5c82bc1..f32587e050 100644
--- a/modules/argv-iter-tests
+++ b/modules/argv-iter-tests
@@ -3,6 +3,7 @@ tests/test-argv-iter.c
tests/macros.h
Depends-on:
+tmpfile
configure.ac:
diff --git a/modules/tmpfile b/modules/tmpfile
index e98a8ee5ae..884f284f22 100644
--- a/modules/tmpfile
+++ b/modules/tmpfile
@@ -9,6 +9,7 @@ Depends-on:
stdio
largefile
pathmax [test $REPLACE_TMPFILE = 1]
+stdbool [test $REPLACE_TMPFILE = 1]
tempname [test $REPLACE_TMPFILE = 1]
tmpdir [test $REPLACE_TMPFILE = 1]