Пример #1
0
int
rpl_dup2 (int fd, int desired_fd)
{
  int result;

# ifdef F_GETFL
  /* On Linux kernels 2.6.26-2.6.29, dup2 (fd, fd) returns -EBADF.
     On Cygwin 1.5.x, dup2 (1, 1) returns 0.
     On Cygwin 1.7.17, dup2 (1, -1) dumps core.
     On Cygwin 1.7.25, dup2 (1, 256) can dump core.
     On Haiku, dup2 (fd, fd) mistakenly clears FD_CLOEXEC.  */
#  if HAVE_SETDTABLESIZE
  setdtablesize (desired_fd + 1);
#  endif
  if (desired_fd < 0)
    fd = desired_fd;
  if (fd == desired_fd)
    return fcntl (fd, F_GETFL) == -1 ? -1 : fd;
# endif

  result = dup2 (fd, desired_fd);

  /* Correct an errno value on FreeBSD 6.1 and Cygwin 1.5.x.  */
  if (result == -1 && errno == EMFILE)
    errno = EBADF;
# if REPLACE_FCHDIR
  if (fd != desired_fd && result != -1)
    result = _gl_register_dup (fd, result);
# endif
  return result;
}
Пример #2
0
int
rpl_dup (int fd)
{
  int result = dup_nothrow (fd);
#if REPLACE_FCHDIR
  if (result >= 0)
    result = _gl_register_dup (fd, result);
#endif
  return result;
}
Пример #3
0
int
rpl_dup (int oldfd)
#undef dup
{
  int newfd = dup (oldfd);

  if (0 <= newfd)
    newfd = _gl_register_dup (oldfd, newfd);
  return newfd;
}
Пример #4
0
int
rpl_dup2 (int fd, int desired_fd)
{
  int result;
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
  /* If fd is closed, mingw hangs on dup2 (fd, fd).  If fd is open,
     dup2 (fd, fd) returns 0, but all further attempts to use fd in
     future dup2 calls will hang.  */
  if (fd == desired_fd)
    {
      if ((HANDLE) _get_osfhandle (fd) == INVALID_HANDLE_VALUE)
        {
          errno = EBADF;
          return -1;
        }
      return fd;
    }
  /* Wine 1.0.1 return 0 when desired_fd is negative but not -1:
     http://bugs.winehq.org/show_bug.cgi?id=21289 */
  if (desired_fd < 0)
    {
      errno = EBADF;
      return -1;
    }
# elif !defined __linux__
  /* On Haiku, dup2 (fd, fd) mistakenly clears FD_CLOEXEC.  */
  if (fd == desired_fd)
    return fcntl (fd, F_GETFL) == -1 ? -1 : fd;
# endif

  result = dup2_nothrow (fd, desired_fd);

# ifdef __linux__
  /* Correct a Linux return value.
     <http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.30.y.git;a=commitdiff;h=2b79bc4f7ebbd5af3c8b867968f9f15602d5f802>
   */
  if (fd == desired_fd && result == (unsigned int) -EBADF)
    {
      errno = EBADF;
      result = -1;
    }
# endif
  if (result == 0)
    result = desired_fd;
  /* Correct a cygwin 1.5.x errno value.  */
  else if (result == -1 && errno == EMFILE)
    errno = EBADF;
# if REPLACE_FCHDIR
  if (fd != desired_fd && result != -1)
    result = _gl_register_dup (fd, result);
# endif
  return result;
}
Пример #5
0
int
dup2 (int fd, int desired_fd)
{
  int result = fcntl (fd, F_GETFL) < 0 ? -1 : fd;
  if (result == -1 || fd == desired_fd)
    return result;
  close (desired_fd);
# ifdef F_DUPFD
  result = fcntl (fd, F_DUPFD, desired_fd);
#  if REPLACE_FCHDIR
  if (0 <= result)
    result = _gl_register_dup (fd, result);
#  endif
# else
  result = dupfd (fd, desired_fd);
# endif
  if (result == -1 && (errno == EMFILE || errno == EINVAL))
    errno = EBADF;
  return result;
}
Пример #6
0
Файл: dup2.c Проект: 274914765/C
int
rpl_dup2 (int fd, int desired_fd)
{
  int result;
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
  /* If fd is closed, mingw hangs on dup2 (fd, fd).  If fd is open,
     dup2 (fd, fd) returns 0, but all further attempts to use fd in
     future dup2 calls will hang.  */
  if (fd == desired_fd)
    {
      if ((HANDLE) _get_osfhandle (fd) == INVALID_HANDLE_VALUE)
        {
          errno = EBADF;
          return -1;
        }
      return fd;
    }
# endif
  result = dup2 (fd, desired_fd);
# ifdef __linux__
  /* Correct a Linux return value.
     <http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.30.y.git;a=commitdiff;h=2b79bc4f7ebbd5af3c8b867968f9f15602d5f802>
   */
  if (fd == desired_fd && result == (unsigned int) -EBADF)
    {
      errno = EBADF;
      result = -1;
    }
# endif
  if (result == 0)
    result = desired_fd;
  /* Correct a cygwin 1.5.x errno value.  */
  else if (result == -1 && errno == EMFILE)
    errno = EBADF;
# if REPLACE_FCHDIR
  if (fd != desired_fd && result != -1)
    result = _gl_register_dup (fd, result);
# endif
  return result;
}
Пример #7
0
int
rpl_dup2 (int fd, int desired_fd)
{
  int result;

# ifdef F_GETFL
  /* On Linux kernels 2.6.26-2.6.29, dup2 (fd, fd) returns -EBADF.
     On Cygwin 1.5.x, dup2 (1, 1) returns 0.
     On Haiku, dup2 (fd, fd) mistakenly clears FD_CLOEXEC.  */
  if (fd == desired_fd)
    return fcntl (fd, F_GETFL) == -1 ? -1 : fd;
# endif

  result = dup2 (fd, desired_fd);

  /* Correct an errno value on FreeBSD 6.1 and Cygwin 1.5.x.  */
  if (result == -1 && errno == EMFILE)
    errno = EBADF;
# if REPLACE_FCHDIR
  if (fd != desired_fd && result != -1)
    result = _gl_register_dup (fd, result);
# endif
  return result;
}
Пример #8
0
int
dup3 (int oldfd, int newfd, int flags)
{
#if HAVE_DUP3
# undef dup3
  /* Try the system call first, if it exists.  (We may be running with a glibc
     that has the function but with an older kernel that lacks it.)  */
  {
    /* Cache the information whether the system call really exists.  */
    static int have_dup3_really; /* 0 = unknown, 1 = yes, -1 = no */
    if (have_dup3_really >= 0)
      {
        int result = dup3 (oldfd, newfd, flags);
        if (!(result < 0 && errno == ENOSYS))
          {
            have_dup3_really = 1;
#if REPLACE_FCHDIR
            if (0 <= result)
              result = _gl_register_dup (oldfd, newfd);
#endif
            return result;
          }
        have_dup3_really = -1;
      }
  }
#endif

  if (newfd < 0 || newfd >= getdtablesize () || fcntl (oldfd, F_GETFD) == -1)
    {
      errno = EBADF;
      return -1;
    }

  if (newfd == oldfd)
    {
      errno = EINVAL;
      return -1;
    }

  /* Check the supported flags.
     Note that O_NONBLOCK is not supported, because setting it on newfd
     would implicitly also set it on oldfd.  */
  if ((flags & ~(O_CLOEXEC | O_BINARY | O_TEXT)) != 0)
    {
      errno = EINVAL;
      return -1;
    }

  if (flags & O_CLOEXEC)
    {
      int result;
      close (newfd);
      result = fcntl (oldfd, F_DUPFD_CLOEXEC, newfd);
      if (newfd < result)
        {
          close (result);
          errno = EIO;
          result = -1;
        }
      if (result < 0)
        return -1;
    }
  else if (dup2 (oldfd, newfd) < 0)
    return -1;

#if O_BINARY
  if (flags & O_BINARY)
    setmode (newfd, O_BINARY);
  else if (flags & O_TEXT)
    setmode (newfd, O_TEXT);
#endif

  return newfd;
}