1/* 2 * Public domain dup2() lookalike 3 * by Curtis Jackson @ AT&T Technologies, Burlington, NC 4 * electronic address: burl!rcj 5 * 6 * dup2 performs the following functions: 7 * 8 * Check to make sure that fd1 is a valid open file descriptor. 9 * Check to see if fd2 is already open; if so, close it. 10 * Duplicate fd1 onto fd2; checking to make sure fd2 is a valid fd. 11 * Return fd2 if all went well; return BADEXIT otherwise. 12 */ 13 14#include "ruby/config.h" 15 16#if defined(HAVE_FCNTL) 17# include <fcntl.h> 18#endif 19 20#if !defined(HAVE_FCNTL) || !defined(F_DUPFD) 21# include <errno.h> 22#endif 23 24#define BADEXIT -1 25 26int 27dup2(int fd1, int fd2) 28{ 29#if defined(HAVE_FCNTL) && defined(F_DUPFD) 30 if (fd1 != fd2) { 31#ifdef F_GETFL 32 if (fcntl(fd1, F_GETFL) < 0) 33 return BADEXIT; 34 if (fcntl(fd2, F_GETFL) >= 0) 35 close(fd2); 36#else 37 close(fd2); 38#endif 39 if (fcntl(fd1, F_DUPFD, fd2) < 0) 40 return BADEXIT; 41 } 42 return fd2; 43#else 44 extern int errno; 45 int i, fd, fds[256]; 46 47 if (fd1 == fd2) return 0; 48 close(fd2); 49 for (i=0; i<256; i++) { 50 fd = fds[i] = dup(fd1); 51 if (fd == fd2) break; 52 } 53 while (i) { 54 close(fds[i--]); 55 } 56 if (fd == fd2) return 0; 57 errno = EMFILE; 58 return BADEXIT; 59#endif 60} 61