ex-3.2.c (2227B)
1 /* 2 * Advanced Programming in the UNIX(r) Environment 3 * 4 * Exercise 3.2 5 */ 6 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <unistd.h> 10 #include <errno.h> 11 12 /* 13 * Determinate the maximum number of open files (fds) 14 */ 15 #ifdef OPEN_MAX 16 static int openmax = OPEN_MAX; 17 #else 18 #define OPEN_MAX_GUESS 256 19 static int openmax = 0; 20 #endif 21 22 /* 23 * Functions prototypes 24 */ 25 int set_open_max(void); 26 int my_dup2(int fd1, int fd2); 27 28 int 29 main(void) 30 { 31 32 /* set the openmax variable */ 33 if( set_open_max() ) 34 return EXIT_FAILURE ; 35 36 /* 37 * Testing the function 38 */ 39 if( my_dup2(STDOUT_FILENO, 5) == -1 ) { 40 perror("my_dup2()"); 41 return EXIT_FAILURE ; /* Something went wrong */ 42 } 43 44 /* Write to the new file descriptor */ 45 if( write(5, "my_dup2()", 9) != 9 ) { 46 perror("write()"); 47 return EXIT_FAILURE ; /* Something went wrong */ 48 } 49 50 /* 51 * File descriptors are implicitally at the end of the program 52 */ 53 54 return EXIT_SUCCESS ; 55 } /* eof main() */ 56 57 /* 58 * Set the maximum number of file descriptors. 59 * Adapted from the APUE sample program 2.3. 60 */ 61 int 62 set_open_max(void) 63 { 64 65 if( ! openmax ) { 66 67 errno = 0; 68 69 if( (openmax = sysconf(_SC_OPEN_MAX)) < 0 ) { 70 if( ! errno ) 71 openmax = OPEN_MAX_GUESS; 72 else 73 return -1; 74 } 75 76 } 77 78 return 0; 79 } /* eof set_open_max() */ 80 81 /* 82 * Duplicate a file descriptor (non atomically) 83 */ 84 int 85 my_dup2(int fd1, int fd2) 86 { 87 int fds_total = 0, *fds_list; 88 89 /* check if are valid file descriptors */ 90 if( fd1 < 0 || fd1 > openmax || fd2 < 0 || fd2 > openmax ) { 91 errno = EBADF; 92 return -1; 93 } 94 95 /* If the descriptors are not the same then duplicate fd1 to fd2 */ 96 if( fd1 != fd2 ) { 97 98 /* Allocate the file descriptors container */ 99 if( (fds_list = calloc(1, openmax * sizeof(int))) == NULL ) 100 return -1; 101 102 /* close fd2 first, if open */ 103 (void)close(fd2); 104 105 /* get the duplicated file descriptor number "fd2" */ 106 while( (fds_list[fds_total] = dup(fd1)) != fd2 ) 107 ++fds_total; 108 109 /* close the others descriptors */ 110 while( --fds_total >= 0 ) 111 (void)close(fds_list[fds_total]); 112 113 free(fds_list); 114 115 } 116 117 return fd2; 118 } /* eof my_dup2() */ 119