From a5ef87836c9dba23c187e361a70dddef87c03746 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku <kaz@kylheku.com> Date: Mon, 30 Oct 2017 06:56:03 -0700 Subject: streams: allow "b" flag on open-command. Currently, using "rb" in open-command reports an error on GNU/Linux, due to popen not liking the "b" mode. On Cygwin, the "b" flag is useful with popen. * stream.c (normalize_mode_no_bin): New function. (open_command): Use normalize_mode_no_bin instead of normalize_mode to strip out the binary flag. This doesn't happen on Cygwin, though. * stream.h (normalize_mode_no_bin): Declared. * share/txr/stdlib/getput.tl (command-get-buf): Since we are getting binary data, pass the "rb" mode to open-command, now that it works. (command-put-buf): Add "b" flag to mode passed to open-command. --- share/txr/stdlib/getput.tl | 4 ++-- stream.c | 18 +++++++++++++++++- stream.h | 1 + 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/share/txr/stdlib/getput.tl b/share/txr/stdlib/getput.tl index cb3e621e..53779b6c 100644 --- a/share/txr/stdlib/getput.tl +++ b/share/txr/stdlib/getput.tl @@ -107,9 +107,9 @@ (put-lines lines s))) (defun command-get-buf (cmd) - (with-stream (s (open-command cmd)) + (with-stream (s (open-command cmd "rb")) (sys:get-buf-common s))) (defun command-put-buf (cmd buf) - (with-stream (s (open-command cmd "w")) + (with-stream (s (open-command cmd "wb")) (put-buf buf 0 s))) diff --git a/stream.c b/stream.c index 2af67db2..9c4f40d5 100644 --- a/stream.c +++ b/stream.c @@ -1446,6 +1446,22 @@ val normalize_mode(struct stdio_mode *m, val mode_str, struct stdio_mode m_dfl) return format_mode(*m); } +val normalize_mode_no_bin(struct stdio_mode *m, val mode_str, struct stdio_mode m_dfl) +{ +#ifdef __CYGWIN__ + return normalize_mode(m, mode_str, m_dfl); +#else + *m = do_parse_mode(mode_str, m_dfl); + + if (m->malformed) + uw_throwf(file_error_s, lit("invalid file open mode ~a"), mode_str, nao); + + m->binary = 0; + + return format_mode(*m); +#endif +} + val set_mode_props(const struct stdio_mode m, val stream) { if (m.interactive || m.linebuf || m.unbuf || m.buforder != -1) { @@ -3857,7 +3873,7 @@ static void fds_restore(struct save_fds *fds) val open_command(val path, val mode_str) { struct stdio_mode m, m_r = stdio_mode_init_r; - val mode = normalize_mode(&m, mode_str, m_r); + val mode = normalize_mode_no_bin(&m, mode_str, m_r); int input = m.read != 0; struct save_fds sfds; FILE *f = 0; diff --git a/stream.h b/stream.h index 149e9ded..17b64aa1 100644 --- a/stream.h +++ b/stream.h @@ -143,6 +143,7 @@ void stream_mark_op(val stream); void stream_destroy_op(val stream); struct stdio_mode parse_mode(val mode_str, struct stdio_mode m_dfl); val normalize_mode(struct stdio_mode *m, val mode_str, struct stdio_mode m_dfl); +val normalize_mode_no_bin(struct stdio_mode *m, val mode_str, struct stdio_mode m_dfl); val set_mode_props(const struct stdio_mode m, val stream); val generic_get_line(val stream); val errno_to_string(val err); -- cgit v1.2.3