Jim Meyering wrote: ... > Thank you for the report. > In fixing that, I made three changes: > > maint: tac: remove sole use of sprintf in favor of stpcpy > tac: don't misbehave with multiple non-seekable inputs > tac: don't leak a file descriptor for each non-seekable input > > Before the primary bug fix (2/3), tac could leak only one file > descriptor, because that bug prevented us from opening 2nd and > subsequent files. But once fixed, it would leak an FD for each "-" > (or other nonseekable) command line argument. ... >>From 95fa11b63f0a5c983723f02afa7c5b896e5a0a97 Mon Sep 17 00:00:00 2001 > From: Jim Meyering <meyer...@redhat.com> > Date: Sun, 16 Oct 2011 12:14:05 +0200 > Subject: [PATCH 3/3] tac: don't leak a file descriptor for each non-seekable > input > > * src/tac.c (tac_nonseekable): Call fclose after each successful > call to copy_to_temp. > --- > src/tac.c | 2 ++ > 1 files changed, 2 insertions(+), 0 deletions(-) > > diff --git a/src/tac.c b/src/tac.c > index 2d8d6ea..ebafa18 100644 > --- a/src/tac.c > +++ b/src/tac.c > @@ -516,9 +516,11 @@ tac_nonseekable (int input_fd, const char *file) > { > if (tac_seekable (fileno (tmp_stream), tmp_file)) > { > + fclose (tmp_stream); > free (tmp_file); > return true; > } > + fclose (tmp_stream); > } > > return false;
There was also an error-path leak of "tmp_file", even with the patch above (which was not pushed). I've adjusted it to fix that, too: >From 3f468dfce95ae301359511e19b13658f35a90444 Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyer...@redhat.com> Date: Sun, 16 Oct 2011 12:14:05 +0200 Subject: [PATCH] tac: don't leak a file descriptor for each non-seekable input * src/tac.c (tac_nonseekable): Call fclose and free tmp_file after each successful call to copy_to_temp. --- src/tac.c | 15 ++++++--------- 1 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/tac.c b/src/tac.c index 2d8d6ea..13b05fb 100644 --- a/src/tac.c +++ b/src/tac.c @@ -512,16 +512,13 @@ tac_nonseekable (int input_fd, const char *file) { FILE *tmp_stream; char *tmp_file; - if (copy_to_temp (&tmp_stream, &tmp_file, input_fd, file)) - { - if (tac_seekable (fileno (tmp_stream), tmp_file)) - { - free (tmp_file); - return true; - } - } + if (!copy_to_temp (&tmp_stream, &tmp_file, input_fd, file)) + return false; - return false; + bool ok = tac_seekable (fileno (tmp_stream), tmp_file); + fclose (tmp_stream); + free (tmp_file); + return ok; } /* Print FILE in reverse, copying it to a temporary -- 1.7.7