]> Savannah Git Hosting - gnulib.git/commitdiff
mkfifoat: Fix crash on macOS 12.
authorBruno Haible <bruno@clisp.org>
Fri, 10 Feb 2023 19:15:08 +0000 (20:15 +0100)
committerBruno Haible <bruno@clisp.org>
Fri, 10 Feb 2023 19:15:08 +0000 (20:15 +0100)
* m4/gnulib-common.m4 (gl_PREPARE_CHECK_FUNCS_MACOS,
gl_CHECK_FUNCS_MACOS, gl_CHECK_FUNCS_ANDROID_MACOS): New macros.
* m4/mkfifoat.m4 (gl_FUNC_MKFIFOAT): Test for mknodat and mkfifoat using
gl_CHECK_FUNCS_ANDROID_MACOS instead of gl_CHECK_FUNCS_ANDROID.

ChangeLog
m4/gnulib-common.m4
m4/mkfifoat.m4

index 9d266165a90b78b44c8394a32305dacb0950497a..01ecf50b80e3e8e65d82c25917c18ee93a86276c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2023-02-10  Bruno Haible  <bruno@clisp.org>
+
+       mkfifoat: Fix crash on macOS 12.
+       * m4/gnulib-common.m4 (gl_PREPARE_CHECK_FUNCS_MACOS,
+       gl_CHECK_FUNCS_MACOS, gl_CHECK_FUNCS_ANDROID_MACOS): New macros.
+       * m4/mkfifoat.m4 (gl_FUNC_MKFIFOAT): Test for mknodat and mkfifoat using
+       gl_CHECK_FUNCS_ANDROID_MACOS instead of gl_CHECK_FUNCS_ANDROID.
+
 2023-02-10  ChuanGang Jiang  <jiangchuanganghw@outlook.com>  (tiny change)
 
        Fix typos like "the the" and "a a" in comments.
index 1e6748ed8c3895cd52ef10aef0a193ec23ae9e84..ff2ea3d4f66b6e6f203d32d98c3797b8efe69614 100644 (file)
@@ -1,4 +1,4 @@
-# gnulib-common.m4 serial 81
+# gnulib-common.m4 serial 82
 dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -1172,6 +1172,202 @@ AC_DEFUN([gl_CHECK_FUNCS_ANDROID],
   fi
 ])
 
