Paul Eggert wrote: > > I would suggest to use a function > > > > int setmode (int fd, int o_mode); > > That would clash with the setmode function defined > in <unistd.h> in FreeBSD etc.
Thanks for the heads-up. Indeed MacOS X, FreeBSD, NetBSD, Minix all have the same kind of getmode/setmode functions. > 'set_binary_mode' would be OK Good. New proposal attached below. > but wouldn't it > be cleaner to use fcntl? The standard way to > set and clear O_* flags is fcntl, so shouldn't > it look like this? > > flags = fcntl (fd, F_GETFL); This can't be easily implemented on native Windows. In particular, there is no way to retrieve the O_APPEND flag. And the read/write flags are hard to retrieve without making system calls as well. 2012-05-12 Bruno Haible <[email protected]> binary-io: Define set_binary_mode function. * lib/binary-io.h (set_binary_mode): New function. (SET_BINARY): Define in terms of set_binary_mode. * tests/test-binary-io.c (main): Accept an argument, and test either set_binary_mode 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 Sun May 13 03:58:11 2012 +++ lib/binary-io.h Sun May 13 03:57:27 2012 @@ -25,28 +25,33 @@ so we include it here first. */ #include <stdio.h> -/* SET_BINARY (fd); - changes the file descriptor fd to perform binary I/O. */ +/* set_binary_mode (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() */ +# define set_binary_mode setmode # else -# define setmode _setmode +# define set_binary_mode _setmode # 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 set_binary_mode(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) ? (set_binary_mode (fd, O_BINARY), 0) : 0)) +#else +# define SET_BINARY(fd) ((void) set_binary_mode (fd, O_BINARY)) #endif #endif /* _BINARY_H */ --- tests/test-binary-io.c.orig Sun May 13 03:58:11 2012 +++ tests/test-binary-io.c Sun May 13 03:56:50 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 set_binary_mode() function. */ + set_binary_mode (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 Sun May 13 03:58:11 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
