diff --git a/byterun/io.c b/byterun/io.c index 77f308c8a..ac7ea76ba 100644 --- a/byterun/io.c +++ b/byterun/io.c @@ -420,14 +420,23 @@ CAMLexport intnat caml_input_scan_line(struct channel *channel) /* OCaml entry points for the I/O functions. Wrap struct channel * objects into a heap-allocated object. Perform locking and unlocking around the I/O operations. */ + /* FIXME CAMLexport, but not in io.h exported for Cash ? */ CAMLexport void caml_finalize_channel(value vchan) { struct channel * chan = Channel(vchan); if (--chan->refcount > 0) return; if (caml_channel_mutex_free != NULL) (*caml_channel_mutex_free)(chan); - unlink_channel(chan); - caml_stat_free(chan); + /* If the buffer is empty, remove the channel from the list of all + open channels and free it. Otherwise, keep it around so the Ocaml + [at_exit] function gets a chance to flush it. + We would want to simply flush the channel now, but flushing can + raise exceptions, which is forbidden in a finalization function. + */ + if (chan->curr == chan->buff){ + unlink_channel(chan); + caml_stat_free(chan); + } } static int compare_channel(value vchan1, value vchan2)