| 1 | #serial 27
 | 
|---|
| 2 | dnl Copyright (C) 2002, 2005, 2007, 2009-2021 Free Software Foundation, Inc.
 | 
|---|
| 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 | AC_DEFUN([gl_FUNC_DUP2],
 | 
|---|
| 8 | [
 | 
|---|
| 9 |   AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
 | 
|---|
| 10 |   AC_REQUIRE([AC_CANONICAL_HOST])
 | 
|---|
| 11 |   AC_CACHE_CHECK([whether dup2 works], [gl_cv_func_dup2_works],
 | 
|---|
| 12 |     [AC_RUN_IFELSE([
 | 
|---|
| 13 |        AC_LANG_PROGRAM(
 | 
|---|
| 14 |          [[#include <errno.h>
 | 
|---|
| 15 |            #include <fcntl.h>
 | 
|---|
| 16 |            #include <limits.h>
 | 
|---|
| 17 |            #include <sys/resource.h>
 | 
|---|
| 18 |            #include <unistd.h>
 | 
|---|
| 19 |            ]GL_MDA_DEFINES[
 | 
|---|
| 20 |            #ifndef RLIM_SAVED_CUR
 | 
|---|
| 21 |            # define RLIM_SAVED_CUR RLIM_INFINITY
 | 
|---|
| 22 |            #endif
 | 
|---|
| 23 |            #ifndef RLIM_SAVED_MAX
 | 
|---|
| 24 |            # define RLIM_SAVED_MAX RLIM_INFINITY
 | 
|---|
| 25 |            #endif
 | 
|---|
| 26 |          ]],
 | 
|---|
| 27 |          [[int result = 0;
 | 
|---|
| 28 |            int bad_fd = INT_MAX;
 | 
|---|
| 29 |            struct rlimit rlim;
 | 
|---|
| 30 |            if (getrlimit (RLIMIT_NOFILE, &rlim) == 0
 | 
|---|
| 31 |                && 0 <= rlim.rlim_cur && rlim.rlim_cur <= INT_MAX
 | 
|---|
| 32 |                && rlim.rlim_cur != RLIM_INFINITY
 | 
|---|
| 33 |                && rlim.rlim_cur != RLIM_SAVED_MAX
 | 
|---|
| 34 |                && rlim.rlim_cur != RLIM_SAVED_CUR)
 | 
|---|
| 35 |              bad_fd = rlim.rlim_cur;
 | 
|---|
| 36 |            #ifdef FD_CLOEXEC
 | 
|---|
| 37 |              if (fcntl (1, F_SETFD, FD_CLOEXEC) == -1)
 | 
|---|
| 38 |                result |= 1;
 | 
|---|
| 39 |            #endif
 | 
|---|
| 40 |            if (dup2 (1, 1) != 1)
 | 
|---|
| 41 |              result |= 2;
 | 
|---|
| 42 |            #ifdef FD_CLOEXEC
 | 
|---|
| 43 |              if (fcntl (1, F_GETFD) != FD_CLOEXEC)
 | 
|---|
| 44 |                result |= 4;
 | 
|---|
| 45 |            #endif
 | 
|---|
| 46 |            close (0);
 | 
|---|
| 47 |            if (dup2 (0, 0) != -1)
 | 
|---|
| 48 |              result |= 8;
 | 
|---|
| 49 |            /* Many gnulib modules require POSIX conformance of EBADF.  */
 | 
|---|
| 50 |            if (dup2 (2, bad_fd) == -1 && errno != EBADF)
 | 
|---|
| 51 |              result |= 16;
 | 
|---|
| 52 |            /* Flush out some cygwin core dumps.  */
 | 
|---|
| 53 |            if (dup2 (2, -1) != -1 || errno != EBADF)
 | 
|---|
| 54 |              result |= 32;
 | 
|---|
| 55 |            dup2 (2, 255);
 | 
|---|
| 56 |            dup2 (2, 256);
 | 
|---|
| 57 |            /* On OS/2 kLIBC, dup2() does not work on a directory fd.  */
 | 
|---|
| 58 |            {
 | 
|---|
| 59 |              int fd = open (".", O_RDONLY);
 | 
|---|
| 60 |              if (fd == -1)
 | 
|---|
| 61 |                result |= 64;
 | 
|---|
| 62 |              else if (dup2 (fd, fd + 1) == -1)
 | 
|---|
| 63 |                result |= 128;
 | 
|---|
| 64 |              close (fd);
 | 
|---|
| 65 |            }
 | 
|---|
| 66 |            return result;]])
 | 
|---|
| 67 |       ],
 | 
|---|
| 68 |       [gl_cv_func_dup2_works=yes], [gl_cv_func_dup2_works=no],
 | 
|---|
| 69 |       [case "$host_os" in
 | 
|---|
| 70 |          mingw*) # on this platform, dup2 always returns 0 for success
 | 
|---|
| 71 |            gl_cv_func_dup2_works="guessing no" ;;
 | 
|---|
| 72 |          cygwin*) # on cygwin 1.5.x, dup2(1,1) returns 0
 | 
|---|
| 73 |            gl_cv_func_dup2_works="guessing no" ;;
 | 
|---|
| 74 |          aix* | freebsd*)
 | 
|---|
| 75 |                  # on AIX 7.1 and FreeBSD 6.1, dup2 (1,toobig) gives EMFILE,
 | 
|---|
| 76 |                  # not EBADF.
 | 
|---|
| 77 |            gl_cv_func_dup2_works="guessing no" ;;
 | 
|---|
| 78 |          haiku*) # on Haiku alpha 2, dup2(1, 1) resets FD_CLOEXEC.
 | 
|---|
| 79 |            gl_cv_func_dup2_works="guessing no" ;;
 | 
|---|
| 80 |          *-android*) # implemented using dup3(), which fails if oldfd == newfd
 | 
|---|
| 81 |            gl_cv_func_dup2_works="guessing no" ;;
 | 
|---|
| 82 |          os2*) # on OS/2 kLIBC, dup2() does not work on a directory fd.
 | 
|---|
| 83 |            gl_cv_func_dup2_works="guessing no" ;;
 | 
|---|
| 84 |          *) gl_cv_func_dup2_works="guessing yes" ;;
 | 
|---|
| 85 |        esac])
 | 
|---|
| 86 |     ])
 | 
|---|
| 87 |   case "$gl_cv_func_dup2_works" in
 | 
|---|
| 88 |     *yes) ;;
 | 
|---|
| 89 |     *)
 | 
|---|
| 90 |       REPLACE_DUP2=1
 | 
|---|
| 91 |       AC_CHECK_FUNCS([setdtablesize])
 | 
|---|
| 92 |       ;;
 | 
|---|
| 93 |   esac
 | 
|---|
| 94 |   dnl Replace dup2() for supporting the gnulib-defined fchdir() function,
 | 
|---|
| 95 |   dnl to keep fchdir's bookkeeping up-to-date.
 | 
|---|
| 96 |   m4_ifdef([gl_FUNC_FCHDIR], [
 | 
|---|
| 97 |     gl_TEST_FCHDIR
 | 
|---|
| 98 |     if test $HAVE_FCHDIR = 0; then
 | 
|---|
| 99 |       REPLACE_DUP2=1
 | 
|---|
| 100 |     fi
 | 
|---|
| 101 |   ])
 | 
|---|
| 102 | ])
 | 
|---|
| 103 | 
 | 
|---|
| 104 | # Prerequisites of lib/dup2.c.
 | 
|---|
| 105 | AC_DEFUN([gl_PREREQ_DUP2], [])
 | 
|---|