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  |