-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 According to Brian Dessent on 5/6/2005 2:06 AM: > Sebastian Schuberth wrote: > >>my mounts are all text mode, i.e. the "Default Text File >>Type" is "DOS". Nevertheless, shouldn't >> >>dd if=test_unix.txt of=text.txt >> >>create an exact copy of "test_unix.txt"? It seems DD doesn't open the >>file in binary mode >> >>I already tried several of the "conv=" arguments to DD with no luck. > > > Yeah, that does seem a bit broken. You can solve that with something > like the following: > > --- dd.c.orig 2005-05-06 01:03:01.125000000 -0700 > +++ dd.c 2005-05-06 01:00:07.265625000 -0700 > @@ -136,8 +136,12 @@ > static int conversions_mask = 0; > > /* Open flags for the input and output files. */ > -static int input_flags = 0; > -static int output_flags = 0; > +#ifndef O_BINARY > +#define O_BINARY 0 > +#endif > + > +static int input_flags = O_BINARY; > +static int output_flags = O_BINARY; > > /* Status flags for what is printed to stderr. */ > static int status_flags = 0; > > ----- > > It would be up to the coreutils maintainer to decide what to do about > this. It could be handled in a number of ways. > > Brian >
Predefining O_BINARY as the default input_flags and output_flags is a stopgap measure. While it is fine for other programs, such as od, to always open in binary mode, I think that dd should be more flexible as it already can specify so many other fine-tuning details. It would be nicer if iflag= and oflag= supported text and binary as supported flags (no-ops on platforms where there is no difference). Or maybe introduce new keywords imode= and omode=, since it is not clear whether fcntl(fd, F_SETFL, O_BINARY) will work, or whether modes must be set with SET_MODE(fd, O_BINARY) from system.h. Also, since O_BINARY and O_TEXT are mutually exclusive (when O_BINARY is defined, you can't set the mode to O_BINARY|O_TEXT), it would add a layer of complication to parsing iflags to ensure that an incompatible mode is not chosen. There is still the question on cygwin whether an unspecified text/binary mode should always default to binary, or should default to the underlying default for that particular mount. Meanwhile, I noticed that cygwin permits open("foo", O_RDWR | O_BINARY | O_TEXT), although I don't know which of the two modes it chose; I think it should instead return EINVAL like setmode(fd, O_BINARY | O_TEXT) does. Here's a cygwin-local patch (against the 5.3.0 tarball) that adds imode= and omode=, and which defaults to binary mode if unspecified. I'll try to release coreutils-5.3.0-6 to cygwin in the next week, including this fix and a `mkdir -p' fix. I'm cc'ing bug-coreutils in case it is decided to be a good idea to use as a starting point for folding in upstream (of course, it would also need NEWS and coreutils.texi documentation, and updated to apply against CVS HEAD). 2005-05-06 Eric Blake <[EMAIL PROTECTED]> Add imode= and omode= to dd: * src/dd.c (input_mode, output_mode, modes, set_fd_mode): New variables and method. (usage) [O_BINARY]: Document new args. (scanargs) [O_BINARY]: Parse new imode and omode args. (main): Set file mode. - -- Life is short - so eat dessert first! Eric Blake [EMAIL PROTECTED] -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFCe3DJ84KuGfSFAYARApZbAKCaEJJqwJ9I2UCXy5HarHMJXKHqSACdFNyN XurPMrVxdRcFj+cqepzaSnw= =m/hB -----END PGP SIGNATURE-----
--- ../coreutils-5.3.0.orig/src/dd.c 2004-11-22 07:14:44.000000000 -0700 +++ src/dd.c 2005-05-06 07:17:15.073875000 -0600 @@ -139,6 +139,10 @@ static int input_flags = 0; static int output_flags = 0; +/* Mode flags for the input and output files. */ +static int input_mode = 0; +static int output_mode = 0; + /* Status flags for what is printed to stderr. */ static int status_flags = 0; @@ -237,6 +241,16 @@ {"", 0} }; +#if O_BINARY +static struct symbol_value const modes[] = +{ + {"binary", O_BINARY}, + {"text", O_TEXT}, + {"", 0} +}; +#endif + + /* Status, for status="...". */ static struct symbol_value const statuses[] = { @@ -380,9 +394,23 @@ fputs (_("\ if=FILE read from FILE instead of stdin\n\ iflag=FLAGS read as per the comma separated symbol list\n\ +"), stdout); +#if O_BINARY + fputs (_("\ + imode=MODE open input in MODE\n\ +"), stdout); +#endif + fputs (_("\ obs=BYTES write BYTES bytes at a time\n\ of=FILE write to FILE instead of stdout\n\ oflag=FLAGS write as per the comma separated symbol list\n\ +"), stdout); +#if O_BINARY + fputs (_("\ + omode=MODE open output in MODE\n\ +"), stdout); +#endif + fputs (_("\ seek=BLOCKS skip BLOCKS obs-sized blocks at start of output\n\ skip=BLOCKS skip BLOCKS ibs-sized blocks at start of input\n\ status=noxfer suppress transfer statistics\n\ @@ -435,6 +463,15 @@ if (O_NOCTTY) fputs (_(" noctty do not assign controlling terminal from file\n"), stdout); +#if O_BINARY + fputs (_("\ +\n\ +Each MODE symbol may be one of:\n\ +\n\ + binary binary mode (default if unspecified)\n\ + text text mode\n\ +"), stdout); +#endif fputs (_("\ \n\ Sending a SIGUSR1 signal to a running `dd' process makes it\n\ @@ -750,6 +787,14 @@ else if (STREQ (name, "oflag")) output_flags |= parse_symbols (val, flags, N_("invalid output flag: %s")); +#if O_BINARY + else if (STREQ (name, "imode")) + input_mode |= parse_symbols (val, modes, + N_("invalid input mode: %s")); + else if (STREQ (name, "omode")) + output_mode |= parse_symbols (val, modes, + N_("invalid output mode: %s")); +#endif else if (STREQ (name, "status")) status_flags |= parse_symbols (val, statuses, N_("invalid status flag: %s")); @@ -1189,6 +1234,22 @@ } } +/* Set the file descriptor FD to mode MODE if it is valid. The file's name + is NAME. */ + +#if O_BINARY +static void +set_fd_mode (int fd, int mode, char const *name) +{ + if (!mode && !isatty(fd)) + mode = O_BINARY; + if (mode && SET_MODE (fd, mode) < 0) + error (EXIT_FAILURE, errno, _("setting mode for %s"), quote (name)); +} +#else +# define set_fd_mode (_f, _m, _n) (void)0 +#endif + /* The main loop. */ static int @@ -1470,10 +1531,12 @@ { input_file = _("standard input"); set_fd_flags (STDIN_FILENO, input_flags, input_file); + set_fd_mode (STDIN_FILENO, input_mode, input_file); } else { - if (open_fd (STDIN_FILENO, input_file, O_RDONLY | input_flags, 0) < 0) + if (open_fd (STDIN_FILENO, input_file, + O_RDONLY | input_flags | input_mode, 0) < 0) error (EXIT_FAILURE, errno, _("opening %s"), quote (input_file)); } @@ -1486,12 +1549,13 @@ { output_file = _("standard output"); set_fd_flags (STDOUT_FILENO, output_flags, output_file); + set_fd_mode (STDOUT_FILENO, output_mode, output_file); } else { mode_t perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; int opts - = (output_flags + = (output_flags | output_mode | (conversions_mask & C_NOCREAT ? 0 : O_CREAT) | (conversions_mask & C_EXCL ? O_EXCL : 0) | (seek_records || (conversions_mask & C_NOTRUNC) ? 0 : O_TRUNC));
-- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/