This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: DD converts LF -> CR / LF


-----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  <ebb9@byu.net>

	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             ebb9@byu.net
-----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/

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]