@@ -398,16 +398,17 @@ int __bbs_close(int fd, const char *file, int line, const char *func)
398398
399399 /* Detect attempts to close file descriptors we shouldn't be closing
400400 * (e.g. can happen if a file descriptor variable is initialized to 0 instead of -1) */
401- if (fd <= 2 && (fd < 0 || strcmp (file , "system.c" ))) { /* It's legitimate to close file descriptors 0, 1, and 2 when calling exec */
401+ if (unlikely ( fd <= 2 ) && (fd < 0 || strcmp (file , "system.c" ))) { /* It's legitimate to close file descriptors 0, 1, and 2 when calling exec */
402402 bbs_warning ("Attempting to close file descriptor %d at %s:%d (%s)\n" , fd , file , line , func );
403403 bbs_log_backtrace (); /* Get a backtrace to see what made the invalid close, in case immediate caller isn't enough detail. */
404404 }
405405 res = close (fd );
406406 if (res ) {
407407 if (errno == EBADF && ARRAY_IN_BOUNDS (fd , fdleaks )) {
408- __bbs_log (LOG_WARNING , 0 , file , line , func , "Failed to close file descriptor %d: %s (previously closed at %s:%d)\n" , fd , strerror (errno ), fdleaks [fd ].file , fdleaks [fd ].line );
408+ __bbs_log (LOG_WARNING , 0 , file , line , func , "Failed to close fd %d: %s (previously %s at %s:%d)\n" ,
409+ fd , strerror (errno ), fdleaks [fd ].isopen ? "opened" : "closed" , fdleaks [fd ].file , fdleaks [fd ].line );
409410 } else {
410- __bbs_log (LOG_WARNING , 0 , file , line , func , "Failed to close file descriptor %d: %s\n" , fd , strerror (errno ));
411+ __bbs_log (LOG_WARNING , 0 , file , line , func , "Failed to close fd %d: %s\n" , fd , strerror (errno ));
411412 }
412413 } else if (ARRAY_IN_BOUNDS (fd , fdleaks )) { /* && !res (implicit) */
413414 fdleaks [fd ].isopen = 0 ;
@@ -417,7 +418,27 @@ int __bbs_close(int fd, const char *file, int line, const char *func)
417418 }
418419 FD_LOGF ("%lu: %s:%d (%s) close(%d)\n" , time (NULL ), file , line , func , fd );
419420 return res ;
420- }
421+ }
422+
423+ /* gcc thinks func is unused in this function? */
424+ #pragma GCC diagnostic push
425+ #pragma GCC diagnostic ignored "-Wunused-parameter"
426+ int __bbs_mark_closed (int fd , const char * file , int line , const char * func )
427+ {
428+ /* Don't attempt to close the file descriptor, if it's already closed.
429+ * Something else may reuse it in the meantime and we could close something else.
430+ * Of course, if that's the case, we'll mess up our state array below,
431+ * but that's lower stakes than actually messing up program behavior. */
432+ if (ARRAY_IN_BOUNDS (fd , fdleaks )) {
433+ fdleaks [fd ].isopen = 0 ;
434+ /* Update to where it was closed so we can debug attempts to close previously closed fds */
435+ COPY (fdleaks [fd ].file , file );
436+ fdleaks [fd ].line = line ;
437+ }
438+ FD_LOGF ("%lu: %s:%d (%s) mark_closed(%d)\n" , time (NULL ), file , line , func , fd );
439+ return 0 ;
440+ }
441+ #pragma GCC diagnostic pop
421442
422443FILE * __bbs_fopen (const char * path , const char * mode , const char * file , int line , const char * func )
423444{
0 commit comments