From owner-svn-src-all@FreeBSD.ORG Mon Oct 27 17:28:46 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 681EBCA6; Mon, 27 Oct 2014 17:28:46 +0000 (UTC) Received: from mail109.syd.optusnet.com.au (mail109.syd.optusnet.com.au [211.29.132.80]) by mx1.freebsd.org (Postfix) with ESMTP id 2BC987F8; Mon, 27 Oct 2014 17:28:45 +0000 (UTC) Received: from c122-106-147-133.carlnfd1.nsw.optusnet.com.au (c122-106-147-133.carlnfd1.nsw.optusnet.com.au [122.106.147.133]) by mail109.syd.optusnet.com.au (Postfix) with ESMTPS id E29C7D62048; Tue, 28 Oct 2014 04:28:37 +1100 (AEDT) Date: Tue, 28 Oct 2014 04:28:37 +1100 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Konstantin Belousov Subject: Re: svn commit: r273129 - head/sys/kern In-Reply-To: <201410151238.s9FCcRMe018200@svn.freebsd.org> Message-ID: <20141028040935.M3114@besplex.bde.org> References: <201410151238.s9FCcRMe018200@svn.freebsd.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.1 cv=BdjhjNd2 c=1 sm=1 tr=0 a=7NqvjVvQucbO2RlWB8PEog==:117 a=PO7r1zJSAAAA:8 a=kj9zAlcOel0A:10 a=JzwRw_2MAAAA:8 a=wx-8-68_qoafIrUy0MQA:9 a=CjuIK1q_8ugA:10 Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 27 Oct 2014 17:28:46 -0000 On Wed, 15 Oct 2014, Konstantin Belousov wrote: > Log: > Implement FIODTYPE for master ptys. > > Requested and reviewed by: bde > Sponsored by: The FreeBSD Foundation > MFC after: 1 week Thanks. This allows dd to work on ptys again. dd has the following bad code: % static void % getfdtype(IO *io) % { % struct stat sb; % int type; % % if (fstat(io->fd, &sb) == -1) % err(1, "%s", io->name); FIODTYPE should only be used as a hint, but dd makes its non-support fatal in some cases. Even fstat() failure for determining the hint shouldn't be fatal. % if (S_ISREG(sb.st_mode)) % io->flags |= ISTRUNC; % if (S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) { % if (ioctl(io->fd, FIODTYPE, &type) == -1) { % err(1, "%s", io->name); % } else { dd only uses the dtype hint for devices. Otherwise, it uses defaults. It might as well use the defaults for devices that don't support dtype too. % if (type & D_TAPE) % io->flags |= ISTAPE; % else if (type & (D_DISK | D_MEM)) % io->flags |= ISSEEK; % if (S_ISCHR(sb.st_mode) && (type & D_TAPE) == 0) % io->flags |= ISCHR; % } % return; % } % errno = 0; % if (lseek(io->fd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE) % io->flags |= ISPIPE; % else % io->flags |= ISSEEK; % } Not only the dtype check is bad. dd still has to guess about seekability, and does this not very well. Guessing is not needed for pipes, but dd guesses for them. Pipes are not seekable, but the converse is false. Tapes ar character devices, but ISCHR is not set for them. I use the following fixes (not complete -- at least the spelling change for ISSEEK is mostly in other files). @diff -u2 dd.c~ dd.c @--- dd.c~ Wed Apr 7 20:20:48 2004 @+++ dd.c Wed Apr 7 20:20:49 2004 @@@ -247,21 +245,18 @@ @ io->flags |= ISTRUNC; @ if (S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) { @- if (ioctl(io->fd, FIODTYPE, &type) == -1) { @+ if (ioctl(io->fd, FIODTYPE, &type) == -1) @ err(1, "%s", io->name); @- } else { @+ else { @ if (type & D_TAPE) @ io->flags |= ISTAPE; @ else if (type & (D_DISK | D_MEM)) @- io->flags |= ISSEEK; @- if (S_ISCHR(sb.st_mode) && (type & D_TAPE) == 0) @+ io->flags |= ISSEEKABLE; @+ if (S_ISCHR(sb.st_mode)) @ io->flags |= ISCHR; @ } @- return; @- } @- errno = 0; @- if (lseek(io->fd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE) @- io->flags |= ISPIPE; @- else @- io->flags |= ISSEEK; @+ } else if (lseek(io->fd, (off_t)0, SEEK_CUR) == 0) @+ io->flags |= ISSEEKABLE; @+ else if (errno == ESPIPE) @+ io->flags |= ISPIPE; /* XXX fixed in 4.4BSD */ @ } @ Bruce