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 |