Source File ut/fdwrap.c

    1    | /******************
    2    |   Copyright (c) 2001,2002                         RIPE NCC
    3    |
    4    |   All Rights Reserved
    5    |
    6    |   Permission to use, copy, modify, and distribute this software and its
    7    |   documentation for any purpose and without fee is hereby granted,
    8    |   provided that the above copyright notice appear in all copies and that
    9    |   both that copyright notice and this permission notice appear in
    10   |   supporting documentation, and that the name of the author not be
    11   |   used in advertising or publicity pertaining to distribution of the
    12   |   software without specific, written prior permission.
    13   |
    14   |   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
    15   |   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
    16   |   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
    17   |   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
    18   |   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    19   |   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    20   |   ***************************************/
    21   |
    22   | #if 0
    23   | We have received errors both from select() and fcntl() claiming that
    24   | they were called on bad file descriptors in "impossible" situations.
    25   | The theory is that some other thread has closed the file descriptor.
    26   | This can happen, for instance, if another thread attempts to call
    27   | close() twice on the same integer.  For example:
    28   |
    29   |    ret_val = 0;
    30   |    connect(fd, &addr, sizeof(addr));
    31   |      .
    32   |      .
    33   |      .
    34   |    if (error) {
    35   |        close(fd);
    36   |        ret_val = -1;
    37   |        goto get_out;
    38   |    }
    39   |      .
    40   |      .
    41   |      .
    42   |    get_out:
    43   |        close(fd);          /* OOOPS!!!  Bogus second call to close() */
    44   |        return ret_val;
    45   |
    46   | In an effort to detect this condition, we introduce this wrapper, which
    47   | sets the file descriptor to -1 (an illegal file number) while closing.
    48   | This means that subsequent calls can detect the -1 value and issue an
    49   | appropriate warning.
    50   |
    51   | Shane, 2001-07-02
    52   | #endif /* 0 */
    53   |
    54   | #include "rip.h"
    55   |
    56   | #include <unistd.h>
    57   | #include <stdio.h>
    58   | #include <errno.h>
    59   |
    60   | /* undefine our wrappers so we can use the real functions */
    61   | #undef close
    62   | #undef fclose
    63   |
    64   | int
    65   | fdwrap_close (int *fd, const char *file, int line)
    66   | {
    67   |     int open_fd;
    68   |
    69   |     /* save the passed file descriptor, and set to -1 */
    70   |     open_fd = *fd;
    71   |     *fd = -1;
    72   |
    73   |     /* check to see if we've closed this already */
    74   |     if (open_fd < 0) {
    75   |         /* report error */
    76   |         ER_perror(FAC_UT, UT_DUPCLOSE,
    77   |             "close() called on closed file descriptor from %s:%d",
    78   |             file, line);
    79   |
    80   |         /* return error */
    81   |         errno = EBADF;
    82   |         return -1;
    83   |     } else {
    84   |         /* the usual case, call close() */
    85   |         return close(open_fd);
    86   |     }
    87   | }
    88   |
    89   | int
    90   | fdwrap_fclose (FILE **fp, const char *file, int line)
    91   | {
    92   |     FILE *open_fp;
    93   |
    94   |     /* save the passed file handle, and set to NULL */
    95   |     open_fp = *fp;
    96   |     *fp = NULL;
    97   |
    98   |     /* check to see if we've closed this already */
    99   |     if (open_fp == NULL) {
    100  |         /* report error */
    101  |         ER_perror(FAC_UT, UT_DUPCLOSE,
    102  |             "fclose() called on closed file handle from %s:%d",
    103  |             file, line);
    104  |
    105  |         /* return error */
    106  |         errno = EBADF;
    107  |         return EOF;
    108  |     } else {
    109  |         /* the usual case, call fclose() */
    110  |         return fclose(open_fp);
    111  |     }
    112  | }
    113  |