training

Code I wrote during training
git clone git://git.bitsmanent.org/training
Log | Files | Refs | README

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