Discussion:
truncate: Fix compilation error on Android
Bruno Haible
2018-05-13 23:53:36 UTC
Permalink
Compiling a testdir for Android 4.3, I'm seeing this error:

In file included from test-truncate.c:21:0:
test-truncate.c:22:18: error: 'truncate' undeclared here (not in a function)
SIGNATURE_CHECK (truncate, int, (const char *, off_t));
^

The reason is that AC_SYS_LARGEFILE is in effect, and while later versions
of Android have a redirect from 'truncate' to a function 'truncate64' that
takes a 64-bit off_t, in Android 4.0 .. 4.4 this function does not
yet exist, and 'truncate' is accordingly not declared in <unistd.h>.


2018-05-13 Bruno Haible <***@clisp.org>

truncate: Fix compilation error on Android.
* m4/truncate.m4 (gl_FUNC_TRUNCATE): Test also whether 'truncate' is
declared. Set HAVE_DECL_TRUNCATE, not HAVE_TRUNCATE.
* lib/unistd.in.h (truncate): Test HAVE_DECL_TRUNCATE, not
HAVE_TRUNCATE.
* modules/truncate: Likewise.
* m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Initialize HAVE_DECL_TRUNCATE,
not HAVE_TRUNCATE.
* modules/unistd (Makefile.am): Substitute HAVE_DECL_TRUNCATE, not
HAVE_TRUNCATE.
* doc/posix-functions/truncate.texi: Mention the issue.

