>From 46b942713254075aaff46d1a4578fe7cc9c44be4 Mon Sep 17 00:00:00 2001 From: Assaf Gordon Date: Thu, 18 Oct 2018 16:16:53 -0600 Subject: [PATCH 1/2] sed: fix -b/--binary mode under windows/mingw Discussed in https://lists.gnu.org/r/sed-devel/2018-10/msg00001.html . * NEWS: Mention change. * bootstrap.conf: Add gnulib's binary-io module. * sed/sed.c (main): Set stdin/stdout to binary mode if needed. * sed/utils.c (ck_mkstemp): Explicitly set binary mode on file descriptor. It seems that on (non-cygwin) Windows the fdopen(3) call ignores the 'b' in the 'mode' argument - and the file was always opened in O_TEXT mode. Thus "--binary" was not working with "--inplace". --- NEWS | 3 +++ bootstrap.conf | 1 + sed/sed.c | 22 ++++++++++++++++++++-- sed/utils.c | 9 +++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index a03bb63..1464db8 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,9 @@ GNU sed NEWS -*- outline -*- and other write commands. Buffering can be disabled (as before) with "sed -u". + sed in non-cygwin windows environments (e.g. mingw) now properly handles + '\n' newlines in -b/--binary mode. + ** Bug fixes sed no longer accesses invalid memory (heap overflow) when given invalid diff --git a/bootstrap.conf b/bootstrap.conf index 5227ee2..692ddfc 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -24,6 +24,7 @@ gnulib_modules=' acl alloca stdalign +binary-io btowc c-ctype closeout diff --git a/sed/sed.c b/sed/sed.c index e814613..e588c56 100644 --- a/sed/sed.c +++ b/sed/sed.c @@ -24,6 +24,7 @@ #include #include #include +#include "binary-io.h" #include "getopt.h" #include "progname.h" #include "version.h" @@ -69,6 +70,11 @@ char *in_place_extension = NULL; char const *read_mode = "r"; char const *write_mode = "w"; +#if O_BINARY +/* Additional flag for binary mode on platforms with O_BINARY/O_TEXT. */ +bool binary_mode = false; +#endif + /* Do we need to be pedantically POSIX compliant? */ enum posixicity_types posixicity; @@ -148,8 +154,7 @@ Usage: %s [OPTION]... {script-only-if-no-other-script} [input-file]...\n\ #endif fprintf (out, _(" -i[SUFFIX], --in-place[=SUFFIX]\n\ edit files in place (makes backup if SUFFIX supplied)\n")); -#if defined WIN32 || defined _WIN32 || defined __CYGWIN__ \ - || defined MSDOS || defined __EMX__ +#if O_BINARY fprintf (out, _(" -b, --binary\n\ open files in binary mode (CR+LFs are not" \ " processed specially)\n")); @@ -310,6 +315,9 @@ main (int argc, char **argv) case 'b': read_mode = "rb"; write_mode = "wb"; +#if O_BINARY + binary_mode = true; +#endif break; case 'E': @@ -358,6 +366,16 @@ main (int argc, char **argv) } check_final_program (the_program); +#if O_BINARY + if (binary_mode) + { + if (set_binary_mode ( fileno (stdin), O_BINARY) == -1) + panic (_("failed to set binary mode on STDIN")); + if (set_binary_mode ( fileno (stdout), O_BINARY) == -1) + panic (_("failed to set binary mode on STDOUT")); + } +#endif + if (debug) debug_print_program (the_program); diff --git a/sed/utils.c b/sed/utils.c index 45ba678..6f847cd 100644 --- a/sed/utils.c +++ b/sed/utils.c @@ -26,12 +26,17 @@ #include #include +#include "binary-io.h" #include "unlocked-io.h" #include "utils.h" #include "progname.h" #include "fwriting.h" #include "xalloc.h" +#if O_BINARY +extern bool binary_mode; +#endif + /* Store information about files opened with ck_fopen so that error messages from ck_fread, ck_fwrite, etc. can print the name of the file that had the error */ @@ -182,6 +187,10 @@ ck_mkstemp (char **p_filename, const char *tmpdir, if (fd == -1) panic (_("couldn't open temporary file %s: %s"), template, strerror (errno)); +#if O_BINARY + if (binary_mode && (set_binary_mode ( fd, O_BINARY) == -1)) + panic (_("failed to set binary mode on '%s'"), template); +#endif *p_filename = template; FILE *fp = fdopen (fd, mode); -- 2.11.0