summaryrefslogtreecommitdiffstats
path: root/gzio.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-06-21 07:28:53 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-06-21 07:28:53 -0700
commitf7942e319816ddff862017112aadc3f14fb73e81 (patch)
treea849aecf81b71ce8d7af46437f23b6797484950c /gzio.c
parent8446eac7ee6ecc8b80b0715745b5fd0d56948adc (diff)
downloadtxr-f7942e319816ddff862017112aadc3f14fb73e81.tar.gz
txr-f7942e319816ddff862017112aadc3f14fb73e81.tar.bz2
txr-f7942e319816ddff862017112aadc3f14fb73e81.zip
bugfix: missing gzip support in open-command.
* stream.c (pipe_close_status_helper): New function, factored out of pipe_close and used by it, and also by gzio_close. (pipe_close): Call pipe_close, which now contains the classification of process wait status codes. (open_fileno): Now takes optional pid argument. If this specified, then make_pipevp_stream is used. (open_subprocess): Use the open_fileno function, rather than fopen. This simplifies things too, except that we have to catch exception. Pass pid to the newly added parameter of open_fileno so that we obtain a proper pipe stream that will wait for the process to terminate when closed. (mkstemp_wrap): Pass nil for pid argument of open_fileno. (stream_init): Update registration of open-fileno. * gzio.c (struct gzio_handle): New member, pid. (gzio_close): If there is a nonzero pid, wait for the process to terminate. (make_gzio_stream): Initialize h->pid to zero. (make_gzio_pipe_stream): New function. * parser.c (lino_fdopen): Pass nil for pid argument of open_fileno. * gzio.h (make_gzio_pipe_stream): Declared. * tests/018/gzip.tl: New test.
Diffstat (limited to 'gzio.c')
-rw-r--r--gzio.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/gzio.c b/gzio.c
index 11991aa1..1edb04a4 100644
--- a/gzio.c
+++ b/gzio.c
@@ -35,6 +35,9 @@
#include <errno.h>
#include <zlib.h>
#include "config.h"
+#if HAVE_SYS_WAIT
+#include <sys/wait.h>
+#endif
#include "alloca.h"
#include "lib.h"
#include "stream.h"
@@ -57,6 +60,9 @@ struct gzio_handle {
val err, errstr;
char *buf;
int fd;
+#if HAVE_FORK_STUFF
+ pid_t pid;
+#endif
unsigned is_byte_oriented : 8;
unsigned is_output : 8;
};
@@ -283,7 +289,18 @@ static val gzio_close(val stream, val throw_on_error)
gzio_maybe_error(stream, lit("closing"));
return nil;
}
- return t;
+#if HAVE_FORK_STUFF
+ if (h->pid != 0)
+ {
+ int status = 0;
+ val self = lit("close-stream");
+ sig_save_enable;
+ while (waitpid(h->pid, &status, 0) == -1 && errno == EINTR)
+ ;
+ sig_restore_enable;
+ return pipe_close_status_helper(stream, throw_on_error, status, self);
+ }
+#endif
}
return nil;
}
@@ -561,5 +578,20 @@ val make_gzio_stream(gzFile f, int fd, val descr, int is_output)
h->buf = 0;
h->is_byte_oriented = 0;
h->is_output = is_output;
+#if HAVE_FORK_STUFF
+ h->pid = 0;
+#endif
+ return stream;
+}
+
+#if HAVE_FORK_STUFF
+
+val make_gzio_pipe_stream(gzFile f, int fd, val descr, int is_output, pid_t pid)
+{
+ val stream = make_gzio_stream(f, fd, descr, is_output);
+ struct gzio_handle *h = coerce(struct gzio_handle *, stream->co.handle);
+ h->pid = pid;
return stream;
}
+
+#endif