diff --git a/doc/posix-functions/truncate.texi b/doc/posix-functions/truncate.texi
index b443d31..8cbd940 100644
--- a/doc/posix-functions/truncate.texi
+++ b/doc/posix-functions/truncate.texi
@@ -10,7 +10,7 @@
@itemize
@item
This function is missing on some platforms:
-mingw, MSVC 14.
+mingw, MSVC 14, Android 4.4 with @code{AC_SYS_LARGEFILE} in effect.
@item
On platforms where @code{off_t} is a 32-bit type, this function is not
applicable to arbitrary lengths for files larger than 2 GB. The fix is to
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index 98a5abe..075cab3 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -1489,7 +1489,7 @@ _GL_FUNCDECL_RPL (truncate, int, (const char *filename, off_t length)
_GL_ARG_NONNULL ((1)));
_GL_CXXALIAS_RPL (truncate, int, (const char *filename, off_t length));
# else
-# if !@HAVE_TRUNCATE@
+# if !@HAVE_DECL_TRUNCATE@
_GL_FUNCDECL_SYS (truncate, int, (const char *filename, off_t length)
_GL_ARG_NONNULL ((1)));
# endif
diff --git a/m4/truncate.m4 b/m4/truncate.m4
index d46ff2b..87f0493 100644
--- a/m4/truncate.m4
+++ b/m4/truncate.m4
@@ -1,4 +1,4 @@
-# truncate.m4 serial 1 -*- Autoconf -*-
+# truncate.m4 serial 2 -*- Autoconf -*-
dnl Copyright (C) 2017-2018 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -8,7 +8,12 @@ AC_DEFUN([gl_FUNC_TRUNCATE],
[
AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
AC_CHECK_FUNCS_ONCE([truncate])
- if test $ac_cv_func_truncate = yes; then
+ dnl AC_CHECK_FUNC is not enough here, because when compiling for Android 4.4
+ dnl or older with _FILE_OFFSET_BITS=64, truncate() is not declared. There
+ dnl is a function 'truncate' in libc, but it is unsuitable, because it takes
+ dnl only a 32-bit offset argument.
+ AC_CHECK_DECL([truncate], , , [[#include <unistd.h>]])
+ if test $ac_cv_have_decl_truncate = yes; then
m4_ifdef([gl_LARGEFILE], [
AC_REQUIRE([AC_CANONICAL_HOST])
case "$host_os" in
@@ -25,7 +30,11 @@ AC_DEFUN([gl_FUNC_TRUNCATE],
:
])
else
- HAVE_TRUNCATE=0
+ HAVE_DECL_TRUNCATE=0
+ if test $ac_cv_func_truncate = yes; then
+ dnl Avoid a conflict with the 'truncate' in libc.
+ REPLACE_TRUNCATE=1
+ fi
fi
])

diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4
index 77110a9..159c48a 100644
--- a/m4/unistd_h.m4
+++ b/m4/unistd_h.m4
@@ -1,4 +1,4 @@
-# unistd_h.m4 serial 72
+# unistd_h.m4 serial 73
dnl Copyright (C) 2006-2018 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -140,7 +140,6 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
HAVE_SLEEP=1; AC_SUBST([HAVE_SLEEP])
HAVE_SYMLINK=1; AC_SUBST([HAVE_SYMLINK])
HAVE_SYMLINKAT=1; AC_SUBST([HAVE_SYMLINKAT])
- HAVE_TRUNCATE=1; AC_SUBST([HAVE_TRUNCATE])
HAVE_UNLINKAT=1; AC_SUBST([HAVE_UNLINKAT])
HAVE_USLEEP=1; AC_SUBST([HAVE_USLEEP])
HAVE_DECL_ENVIRON=1; AC_SUBST([HAVE_DECL_ENVIRON])
@@ -152,6 +151,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
HAVE_DECL_GETPAGESIZE=1; AC_SUBST([HAVE_DECL_GETPAGESIZE])
HAVE_DECL_GETUSERSHELL=1; AC_SUBST([HAVE_DECL_GETUSERSHELL])
HAVE_DECL_SETHOSTNAME=1; AC_SUBST([HAVE_DECL_SETHOSTNAME])
+ HAVE_DECL_TRUNCATE=1; AC_SUBST([HAVE_DECL_TRUNCATE])
HAVE_DECL_TTYNAME_R=1; AC_SUBST([HAVE_DECL_TTYNAME_R])
HAVE_OS_H=0; AC_SUBST([HAVE_OS_H])
HAVE_SYS_PARAM_H=0; AC_SUBST([HAVE_SYS_PARAM_H])
diff --git a/modules/truncate b/modules/truncate
index e141b1a..b6fb377 100644
--- a/modules/truncate
+++ b/modules/truncate
@@ -9,12 +9,12 @@ Depends-on:
unistd
sys_types
largefile
-open [test $HAVE_TRUNCATE = 0 || test $REPLACE_TRUNCATE = 1]
-ftruncate [test $HAVE_TRUNCATE = 0 || test $REPLACE_TRUNCATE = 1]
+open [test $HAVE_DECL_TRUNCATE = 0 || test $REPLACE_TRUNCATE = 1]
+ftruncate [test $HAVE_DECL_TRUNCATE = 0 || test $REPLACE_TRUNCATE = 1]

configure.ac:
gl_FUNC_TRUNCATE
-if test $HAVE_TRUNCATE = 0 || test $REPLACE_TRUNCATE = 1; then
+if test $HAVE_DECL_TRUNCATE = 0 || test $REPLACE_TRUNCATE = 1; then
AC_LIBOBJ([truncate])
gl_PREREQ_TRUNCATE
fi
diff --git a/modules/unistd b/modules/unistd
index 98b6f9e..25bf9fa 100644
--- a/modules/unistd
+++ b/modules/unistd
@@ -115,7 +115,6 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \
-e 's|@''HAVE_SYMLINK''@|$(HAVE_SYMLINK)|g' \
-e 's|@''HAVE_SYMLINKAT''@|$(HAVE_SYMLINKAT)|g' \
- -e 's|@''HAVE_TRUNCATE''@|$(HAVE_TRUNCATE)|g' \
-e 's|@''HAVE_UNLINKAT''@|$(HAVE_UNLINKAT)|g' \
-e 's|@''HAVE_USLEEP''@|$(HAVE_USLEEP)|g' \
-e 's|@''HAVE_DECL_ENVIRON''@|$(HAVE_DECL_ENVIRON)|g' \
@@ -127,6 +126,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's|@''HAVE_DECL_GETPAGESIZE''@|$(HAVE_DECL_GETPAGESIZE)|g' \
-e 's|@''HAVE_DECL_GETUSERSHELL''@|$(HAVE_DECL_GETUSERSHELL)|g' \
-e 's|@''HAVE_DECL_SETHOSTNAME''@|$(HAVE_DECL_SETHOSTNAME)|g' \
+ -e 's|@''HAVE_DECL_TRUNCATE''@|$(HAVE_DECL_TRUNCATE)|g' \
-e 's|@''HAVE_DECL_TTYNAME_R''@|$(HAVE_DECL_TTYNAME_R)|g' \
-e 's|@''HAVE_OS_H''@|$(HAVE_OS_H)|g' \
-e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \

Loading...