From fbb9921f8d29350fbc69e568f90cd66379502e9c Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Mon, 10 Mar 2014 00:23:15 -0700 Subject: * stream.c (pipe_close): Restructured the function a bit. Do not throw exceptions for normal process terminations, only for abnormal ones (terminated by a signal). Return the termination status instead of just t. * txr.1: Fixed the neglected documentation of the optional boolean argument of close-stream. Described the behaviors with regard to pipes in more detail. --- ChangeLog | 11 +++++++++++ stream.c | 43 ++++++++++++++++++++++--------------------- txr.1 | 19 ++++++++++++++++++- 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index ca9ae1ff..55fec2ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2014-03-10 Kaz Kylheku + + * stream.c (pipe_close): Restructured the function a bit. + Do not throw exceptions for normal process terminations, only for + abnormal ones (terminated by a signal). Return the termination + status instead of just t. + + * txr.1: Fixed the neglected documentation of the optional boolean + argument of close-stream. Described the behaviors with regard + to pipes in more detail. + 2014-03-09 Kaz Kylheku * match.c (v_trailer): Fix segfault. The code which diff --git a/stream.c b/stream.c index 912e6a80..7d073fc1 100644 --- a/stream.c +++ b/stream.c @@ -654,36 +654,37 @@ static val pipe_close(val stream, val throw_on_error) #endif h->f = 0; - if (status != 0 && throw_on_error) { - if (status < 0) { + if (status < 0) { + if (throw_on_error) uw_throwf(process_error_s, lit("unable to obtain status of command ~a: ~a/~s"), stream, num(errno), string_utf8(strerror(errno)), nao); + } else { #ifdef HAVE_SYS_WAIT + if (throw_on_error) { + if (WIFSIGNALED(status)) { + int termsig = WTERMSIG(status); + uw_throwf(process_error_s, lit("pipe ~a terminated by signal ~a"), + stream, num(termsig), nao); #ifndef WIFCONTINUED #define WIFCONTINUED(X) 0 #endif - } else if (WIFEXITED(status)) { + } else if (WIFSTOPPED(status) || WIFCONTINUED(status)) { + uw_throwf(process_error_s, + lit("processes of closed pipe ~a still running"), + stream, nao); + } + } + if (WIFEXITED(status)) { int exitstatus = WEXITSTATUS(status); - uw_throwf(process_error_s, lit("pipe ~a terminated with status ~a"), - stream, num(exitstatus), nao); - } else if (WIFSIGNALED(status)) { - int termsig = WTERMSIG(status); - uw_throwf(process_error_s, lit("pipe ~a terminated by signal ~a"), - stream, num(termsig), nao); - - } else if (WIFSTOPPED(status) || WIFCONTINUED(status)) { - uw_throwf(process_error_s, - lit("processes of closed pipe ~a still running"), - stream, nao); - } else { - uw_throwf(file_error_s, lit("strange status in when closing pipe ~a"), - stream, nao); -#endif + return num(exitstatus); } - } - - return status == 0 ? t : nil; +#else + if (status != 0 && throw_on_error) + uw_throwf(process_error_s, lit("closing pipe ~a failed"), stream, nao); +#endif + return status == 0 ? zero : nil; + } } return nil; } diff --git a/txr.1 b/txr.1 index f48f1360..87e0b624 100644 --- a/txr.1 +++ b/txr.1 @@ -11685,7 +11685,7 @@ finalized, so that further output is no longer possible. .TP Syntax: - (close-stream ) + (close-stream []) .TP Description: @@ -11697,6 +11697,23 @@ to operating system files or devices, will perform a close of the underlying file descriptor, and dissociate that descriptor from the stream. Any buffered data is flushed first. +The function returns a boolean true value if the close has occurred without +errors, otherwise nil. + +For most streams, "without errors" means that any buffered output data is +flushed successfully. + +For command and process pipes (see open-command and open-process), success also +means that the process terminates normally, with a successful error code, or an +unsuccessul one. An abnormal termination is considered an error, as +as is the inability to retrieve the termination status, as well as the situation +that the process continues running in spite of the close attempt. +Detecting these situations is platform specific. + +If the argument is specified, and isn't nil, then the +function throws an exception if an error occurs during the close operation +instead of returning nil. + .SS Functions get-line, get-char and get-byte .TP -- cgit v1.2.3