On 02/14/2017 05:08 PM, Paul Eggert wrote: > On 02/13/2017 12:20 PM, Eric Blake wrote: >> undossify_input causes more problems than it >> solves. We should trust fopen("r") to do the right thing, rather than >> reinventing it ourselves. > > Yes, that makes sense. Attached is a proposed patch to implement this. > It assumes the patch you already submitted for Bug#25707. > > This patch keeps the -U option, for MS-Windows users who want to > override fopen "-r"'s choice of binary vs text I/O. Perhaps that's too > conservative? It would be easy to turn -U into a no-op too.
For reference, here's the patch I applied to Cygwin when building grep-3.0; it didn't go as far as your patch in killing -u (so I like your patch better), but had the same net effect of keeping -U as a way to force binary behavior, while using fcntl() to learn (after-the-fact) whether our force-to-binary was a no-op, and only doing undossify stuff if we turned a text-mode into binary-mode: --- origsrc/grep-3.0/src/dosbuf.c 2017-01-01 05:34:33.000000000 -0600 +++ src/grep-3.0/src/dosbuf.c 2017-02-14 09:50:08.701835000 -0600 @@ -48,6 +48,7 @@ static struct dos_map *dos_pos_map; static int dos_pos_map_size = 0; static int dos_pos_map_used = 0; static int inp_map_idx = 0, out_map_idx = 1; +static int mode_forced; /* Set default DOS file type to binary. */ static void @@ -95,7 +96,7 @@ guess_type (char *buf, size_t buflen) static size_t undossify_input (char *buf, size_t buflen) { - if (! O_BINARY) + if (! O_BINARY || ! mode_forced) return buflen; size_t bytes_left = 0; @@ -186,7 +187,7 @@ undossify_input (char *buf, size_t bufle static off_t dossified_pos (off_t byteno) { - if (! O_BINARY) + if (! O_BINARY || ! mode_forced) return byteno; off_t pos_lo; --- origsrc/grep-3.0/src/grep.c 2017-02-08 19:37:33.000000000 -0600 +++ src/grep-3.0/src/grep.c 2017-02-14 09:58:11.134855800 -0600 @@ -1860,10 +1860,17 @@ grepdesc (int desc, bool command_line) goto closeout; } - /* Set input to binary mode. Pipes are simulated with files - on DOS, so this includes the case of "foo | grep bar". */ + /* Force input to binary mode, while remembering if it was originally + text. Options -u and -U only matter on text mounts. */ + mode_forced = 0; if (O_BINARY && !isatty (desc)) - set_binary_mode (desc, O_BINARY); + { + if (fcntl (desc, F_GETFL) & O_TEXT) + { + set_binary_mode (desc, O_BINARY); + mode_forced = 1; + } + } count = grep (desc, &st, &ineof); if (count_matches) @@ -2586,7 +2593,7 @@ main (int argc, char **argv) break; case 'f': - fp = STREQ (optarg, "-") ? stdin : fopen (optarg, O_TEXT ? "rt" : "r"); + fp = STREQ (optarg, "-") ? stdin : fopen (optarg, "r"); if (!fp) die (EXIT_TROUBLE, errno, "%s", optarg); oldcc = keycc; -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature