From owner-freebsd-arch@FreeBSD.ORG Tue Mar 2 20:21:40 2004 Return-Path: Delivered-To: freebsd-arch@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 38CA516A4CE for ; Tue, 2 Mar 2004 20:21:40 -0800 (PST) Received: from mailout2.pacific.net.au (mailout2.pacific.net.au [61.8.0.85]) by mx1.FreeBSD.org (Postfix) with ESMTP id 55EA243D31 for ; Tue, 2 Mar 2004 20:21:39 -0800 (PST) (envelope-from bde@zeta.org.au) Received: from mailproxy1.pacific.net.au (mailproxy1.pacific.net.au [61.8.0.86])i234LZnX029007; Wed, 3 Mar 2004 15:21:35 +1100 Received: from gamplex.bde.org (katana.zip.com.au [61.8.7.246]) i234LVsJ018459; Wed, 3 Mar 2004 15:21:33 +1100 Date: Wed, 3 Mar 2004 15:21:31 +1100 (EST) From: Bruce Evans X-X-Sender: bde@gamplex.bde.org To: "Jordan K. Hubbard" In-Reply-To: Message-ID: <20040303150647.Y5253@gamplex.bde.org> References: <1060DC2A-6C31-11D8-9000-000393BB9222@queasyweasel.com> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII cc: freebsd-arch@freebsd.org Subject: Re: Another conformance question... This time fputs(). X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Mar 2004 04:21:40 -0000 On Tue, 2 Mar 2004, Jordan K. Hubbard wrote: > It's also not clear to me why ENODEV is being returned, though I'm not > as inclined to blame isatty() since it appears to do the right thing: > > #include > #include > #include > > main() { > int fd, ret; > > fd = open("/dev/null", O_RDONLY); > ret = isatty(fd); > printf("ret = %d, errno = %d\n", ret, errno); > close(fd); > } > > Prints: ret = 0, errno = 25 This is because someone fixed /dev/null but not /dev/zero (I misread this in my previous reply). They are implemented in the same file, but only 1 has this bug. From null.c: %%% static struct cdevsw null_cdevsw = { .d_version = D_VERSION, .d_read = (d_read_t *)nullop, .d_write = null_write, .d_ioctl = null_ioctl, .d_name = "null", .d_maj = CDEV_MAJOR, }; static struct cdevsw zero_cdevsw = { .d_version = D_VERSION, .d_read = zero_read, .d_write = null_write, .d_name = "zero", .d_maj = CDEV_MAJOR, .d_flags = D_MMAP_ANON, }; %%% /dev/null has a special ioctl function "null_ioctl" which does the right thing without having to do anything (the existence of an ioctl function means that at least 1 ioctl is supported, so ENOTTY is correct for the unsupported ones). /dev/zero doesn't have any ioctl function, so it gets the default which is enodev() (which just returns ENODEV). This is almost correct -- ENODEV means that ioctls are completely unsupported, which is technically correct. However, it is surprising -- ENOTTY is the errno for most types of files including regular ones. > All isatty() does is call tcgetattr(), it doesn't do an > ioctl(...TIOCGETA...). Yes it does; see another reply. (tcgetattr() is tcsetattr(3), not a hypothetical tcsetattr(2) syscall. It happens to be implemented using an old ioctl.) Bruce