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