Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/bin/dd/dd.c,v rcsdiff: /ftp/cvs/cvsroot/src/bin/dd/dd.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.33 retrieving revision 1.34 diff -u -p -r1.33 -r1.34 --- src/bin/dd/dd.c 2003/09/14 19:20:19 1.33 +++ src/bin/dd/dd.c 2003/11/15 12:44:54 1.34 @@ -1,4 +1,4 @@ -/* $NetBSD: dd.c,v 1.33 2003/09/14 19:20:19 jschauma Exp $ */ +/* $NetBSD: dd.c,v 1.34 2003/11/15 12:44:54 dsainty Exp $ */ /*- * Copyright (c) 1991, 1993, 1994 @@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1991, 19 #if 0 static char sccsid[] = "@(#)dd.c 8.5 (Berkeley) 4/2/94"; #else -__RCSID("$NetBSD: dd.c,v 1.33 2003/09/14 19:20:19 jschauma Exp $"); +__RCSID("$NetBSD: dd.c,v 1.34 2003/11/15 12:44:54 dsainty Exp $"); #endif #endif /* not lint */ @@ -69,6 +69,7 @@ __RCSID("$NetBSD: dd.c,v 1.33 2003/09/14 static void dd_close(void); static void dd_in(void); static void getfdtype(IO *); +static int redup_clean_fd(int); static void setup(void); int main(int, char *[]); @@ -129,6 +130,9 @@ setup(void) if (in.fd < 0) err(EXIT_FAILURE, "%s", in.name); /* NOTREACHED */ + + /* Ensure in.fd is outside the stdio descriptor range */ + in.fd = redup_clean_fd(in.fd); } getfdtype(&in); @@ -159,6 +163,9 @@ setup(void) err(EXIT_FAILURE, "%s", out.name); /* NOTREACHED */ } + + /* Ensure out.fd is outside the stdio descriptor range */ + out.fd = redup_clean_fd(out.fd); } getfdtype(&out); @@ -249,6 +256,39 @@ getfdtype(IO *io) io->flags |= ISPIPE; /* XXX fixed in 4.4BSD */ } +/* + * Move the parameter file descriptor to a descriptor that is outside the + * stdio descriptor range, if necessary. This is required to avoid + * accidentally outputting completion or error messages into the + * output file that were intended for the tty. + */ +static int +redup_clean_fd(int fd) +{ + int newfd; + + if (fd != STDIN_FILENO && fd != STDOUT_FILENO && + fd != STDERR_FILENO) + /* File descriptor is ok, return immediately. */ + return fd; + + newfd = dup(fd); + if (newfd < 0) { + err(EXIT_FAILURE, "dup IO"); + /* NOTREACHED */ + } + + /* + * Recurse, to ensure that the new descriptor is clean. Don't + * free the old descriptor(s) until we've allocated a clean + * one. + */ + newfd = redup_clean_fd(newfd); + close(fd); + + return newfd; +} + static void dd_in(void) {