Ruby 1.9.3p327(2012-11-10revision37606)
|
00001 /* 00002 * Public domain dup2() lookalike 00003 * by Curtis Jackson @ AT&T Technologies, Burlington, NC 00004 * electronic address: burl!rcj 00005 * 00006 * dup2 performs the following functions: 00007 * 00008 * Check to make sure that fd1 is a valid open file descriptor. 00009 * Check to see if fd2 is already open; if so, close it. 00010 * Duplicate fd1 onto fd2; checking to make sure fd2 is a valid fd. 00011 * Return fd2 if all went well; return BADEXIT otherwise. 00012 */ 00013 00014 #include "ruby/config.h" 00015 00016 #if defined(HAVE_FCNTL) 00017 # include <fcntl.h> 00018 #endif 00019 00020 #if !defined(HAVE_FCNTL) || !defined(F_DUPFD) 00021 # include <errno.h> 00022 #endif 00023 00024 #define BADEXIT -1 00025 00026 int 00027 dup2(int fd1, int fd2) 00028 { 00029 #if defined(HAVE_FCNTL) && defined(F_DUPFD) 00030 if (fd1 != fd2) { 00031 #ifdef F_GETFL 00032 if (fcntl(fd1, F_GETFL) < 0) 00033 return BADEXIT; 00034 if (fcntl(fd2, F_GETFL) >= 0) 00035 close(fd2); 00036 #else 00037 close(fd2); 00038 #endif 00039 if (fcntl(fd1, F_DUPFD, fd2) < 0) 00040 return BADEXIT; 00041 } 00042 return fd2; 00043 #else 00044 extern int errno; 00045 int i, fd, fds[256]; 00046 00047 if (fd1 == fd2) return 0; 00048 close(fd2); 00049 for (i=0; i<256; i++) { 00050 fd = fds[i] = dup(fd1); 00051 if (fd == fd2) break; 00052 } 00053 while (i) { 00054 close(fds[i--]); 00055 } 00056 if (fd == fd2) return 0; 00057 errno = EMFILE; 00058 return BADEXIT; 00059 #endif 00060 } 00061