Mercurial > hg > xemacs-beta
diff src/lstream.c @ 207:e45d5e7c476e r20-4b2
Import from CVS: tag r20-4b2
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:03:52 +0200 |
parents | 3d6bfa290dbd |
children | 262b8bb4a523 |
line wrap: on
line diff
--- a/src/lstream.c Mon Aug 13 10:02:48 2007 +0200 +++ b/src/lstream.c Mon Aug 13 10:03:52 2007 +0200 @@ -714,13 +714,37 @@ if (lstr->flags & LSTREAM_FL_IS_OPEN) { - /* don't return here on error, or file descriptor leak will result. */ rc = Lstream_pseudo_close (lstr); + /* + * We used to return immediately if the closer method reported + * failure, leaving the stream open. But this is no good, for + * the following reasons. + * + * 1. The finalizer method used in GC makes no provision for + * failure, so we must not return without freeing buffer + * memory. + * + * 2. The closer method may have already freed some memory + * used for I/O in this stream. E.g. encoding_closer frees + * ENCODING_STREAM_DATA(stream)->runoff. If a writer method + * tries to use this buffer later, it will write into memory + * that may have been allocated elsewhere. Sometime later + * you will see a sign that says "Welcome to Crash City." + * + * 3. The closer can report failure if a flush fails in the + * other stream in a MULE encoding/decoding stream pair. + * The other stream in the pair is closed, but returning + * early leaves the current stream open. If we try to + * flush the current stream later, we will crash when the + * flusher notices that the other end stream is closed. + * + * So, we no longer abort the close if the closer method + * reports some kind of failure. We still report the failure + * to the caller. + */ if (lstr->imp->closer) - { - if ((lstr->imp->closer) (lstr) < 0) - return -1; - } + if ((lstr->imp->closer) (lstr) < 0) + rc = -1; } lstr->flags &= ~LSTREAM_FL_IS_OPEN;