Set stdout to binary mode on Windows as needed master
authorDevan Lai <devan.lai@gmail.com>
Fri, 11 Oct 2019 03:16:01 +0000 (20:16 -0700)
committerUwe Hermann <uwe@hermann-uwe.de>
Sat, 9 Nov 2019 17:28:26 +0000 (18:28 +0100)
On Windows, stdout defaults to text mode, which attempts to perform
newline conversion such that if it sees a bare line feed (hex 0A),
it will insert a carriage return (hex 0D) before the line feed.

For textual output like normal annotation display or ASCII art, this is
desirable, but for binary output, this is likely to garble the output.

On Windows when using stdout as the output file destination or when
using the -B/--protocol-decoder-binary option, change the mode of stdout
to _O_BINARY to disable this newline conversion to ensure that the
binary output is faithfully delivered to stdout without modifications.

On all other platforms, setup_binary_stdout() is a no-op.

This fixes the original issue in bug #1427.

Further follow-up work might be needed to fix the reverse behavior that is
introduced by this change - now textual output sent to stdout on Windows
will only have Unix style line endings, rather than being converted to
Windows style line endings.

Makefile.am
main.c
output.c [new file with mode: 0644]
session.c
sigrok-cli.h

index 84f94b49afbad809ecb58de3b60dacd7766b7d47..d5cc780c49c2609a3da5737b9322dde9f5850206 100644 (file)
@@ -30,6 +30,7 @@ sigrok_cli_SOURCES = \
        device.c \
        session.c \
        input.c \
+       output.c \
        decode.c \
        sigrok-cli.h \
        parsers.c \
diff --git a/main.c b/main.c
index 829492f5704aa8b3b0f4d5f2a1c48a1d4b61709a..c2f39d84ff601fec51236cf261f723016bd2e552 100644 (file)
--- a/main.c
+++ b/main.c
@@ -242,6 +242,8 @@ int main(int argc, char **argv)
                if (opt_pd_binary) {
                        if (setup_pd_binary(opt_pd_binary) != 0)
                                goto done;
+                       if (setup_binary_stdout() != 0)
+                               goto done;
                        if (srd_pd_output_callback_add(srd_sess, SRD_OUTPUT_BINARY,
                                        show_pd_binary, NULL) != SRD_OK)
                                goto done;
diff --git a/output.c b/output.c
new file mode 100644 (file)
index 0000000..051ec8b
--- /dev/null
+++ b/output.c
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the sigrok-cli project.
+ *
+ * Copyright (C) 2019 Devan Lai <devan.lai@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+
+#ifdef _WIN32
+#include <io.h>
+#include <fcntl.h>
+#endif
+
+#include <glib.h>
+#include "sigrok-cli.h"
+
+/* Disable newline translation on stdout when outputting binary data. */
+int setup_binary_stdout(void)
+{
+#ifdef _WIN32
+       int oldmode = _setmode(_fileno(stdout), _O_BINARY);
+       if (oldmode == -1) {
+               g_critical("Failed to set binary stdout mode: errno=%d", errno);
+               return -1;
+       }
+#endif
+       return 0;
+}
index 3b3e962d3706ad46c28132f1fece9068d42ac405..f1542357ffc6a22605669cf5e1674bf3a3baf7c5 100644 (file)
--- a/session.c
+++ b/session.c
@@ -117,6 +117,7 @@ const struct sr_output *setup_output_format(const struct sr_dev_inst *sdi, FILE
                        *outfile = NULL;
                }
        } else {
+               setup_binary_stdout();
                *outfile = stdout;
        }
 
index 7def7412fd62cbc8dd3bb4885da4c02f30d46173..8d2669967e3d9ff2af56b6fbe75ddbbeed9ea924 100644 (file)
@@ -82,6 +82,9 @@ void run_session(void);
 /* input.c */
 void load_input_file(gboolean do_props);
 
+/* output.c */
+int setup_binary_stdout(void);
+
 /* decode.c */
 #ifdef HAVE_SRD
 int register_pds(gchar **all_pds, char *opt_pd_annotations);