Another conformance question... This time fputs().
Bruce Evans
bde at zeta.org.au
Tue Mar 2 20:21:40 PST 2004
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 <stdio.h>
> #include <fcntl.h>
> #include <errno.h>
>
> 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
More information about the freebsd-arch
mailing list