+dnl Preparations for gl_CHECK_FUNCS_MACOS.
+AC_DEFUN([gl_PREPARE_CHECK_FUNCS_MACOS],
+[
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_REQUIRE([gl_COMPILER_CLANG])
+  AC_CACHE_CHECK([for compiler option needed when checking for future declarations],
+    [gl_cv_compiler_check_future_option],
+    [case "$host_os" in
+       dnl This is only needed on macOS.
+       darwin*)
+         if test $gl_cv_compiler_clang = yes; then
+           dnl Test whether the compiler supports the option
+           dnl '-Werror=unguarded-availability-new'.
+           save_ac_compile="$ac_compile"
+           ac_compile="$ac_compile -Werror=unguarded-availability-new"
+           AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],[[]])],
+             [gl_cv_compiler_check_future_option='-Werror=unguarded-availability-new'],
+             [gl_cv_compiler_check_future_option=none])
+           ac_compile="$save_ac_compile"
+         else
+           gl_cv_compiler_check_future_option=none
+         fi
+         ;;
+       *) gl_cv_compiler_check_future_option=none ;;
+     esac
+    ])
+])
+
+dnl gl_CHECK_FUNCS_MACOS([func], [[#include <foo.h>]])
+dnl is like AC_CHECK_FUNCS([func]), taking into account a portability problem
+dnl on macOS.
+dnl
+dnl When code is compiled on macOS, it is in the context of a certain minimum
+dnl macOS version, that can be set through the option '-mmacosx-version-min='.
+dnl In other words, you don't compile for a specific version of macOS. You
+dnl compile for all versions of macOS, onwards from the given version.
+dnl Thus, the question "does the OS have the function func" has three possible
+dnl answers:
+dnl   - yes, in all versions starting from the given version,
+dnl   - no, in no version,
+dnl   - not in the given version, but in a later version of macOS.
+dnl
+dnl In detail, this works as follows:
+dnl If func was added to, say, macOS version 13, then the libc has the
+dnl symbol func always, whereas the header file <foo.h> declares func
+dnl conditionally with a special availability attribute:
+dnl   ... func (...) __attribute__((availability(macos,introduced=13.0)));
+dnl Thus, when compiling with "clang mmacosx-version-min=13", there is no
+dnl warning about the use of func, and the resulting binary
+dnl   - runs fine on macOS 13,
+dnl   - aborts with a dyld "Symbol not found" message on macOS 12.
+dnl Whereas, when compiling with "clang mmacosx-version-min=12", there is a
+dnl   warning: 'func' is only available on macOS 13.0 or newer
+dnl   [-Wunguarded-availability-new],
+dnl and the resulting binary
+dnl   - runs fine on macOS 13,
+dnl   - crashes with a SIGSEGV (signal 11) on macOS 12.
+dnl
+dnl This macro sets two variables:
+dnl   - gl_cv_onwards_func_<func>   to yes / no / "future OS version"
+dnl   - ac_cv_func_<func>           to yes / no / no
+dnl The first variable allows to distinguish all three cases.
+dnl The second variable is set, so that an invocation
+dnl   gl_CHECK_FUNCS_MACOS([func], [[#include <foo.h>]])
+dnl can be used as a drop-in replacement for
+dnl   AC_CHECK_FUNCS([func]).
+AC_DEFUN([gl_CHECK_FUNCS_MACOS],
+[
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_REQUIRE([gl_PREPARE_CHECK_FUNCS_MACOS])
+  AC_CACHE_CHECK([for [$1]],
+    [[gl_cv_onwards_func_][$1]],
+    [gl_SILENT([
+       case "$host_os" in
+         darwin*)
+           if test "x$gl_cv_compiler_check_future_option" != "xnone"; then
+             dnl Use a compile test, not a link test.
+             save_ac_compile="$ac_compile"
+             ac_compile="$ac_compile $gl_cv_compiler_check_future_option"
+             save_ac_compile_for_check_decl="$ac_compile_for_check_decl"
+             ac_compile_for_check_decl="$ac_compile_for_check_decl $gl_cv_compiler_check_future_option"
+             unset [ac_cv_have_decl_][$1]
+             AC_CHECK_DECL([$1], , , [$2])
+             ac_compile="$save_ac_compile"
+             ac_compile_for_check_decl="$save_ac_compile_for_check_decl"
+             [ac_cv_func_][$1]="$[ac_cv_have_decl_][$1]"
+             if test $[ac_cv_func_][$1] = yes; then
+               [gl_cv_onwards_func_][$1]=yes
+             else
+               unset [ac_cv_have_decl_][$1]
+               AC_CHECK_DECL([$1], , , [$2])
+               if test $[ac_cv_have_decl_][$1] = yes; then
+                 [gl_cv_onwards_func_][$1]='future OS version'
+               else
+                 [gl_cv_onwards_func_][$1]=no
+               fi
+             fi
+           else
+             AC_CHECK_FUNC([$1])
+             [gl_cv_onwards_func_][$1]=$[ac_cv_func_][$1]
+           fi
+           ;;
+         *)
+           AC_CHECK_FUNC([$1])
+           [gl_cv_onwards_func_][$1]=$[ac_cv_func_][$1]
+           ;;
+       esac
+      ])
+    ])
+  case "$[gl_cv_onwards_func_][$1]" in
+    future*) [ac_cv_func_][$1]=no ;;
+    *)       [ac_cv_func_][$1]=$[gl_cv_onwards_func_][$1] ;;
+  esac
+  if test $[ac_cv_func_][$1] = yes; then
+    AC_DEFINE([HAVE_]m4_translit([[$1]],
+                                 [abcdefghijklmnopqrstuvwxyz],
+                                 [ABCDEFGHIJKLMNOPQRSTUVWXYZ]),
+              [1], [Define to 1 if you have the `$1' function.])
+  fi
+])
+
+dnl gl_CHECK_FUNCS_ANDROID_MACOS([func], [[#include <foo.h>]])
+dnl is like AC_CHECK_FUNCS([func]), taking into account a portability problem
+dnl on Android and on macOS.
+dnl It is the combination of gl_CHECK_FUNCS_ANDROID and gl_CHECK_FUNCS_MACOS.
+AC_DEFUN([gl_CHECK_FUNCS_ANDROID_MACOS],
+[
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_REQUIRE([gl_PREPARE_CHECK_FUNCS_MACOS])
+  AC_CACHE_CHECK([for [$1]],
+    [[gl_cv_onwards_func_][$1]],
+    [gl_SILENT([
+       case "$host_os" in
+         linux*-android*)
+           AC_CHECK_DECL([$1], , , [$2])
+           if test $[ac_cv_have_decl_][$1] = yes; then
+             AC_CHECK_FUNC([[$1]])
+             if test $[ac_cv_func_][$1] = yes; then
+               [gl_cv_onwards_func_][$1]=yes
+             else
+               dnl The function is declared but does not exist. This should not
+               dnl happen normally. But anyway, we know that a future version
+               dnl of Android will have the function.
+               [gl_cv_onwards_func_][$1]='future OS version'
+             fi
+           else
+             [gl_cv_onwards_func_][$1]='future OS version'
+           fi
+           ;;
+         darwin*)
+           if test "x$gl_cv_compiler_check_future_option" != "xnone"; then
+             dnl Use a compile test, not a link test.
+             save_ac_compile="$ac_compile"
+             ac_compile="$ac_compile $gl_cv_compiler_check_future_option"
+             save_ac_compile_for_check_decl="$ac_compile_for_check_decl"
+             ac_compile_for_check_decl="$ac_compile_for_check_decl $gl_cv_compiler_check_future_option"
+             unset [ac_cv_have_decl_][$1]
+             AC_CHECK_DECL([$1], , , [$2])
+             ac_compile="$save_ac_compile"
+             ac_compile_for_check_decl="$save_ac_compile_for_check_decl"
+             [ac_cv_func_][$1]="$[ac_cv_have_decl_][$1]"
+             if test $[ac_cv_func_][$1] = yes; then
+               [gl_cv_onwards_func_][$1]=yes
+             else
+               unset [ac_cv_have_decl_][$1]
+               AC_CHECK_DECL([$1], , , [$2])
+               if test $[ac_cv_have_decl_][$1] = yes; then
+                 [gl_cv_onwards_func_][$1]='future OS version'
+               else
+                 [gl_cv_onwards_func_][$1]=no
+               fi
+             fi
+           else
+             AC_CHECK_FUNC([$1])
+             [gl_cv_onwards_func_][$1]=$[ac_cv_func_][$1]
+           fi
+           ;;
+         *)
+           AC_CHECK_FUNC([$1])
+           [gl_cv_onwards_func_][$1]=$[ac_cv_func_][$1]
+           ;;
+       esac
+      ])
+    ])
+  case "$[gl_cv_onwards_func_][$1]" in
+    future*) [ac_cv_func_][$1]=no ;;
+    *)       [ac_cv_func_][$1]=$[gl_cv_onwards_func_][$1] ;;
+  esac
+  if test $[ac_cv_func_][$1] = yes; then
+    AC_DEFINE([HAVE_]m4_translit([[$1]],
+                                 [abcdefghijklmnopqrstuvwxyz],
+                                 [ABCDEFGHIJKLMNOPQRSTUVWXYZ]),
+              [1], [Define to 1 if you have the `$1' function.])
+  fi
+])
+
 dnl Expands to some code for use in .c programs that, on native Windows, defines
 dnl the Microsoft deprecated alias function names to the underscore-prefixed
 dnl actual function names. With this macro, these function names are available
index ed86d5c1979916a8ec821680516edb7e5bedf8d4..26540506f7962732103739cec1a0542c3f2f9b3d 100644 (file)
@@ -1,4 +1,4 @@
-# serial 9
+# serial 10
 # See if we need to provide mkfifoat/mknodat replacement.
 
 dnl Copyright (C) 2009-2023 Free Software Foundation, Inc.
@@ -18,8 +18,8 @@ AC_DEFUN([gl_FUNC_MKFIFOAT],
 
   AC_REQUIRE([gl_FUNC_OPENAT])
 
-  gl_CHECK_FUNCS_ANDROID([mknodat], [[#include <sys/stat.h>]])
-  gl_CHECK_FUNCS_ANDROID([mkfifoat], [[#include <sys/stat.h>]])
+  gl_CHECK_FUNCS_ANDROID_MACOS([mknodat], [[#include <sys/stat.h>]])
+  gl_CHECK_FUNCS_ANDROID_MACOS([mkfifoat], [[#include <sys/stat.h>]])
   if test $ac_cv_func_mkfifoat = yes; then
     dnl Check for AIX 7.2 bug with trailing slash.
     AC_CACHE_CHECK([whether mkfifoat rejects trailing slashes],