Subject: bug#9762: tac fails when given multiple non-seekable inputs due to misuse of mkstemp()

From: Jim Meyering <[email-masked]>
Date: Tue, 18 Oct 2011 18:27:46 +0200

Paul Eggert wrote:
> On 10/18/11 05:38, Jim Meyering wrote:
>> * src/tac.c (temp_stream): Don't exit immediately upon failed heap
>> allocation, here.  That would inhibit processing of any additional
>> command-line arguments.

Hi Paul,

Perhaps I should add this to the log:

...which may require no additional memory allocation.

> It doesn't matter that much either way here, but in general I'm
> leery about any attempt to do useful work after a memory allocation
> failure in C.  The output of 'tac' will be wrong anyway, and many
> users would prefer 'tac' to simply exit, than to go on and generate
> a much larger (but still wrong) output, consuming needless resources.
>
> Also (as my recent experiences with Emacs have shown),
> once malloc has failed, other code can start to go wrong,
> including library code that we have no control over.  Sometimes
> the failures are subtle, and sometimes they're spectacular; either
> way it's typically better to steer clear of that particular chasm.
>
> After malloc fails, Emacs typically enters a "restricted" mode,
> where it first releases a memory reserve, and then continually
> asks you to save your work and exit as soon as possible.  This
> is good advice, and even then one is not entirely sure of exiting
> safely.

That makes sense for a monolithic, long-running program
like emacs, but command-line tools like tac...
There is little risk.  tac will still exit nonzero,
and that should be sufficient to tell any caller that
there's been a failure.  What is to be gained?
Diagnostics about other file arguments and a greater
percentage of output.

In this case continuing to process arguments after such a failure is
easy and imho, desirable, since a non-seekable input is unusual and
likely to be followed by a seekable one (if by anything).

i.e., if this command fails while processing arg2,

    tac foo <(some command) bar unreadable

it should be able to process "bar" and then diagnose
that the final argument is an unreadable file.

The principle is the same as the one that prompts
POSIX to require (at least from what I recall) that
all arguments be processed, whenever possible.