svn commit: r273129 - head/sys/kern
Bruce Evans
brde at optusnet.com.au
Mon Oct 27 17:28:46 UTC 2014
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
More information about the svn-src-head
mailing list