author | Ian Blanes
<ian@kewao.com> 2018-09-30 09:39:25 UTC |
committer | Alberto Bertogli
<albertito@blitiri.com.ar> 2018-09-30 21:50:42 UTC |
parent | 0d4f662733045f0e3f6e2936e94518cd4186129e |
preload/posix/modules/posix.custom.c | +56 | -3 |
preload/posix/modules/posix.stdio.mod | +4 | -3 |
diff --git a/preload/posix/modules/posix.custom.c b/preload/posix/modules/posix.custom.c index 9c95293..86c6269 100644 --- a/preload/posix/modules/posix.custom.c +++ b/preload/posix/modules/posix.custom.c @@ -289,10 +289,22 @@ static void clear_ferror(void * stream) for (;;) { int next_index = (index + 1) % MAX_FERROR_TRACKED_FILES; - ferror_hash_table[index] = ferror_hash_table[next_index]; - if (ferror_hash_table[index] == NULL) - break; + /* Break if next entry is not a collision or if there is + * nothing to copy back. */ + + int next_hash_value = (int) ( + (uintptr_t) ferror_hash_table[next_index] + % MAX_FERROR_TRACKED_FILES); + + if (next_index == next_hash_value + || ferror_hash_table[next_index] == NULL) { + + ferror_hash_table[index] = NULL; + break; + } + + ferror_hash_table[index] = ferror_hash_table[next_index]; index = next_index; } @@ -421,6 +433,47 @@ void clearerr (FILE *stream) rec_dec(); } +/* Custom wrapper for fclose() that clears ferror_hash_table. */ +mkwrap_top(int , fclose, (FILE *stream), (stream), (FILE *), (EOF)) + static const int valid_errnos[] = { + #ifdef EAGAIN + EAGAIN, + #endif + #ifdef EBADF + EBADF, + #endif + #ifdef EFBIG + EFBIG, + #endif + #ifdef EFBIG + EFBIG, + #endif + #ifdef EINTR + EINTR, + #endif + #ifdef EIO + EIO, + #endif + #ifdef ENOMEM + ENOMEM, + #endif + #ifdef ENOSPC + ENOSPC, + #endif + #ifdef EPIPE + EPIPE, + #endif + #ifdef ENXIO + ENXIO, + #endif + }; +mkwrap_body_errno("posix/stdio/oc/fclose", EOF) + +/* We need a custom injection of clear_ferror here to prevent stale entries in + * ferror_hash_table. */ + clear_ferror(stream); + +mkwrap_bottom(fclose, (stream)) /* diff --git a/preload/posix/modules/posix.stdio.mod b/preload/posix/modules/posix.stdio.mod index 61e9567..3055536 100644 --- a/preload/posix/modules/posix.stdio.mod +++ b/preload/posix/modules/posix.stdio.mod @@ -17,9 +17,10 @@ FILE *freopen(const char *pathname, const char *mode, FILE *stream); valid errnos: EACCES EBADF EINTR EISDIR ELOOP EMFILE ENAMETOOLONG ENFILE ENOENT ENOTDIR ENOSPC ENXIO EOVERFLOW EROFS EBADF EINVAL ENOMEM ENXIO ETXTBSY variants: off64_t -int fclose(FILE *stream); - on error: EOF - valid errnos: EAGAIN EBADF EFBIG EFBIG EINTR EIO ENOMEM ENOSPC EPIPE ENXIO +# This one needs to be further instrumented. +# int fclose(FILE *stream); +# on error: EOF +# valid errnos: EAGAIN EBADF EFBIG EFBIG EINTR EIO ENOMEM ENOSPC EPIPE ENXIO FILE *fdopen(int fd, const char *mode); on error: NULL