verify: new macro 'assume'
[gnulib.git] / m4 / nanosleep.m4
1 # serial 36
2
3 dnl From Jim Meyering.
4 dnl Check for the nanosleep function.
5 dnl If not found, use the supplied replacement.
6 dnl
7
8 # Copyright (C) 1999-2001, 2003-2013 Free Software Foundation, Inc.
9
10 # This file is free software; the Free Software Foundation
11 # gives unlimited permission to copy and/or distribute it,
12 # with or without modifications, as long as this notice is preserved.
13
14 AC_DEFUN([gl_FUNC_NANOSLEEP],
15 [
16  AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS])
17  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
18
19  dnl Persuade glibc and Solaris <time.h> to declare nanosleep.
20  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
21
22  AC_CHECK_HEADERS_ONCE([sys/time.h])
23  AC_REQUIRE([gl_FUNC_SELECT])
24
25  nanosleep_save_libs=$LIBS
26
27  # Solaris 2.5.1 needs -lposix4 to get the nanosleep function.
28  # Solaris 7 prefers the library name -lrt to the obsolescent name -lposix4.
29  LIB_NANOSLEEP=
30  AC_SUBST([LIB_NANOSLEEP])
31  AC_SEARCH_LIBS([nanosleep], [rt posix4],
32                 [test "$ac_cv_search_nanosleep" = "none required" ||
33                  LIB_NANOSLEEP=$ac_cv_search_nanosleep])
34  if test "x$ac_cv_search_nanosleep" != xno; then
35    dnl The system has a nanosleep function.
36
37    AC_REQUIRE([gl_MULTIARCH])
38    if test $APPLE_UNIVERSAL_BUILD = 1; then
39      # A universal build on Apple Mac OS X platforms.
40      # The test result would be 'no (mishandles large arguments)' in 64-bit
41      # mode but 'yes' in 32-bit mode. But we need a configuration result that
42      # is valid in both modes.
43      gl_cv_func_nanosleep='no (mishandles large arguments)'
44    fi
45
46    AC_CACHE_CHECK([for working nanosleep],
47     [gl_cv_func_nanosleep],
48     [
49      AC_RUN_IFELSE(
50        [AC_LANG_SOURCE([[
51           #include <errno.h>
52           #include <limits.h>
53           #include <signal.h>
54           #if HAVE_SYS_TIME_H
55            #include <sys/time.h>
56           #endif
57           #include <time.h>
58           #include <unistd.h>
59           #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
60           #define TYPE_MAXIMUM(t) \
61             ((t) (! TYPE_SIGNED (t) \
62                   ? (t) -1 \
63                   : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
64
65           static void
66           check_for_SIGALRM (int sig)
67           {
68             if (sig != SIGALRM)
69               _exit (1);
70           }
71
72           int
73           main ()
74           {
75             static struct timespec ts_sleep;
76             static struct timespec ts_remaining;
77             static struct sigaction act;
78             /* Test for major problems first.  */
79             if (! nanosleep)
80               return 2;
81             act.sa_handler = check_for_SIGALRM;
82             sigemptyset (&act.sa_mask);
83             sigaction (SIGALRM, &act, NULL);
84             ts_sleep.tv_sec = 0;
85             ts_sleep.tv_nsec = 1;
86             alarm (1);
87             if (nanosleep (&ts_sleep, NULL) != 0)
88               return 3;
89             /* Test for a minor problem: the handling of large arguments.  */
90             ts_sleep.tv_sec = TYPE_MAXIMUM (time_t);
91             ts_sleep.tv_nsec = 999999999;
92             alarm (1);
93             if (nanosleep (&ts_sleep, &ts_remaining) != -1)
94               return 4;
95             if (errno != EINTR)
96               return 5;
97             if (ts_remaining.tv_sec <= TYPE_MAXIMUM (time_t) - 10)
98               return 6;
99             return 0;
100           }]])],
101        [gl_cv_func_nanosleep=yes],
102        [case $? in dnl (
103         4|5|6) gl_cv_func_nanosleep='no (mishandles large arguments)';; dnl (
104         *)   gl_cv_func_nanosleep=no;;
105         esac],
106        [case "$host_os" in dnl ((
107           linux*) # Guess it halfway works when the kernel is Linux.
108             gl_cv_func_nanosleep='guessing no (mishandles large arguments)' ;;
109           *)      # If we don't know, assume the worst.
110             gl_cv_func_nanosleep='guessing no' ;;
111         esac
112        ])
113     ])
114    case "$gl_cv_func_nanosleep" in
115      *yes)
116        REPLACE_NANOSLEEP=0
117        ;;
118      *)
119        REPLACE_NANOSLEEP=1
120        case "$gl_cv_func_nanosleep" in
121          *"mishandles large arguments"*)
122            AC_DEFINE([HAVE_BUG_BIG_NANOSLEEP], [1],
123              [Define to 1 if nanosleep mishandles large arguments.])
124            ;;
125          *)
126            # The replacement uses select(). Add $LIBSOCKET to $LIB_NANOSLEEP.
127            for ac_lib in $LIBSOCKET; do
128              case " $LIB_NANOSLEEP " in
129                *" $ac_lib "*) ;;
130                *) LIB_NANOSLEEP="$LIB_NANOSLEEP $ac_lib";;
131              esac
132            done
133            ;;
134        esac
135        ;;
136    esac
137  else
138    HAVE_NANOSLEEP=0
139  fi
140  LIBS=$nanosleep_save_libs
141 ])
142
143 # Prerequisites of lib/nanosleep.c.
144 AC_DEFUN([gl_PREREQ_NANOSLEEP],
145 [
146   AC_CHECK_HEADERS_ONCE([sys/select.h])
147   gl_PREREQ_SIG_HANDLER_H
148 ])