summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-03-10 00:23:15 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-03-10 00:23:15 -0700
commitfbb9921f8d29350fbc69e568f90cd66379502e9c (patch)
tree9794e7b902cb9c7be7f4d58a7a61e15d1f4362e5
parent110e155595d397e5328f6f7af33e430d1a361bbc (diff)
downloadtxr-fbb9921f8d29350fbc69e568f90cd66379502e9c.tar.gz
txr-fbb9921f8d29350fbc69e568f90cd66379502e9c.tar.bz2
txr-fbb9921f8d29350fbc69e568f90cd66379502e9c.zip
* 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.
-rw-r--r--ChangeLog11
-rw-r--r--stream.c43
-rw-r--r--txr.119
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 <kaz@kylheku.com>
+
+ * 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 <kaz@kylheku.com>
* 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 <stream>)
+ (close-stream <stream> [<throw-on-error-p>])
.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 <throw-on-error-p> 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