Eli Zaretskii wrote: > * lib/binary-io.h [O_BINARY]: Include io.h on all systems that > have non-zero O_BINARY.
Not needed, see the other mail. > (O_TEXT) [!O_BINARY]: Define if not defined. Why? You don't need it in the diffutils change. Additionally, gnulib's <fcntl.h> already does it. > (setmode) [!O_BINARY]: Define to do nothing and return O_BINARY. This part is basically OK, but lacks comments and a unit test. Here's a proposed patch. It passes all tests on glibc, mingw, MSVC, Cygwin. 2012-05-12 Bruno Haible <[email protected]> binary-io: Define setmode function. * lib/binary-io.h (setmode): Define if not defined by the platform. (SET_BINARY): Define in terms of setmode always. * tests/test-binary-io.c (main): Accept an argument, and test either setmode or SET_BINARY depending on the argument. * tests/test-binary-io.sh: Invoke test-binary-io twice, with an argument. Clean up also t-bin-out0.tmp. --- lib/binary-io.h.orig Sat May 12 23:23:39 2012 +++ lib/binary-io.h Sat May 12 22:23:04 2012 @@ -25,8 +25,9 @@ so we include it here first. */ #include <stdio.h> -/* SET_BINARY (fd); - changes the file descriptor fd to perform binary I/O. */ +/* setmode (fd, mode) + sets the binary/text I/O mode of file descriptor fd to the given mode + (must be O_BINARY or O_TEXT) and returns the previous mode. */ #if O_BINARY # if defined __EMX__ || defined __DJGPP__ || defined __CYGWIN__ # include <io.h> /* declares setmode() */ @@ -35,18 +36,21 @@ # undef fileno # define fileno _fileno # endif -# ifdef __DJGPP__ -# include <unistd.h> /* declares isatty() */ - /* Avoid putting stdin/stdout in binary mode if it is connected to - the console, because that would make it impossible for the user - to interrupt the program through Ctrl-C or Ctrl-Break. */ -# define SET_BINARY(fd) ((void) (!isatty (fd) ? (setmode (fd, O_BINARY), 0) : 0)) -# else -# define SET_BINARY(fd) ((void) setmode (fd, O_BINARY)) -# endif #else - /* On reasonable systems, binary I/O is the default. */ -# define SET_BINARY(fd) /* do nothing */ ((void) 0) + /* On reasonable systems, binary I/O is the only choice. */ +# define setmode(fd, mode) ((void) (fd), (void) (mode), O_BINARY) +#endif + +/* SET_BINARY (fd); + changes the file descriptor fd to perform binary I/O. */ +#ifdef __DJGPP__ +# include <unistd.h> /* declares isatty() */ + /* Avoid putting stdin/stdout in binary mode if it is connected to + the console, because that would make it impossible for the user + to interrupt the program through Ctrl-C or Ctrl-Break. */ +# define SET_BINARY(fd) ((void) (!isatty (fd) ? (setmode (fd, O_BINARY), 0) : 0)) +#else +# define SET_BINARY(fd) ((void) setmode (fd, O_BINARY)) #endif #endif /* _BINARY_H */ --- tests/test-binary-io.c.orig Sat May 12 23:23:39 2012 +++ tests/test-binary-io.c Sat May 12 22:27:33 2012 @@ -30,26 +30,40 @@ #include "macros.h" int -main () +main (int argc, char *argv[]) { /* Test the O_BINARY macro. */ { int fd = - open ("t-bin-out2.tmp", O_CREAT | O_TRUNC | O_RDWR | O_BINARY, 0600); + open ("t-bin-out0.tmp", O_CREAT | O_TRUNC | O_RDWR | O_BINARY, 0600); if (write (fd, "Hello\n", 6) < 0) exit (1); close (fd); } { struct stat statbuf; - if (stat ("t-bin-out2.tmp", &statbuf) < 0) + if (stat ("t-bin-out0.tmp", &statbuf) < 0) exit (1); ASSERT (statbuf.st_size == 6); } - /* Test the SET_BINARY macro. */ - SET_BINARY (1); - fputs ("Hello\n", stdout); + switch (argv[1][0]) + { + case '1': + /* Test the setmode() function. */ + setmode (1, O_BINARY); + fputs ("Hello\n", stdout); + break; + + case '2': + /* Test the SET_BINARY macro. */ + SET_BINARY (1); + fputs ("Hello\n", stdout); + break; + + default: + break; + } return 0; } --- tests/test-binary-io.sh.orig Sat May 12 23:23:39 2012 +++ tests/test-binary-io.sh Sat May 12 22:28:28 2012 @@ -3,9 +3,11 @@ tmpfiles="" trap 'rm -fr $tmpfiles' 1 2 3 15 -tmpfiles="$tmpfiles t-bin-out1.tmp t-bin-out2.tmp" -./test-binary-io${EXEEXT} > t-bin-out1.tmp || exit 1 -cmp t-bin-out1.tmp t-bin-out2.tmp > /dev/null || exit 1 +tmpfiles="$tmpfiles t-bin-out0.tmp t-bin-out1.tmp t-bin-out2.tmp" +./test-binary-io${EXEEXT} 1 > t-bin-out1.tmp || exit 1 +cmp t-bin-out0.tmp t-bin-out1.tmp > /dev/null || exit 1 +./test-binary-io${EXEEXT} 2 > t-bin-out2.tmp || exit 1 +cmp t-bin-out0.tmp t-bin-out2.tmp > /dev/null || exit 1 rm -fr $tmpfiles
