dup2.m4 3.7 KB

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