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 |