Hpda@hplabs.UUCP (HP Data Systems) (03/24/84)
Subject: dd(1) destroys file if input and output are the same. Index: /usr/src/bin/dd.c Submitter: Eric Wertz ( ..!ucbvax!hpda!eric, wertz@su-glacier.ARPA, eric@cmu-ee-faraday.ARPA ) Description: If file arguments given via "if=" and "of=" are the same, the file gets trashed. Programs like cp(1) usually catch this. Repeat-By: % cat foo This is a test file. % dd if=foo of=foo 0+0 records in 0+0 records out (oh dear, this doesn't look good...) % cat foo % (sure enough...) Fix: Add <sys/types.h> and <sys/stat.h> to the list of include files. and insert code with change bars... if(ibf < 0) { perror(ifile); exit(0); } | if (ifile && ofile) { | struct stat sbuf_in, sbuf_out; | | /* Can I stat ifile ? */ | if ( stat(ifile,&sbuf_in) == -1 ) { | perror(ifile); | exit(0); | } | /* If ofile exists, test to see if it's the same as ifile */ | if ( stat(ofile,&sbuf_out) == 0 && | sbuf_in.st_dev == sbuf_out.st_dev && | sbuf_in.st_ino == sbuf_out.st_ino ) { | fprintf(stderr,"dd: can't copy file onto itself\n"); | exit(0); | } | } if (ofile) obf = creat(ofile, 0666); Comments: This bug occurs in System III, System V, System V.2, and 4.[12] BSD. Of course, there's no way to prevent... % dd if=foo >foo ...from trashing a file.
dmmartindale@watcgl.UUCP (Dave Martindale) (03/26/84)
If you really want, you can wait until the input and output files are open and then do fstat on both of them and compare inumbers and devs. This would catch the case of dd if=foo >foo However, I'm going to do none of this. Dd is often used to copy data from raw devices, and sometimes it makes sense to have the input and output "files" the same if they are in fact not files but special files.
Hpda@hplabs.UUCP (HP Data Systems) (03/27/84)
[Sorry if anyone sees this post twice...] The case of "dd if=foo >foo" (which is equivalent to "cat foo >foo") is STILL a lose. CSH opens the output file (the result of the redirection) before the command is invoked - whether it be dd(1) or cat(1) or whatever(9). The result is a truncated file. However you do get a reprieve if noclobber is set. cat(1) chooses to tell you about your mistake, but you can still kiss your file goodbye. % cat foo beef % cat foo >foo cat: input foo is output % cat foo % (Where's the beef ?) About copying from "special" devices, point taken. I was lazy. The test should be made for S_IFCHR or S_IFBLK as in cat(1). Hack in the added tests with change bars (is this sufficient ?): if ( stat(ofile,&sbuf_out) == 0 && | sbuf_in.st_mode != S_IFCHR && | sbuf_in.st_mode != S_IFBLK && sbuf_in.st_dev == sbuf_out.st_dev && sbuf_in.st_ino == sbuf_out.st_ino ) {
ian@utcs.UUCP (Ian F. Darwin) (12/05/84)
Index: bin/dd.c 4.2BSD Description: The man page for dd(1) is nebulous about which CONV= parameters can be combined. Perhaps this is an attempt at emulating the etymological origins of the command name, but the humor is lost after you waste many hours rewriting tapes. Repeat-By: dd if=foo/bar of=/dev/rmt1 conv=ibm,block cat /dev/rmt1 You will see that the file on tape is in ASCII, indicating that the `block' option has caused the `ibm' option to be silently ignored. Fix: While `block' is new in 4.?BSD, some vagueness is present in V7, System V et. al, although it is unlikely to cause serious confusion except in 4.?BSD. To fix it, add the following paragraph to BUGS in the manual page: .PP Certain combinations of arguments to .I conv= are permitted. However, the .I block or .I unblock option cannot be combined with .IR ascii , .IR ebcdic "" or .IR ibm . Invalid combinations .I "silently ignore" all but the last mutually-exclusive keyword. -- Ian Darwin, Toronto {ihnp4|decvax}!utcs!ian