Commit | Line | Data |
---|---|---|
6ec2e0f5 | 1 | # fcntl.m4 serial 9 |
5df4cba6 | 2 | dnl Copyright (C) 2009-2020 Free Software Foundation, Inc. |
6ec2e0f5 SDJ |
3 | dnl This file is free software; the Free Software Foundation |
4 | dnl gives unlimited permission to copy and/or distribute it, | |
5 | dnl with or without modifications, as long as this notice is preserved. | |
6 | ||
7 | # For now, this module ensures that fcntl() | |
8 | # - supports F_DUPFD correctly | |
9 | # - supports or emulates F_DUPFD_CLOEXEC | |
10 | # - supports F_GETFD | |
11 | # Still to be ported to mingw: | |
12 | # - F_SETFD | |
13 | # - F_GETFL, F_SETFL | |
14 | # - F_GETOWN, F_SETOWN | |
15 | # - F_GETLK, F_SETLK, F_SETLKW | |
16 | AC_DEFUN([gl_FUNC_FCNTL], | |
17 | [ | |
18 | dnl Persuade glibc to expose F_DUPFD_CLOEXEC. | |
19 | AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) | |
20 | AC_REQUIRE([gl_FCNTL_H_DEFAULTS]) | |
21 | AC_REQUIRE([AC_CANONICAL_HOST]) | |
22 | AC_CHECK_FUNCS_ONCE([fcntl]) | |
23 | if test $ac_cv_func_fcntl = no; then | |
24 | gl_REPLACE_FCNTL | |
25 | else | |
26 | dnl cygwin 1.5.x F_DUPFD has wrong errno, and allows negative target | |
27 | dnl haiku alpha 2 F_DUPFD has wrong errno | |
28 | AC_CACHE_CHECK([whether fcntl handles F_DUPFD correctly], | |
29 | [gl_cv_func_fcntl_f_dupfd_works], | |
30 | [AC_RUN_IFELSE( | |
31 | [AC_LANG_PROGRAM( | |
32 | [[#include <errno.h> | |
33 | #include <fcntl.h> | |
34 | #include <limits.h> | |
35 | #include <sys/resource.h> | |
36 | #include <unistd.h> | |
37 | #ifndef RLIM_SAVED_CUR | |
38 | # define RLIM_SAVED_CUR RLIM_INFINITY | |
39 | #endif | |
40 | #ifndef RLIM_SAVED_MAX | |
41 | # define RLIM_SAVED_MAX RLIM_INFINITY | |
42 | #endif | |
43 | ]], | |
44 | [[int result = 0; | |
45 | int bad_fd = INT_MAX; | |
46 | struct rlimit rlim; | |
47 | if (getrlimit (RLIMIT_NOFILE, &rlim) == 0 | |
48 | && 0 <= rlim.rlim_cur && rlim.rlim_cur <= INT_MAX | |
49 | && rlim.rlim_cur != RLIM_INFINITY | |
50 | && rlim.rlim_cur != RLIM_SAVED_MAX | |
51 | && rlim.rlim_cur != RLIM_SAVED_CUR) | |
52 | bad_fd = rlim.rlim_cur; | |
53 | if (fcntl (0, F_DUPFD, -1) != -1) result |= 1; | |
54 | if (errno != EINVAL) result |= 2; | |
55 | if (fcntl (0, F_DUPFD, bad_fd) != -1) result |= 4; | |
56 | if (errno != EINVAL) result |= 8; | |
57 | /* On OS/2 kLIBC, F_DUPFD does not work on a directory fd */ | |
58 | { | |
59 | int fd; | |
60 | fd = open (".", O_RDONLY); | |
61 | if (fd == -1) | |
62 | result |= 16; | |
63 | else if (fcntl (fd, F_DUPFD, STDERR_FILENO + 1) == -1) | |
64 | result |= 32; | |
65 | ||
66 | close (fd); | |
67 | } | |
68 | return result;]])], | |
69 | [gl_cv_func_fcntl_f_dupfd_works=yes], | |
70 | [gl_cv_func_fcntl_f_dupfd_works=no], | |
71 | [case $host_os in | |
72 | aix* | cygwin* | haiku*) | |
73 | gl_cv_func_fcntl_f_dupfd_works="guessing no" ;; | |
74 | *) gl_cv_func_fcntl_f_dupfd_works="guessing yes" ;; | |
75 | esac])]) | |
76 | case $gl_cv_func_fcntl_f_dupfd_works in | |
77 | *yes) ;; | |
78 | *) gl_REPLACE_FCNTL | |
79 | AC_DEFINE([FCNTL_DUPFD_BUGGY], [1], [Define this to 1 if F_DUPFD | |
80 | behavior does not match POSIX]) ;; | |
81 | esac | |
82 | ||
83 | dnl Many systems lack F_DUPFD_CLOEXEC | |
84 | AC_CACHE_CHECK([whether fcntl understands F_DUPFD_CLOEXEC], | |
85 | [gl_cv_func_fcntl_f_dupfd_cloexec], | |
86 | [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ | |
87 | #include <fcntl.h> | |
88 | #ifndef F_DUPFD_CLOEXEC | |
89 | choke me | |
90 | #endif | |
91 | ]])], | |
92 | [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ | |
93 | #ifdef __linux__ | |
94 | /* The Linux kernel only added F_DUPFD_CLOEXEC in 2.6.24, so we always replace | |
95 | it to support the semantics on older kernels that failed with EINVAL. */ | |
96 | choke me | |
97 | #endif | |
98 | ]])], | |
99 | [gl_cv_func_fcntl_f_dupfd_cloexec=yes], | |
100 | [gl_cv_func_fcntl_f_dupfd_cloexec="needs runtime check"])], | |
101 | [gl_cv_func_fcntl_f_dupfd_cloexec=no])]) | |
102 | if test "$gl_cv_func_fcntl_f_dupfd_cloexec" != yes; then | |
103 | gl_REPLACE_FCNTL | |
104 | dnl No witness macro needed for this bug. | |
105 | fi | |
106 | fi | |
107 | dnl Replace fcntl() for supporting the gnulib-defined fchdir() function, | |
108 | dnl to keep fchdir's bookkeeping up-to-date. | |
109 | m4_ifdef([gl_FUNC_FCHDIR], [ | |
110 | gl_TEST_FCHDIR | |
111 | if test $HAVE_FCHDIR = 0; then | |
112 | gl_REPLACE_FCNTL | |
113 | fi | |
114 | ]) | |
115 | ]) | |
116 | ||
117 | AC_DEFUN([gl_REPLACE_FCNTL], | |
118 | [ | |
119 | AC_REQUIRE([gl_FCNTL_H_DEFAULTS]) | |
120 | AC_CHECK_FUNCS_ONCE([fcntl]) | |
121 | if test $ac_cv_func_fcntl = no; then | |
122 | HAVE_FCNTL=0 | |
123 | else | |
124 | REPLACE_FCNTL=1 | |
125 | fi | |
126 | ]) |