in reply to Re^4: Scoping question - will file handle be closed?
in thread Scoping question - will file handle be closed?

Perl close() is not POSIX close(). Some less-bizarre reasons that Perl close() might fail include:

ENOSPC
A previous write to disk failed because the disk partition ran out of space (and you had not cleared errors for that handle by seek()ing since then).
EPIPE
You had unflushed data and close() tried to flush it and all of the readers at the other end of your pipe/socket have already closed/shutdown their end. Or a previous write to that handle failed for that reason (and you probably got a SIGPIPE earlier).
EIO
Your device has decided to fail. This is more specific than "something is wrong". You should arrange to remember what you had opened so that you can mention that in the "close() failed" error message so the user (or their admin) can determine which device to check.
ECONNRESET
Your socket connection got reset (since the last time you cleared errors by seek()ing).
ENOMEM
The system wanted to allocate more buffer space but the call to allocate that failed (possible at least for sockets).

Plus there are errors that can originate from some I/O layer. You'd have to consult the documentation and/or code for whatever layers you might use for more information on that. Perhaps you can use an encoding layer configured to complain about untranslatable characters via an error return. Or a "decompress" layer might complain about invalid input.

It can be useful to check for close failing because it may be important to not continue on after close() failed because the data you were writing or reading is incomplete and so you shouldn't submit it or shouldn't mark the data source as "done" or whatever.

It is usually easier to check for close() failing than to check every single I/O operation for failure. If using buffered I/O, then checking every single I/O operation wouldn't be sufficient anyway.

If I have no logical recovery step for "incomplete data", then I will just warn when close fails.

- tye        

  • Comment on Re^5: Scoping question - will file handle be closed? (close errors)

Replies are listed 'Best First'.
Re^6: Scoping question - will file handle be closed? (close errors)
by BrowserUk (Patriarch) on Jul 15, 2015 at 14:53 UTC
    If I have no logical recovery step for "incomplete data", then I will just warn when close fails.

    And that is really the point I'm arriving at; and your clarification of some of possibilities has taken me ever closer.

    Basically, there is never a logical recovery step; because the actually failure that gets reported by close may have happened hours ago; and because the range of possibilities is so diverse; and because it would be literally impossible to program a recovery for the vast majority of them.

    So, (IMO) the only logical step would be to modify close so that it automatically logged any errors.

    It ought be able to extract filenames from handles, ips/socknums from sockets etc. and generally produce a much more detailed account of the failure than user code could hope to do.

    And it would relieve the programmer from that burden. I guess I would like an autowarn rather than autodie pragma.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
    I'm with torvalds on this Agile (and TDD) debunked I told'em LLVM was the way to go. But did they listen!
      modify close so that it automatically logged any errors

      Yes, I think that would be better behavior, especially when close is called in a void context (like an "autowarn", like you said). The history of Perl internals is mostly to return success indicators but I think autodie is probably a better choice for most of them and autowarn is the best choice for close.

      Basically, there is never a logical recovery step; because the actually failure that gets reported by close may have happened hours ago; and because the range of possibilities is so diverse

      Not in my experience, no. The failures are all "incomplete data" and the likely mitigation step I already mentioned: Don't process that incomplete data. Additionally (as I already mentioned), don't mark the data source as "processed" if the protocol has such a step (which many protocols I use do).

      True, the recovery for the root cause is not something that I expect the software to try to solve, of course. The mitigation is usually just "close ... or die ...". Somewhere up the stack some eval takes care of trying to mark the item as failed or just not marking it as successful (and deleting the incomplete file if one was being written to).

      But my experience matches your expectation: that having close() autowarn would be better than having it autodie. Having close() autodie would more often abort further work when there was no good reason to.

      - tye