From abdbeff397c2176b130367d6f0d47fdc160df30c Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 27 Jan 2019 22:03:14 +0100 Subject: [PATCH] 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'. --- ChangeLog | 11 ++++++ doc/posix-functions/tmpfile.texi | 3 ++ lib/tmpfile.c | 65 +++++++++++++++++++++++++++----- m4/tmpfile.m4 | 40 ++++++++++++++++---- modules/argv-iter-tests | 1 + modules/tmpfile | 1 + 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 + + 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 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 -/* This replacement is used only on native Windows platforms. */ +#include -#include -#include -#include -#include +#if defined _WIN32 && ! defined __CYGWIN__ +/* A native Windows platforms. */ -#include +# include +# include +# include +# include -#define WIN32_LEAN_AND_MEAN /* avoid including junk */ -#include +# include + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include + +#else + +# include + +#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 +#include +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] -- 2.39.5