From a2848bd240339bb07b647bb82bc7a4043e977d3f Mon Sep 17 00:00:00 2001 From: gnn Date: Wed, 11 Jan 2012 15:00:16 +0000 Subject: Fix for PR 138526. Add the ability for /dev/null and /dev/zero to accept being set into non blocking mode via fcntl(). This brings the code into compliance with IEEE Std 1003.1-2001 as referenced in another PR, 94729. Reviewed by: jhb MFC after: 1 week --- sys/dev/null/null.c | 48 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) (limited to 'sys/dev/null/null.c') diff --git a/sys/dev/null/null.c b/sys/dev/null/null.c index b053d5d..0fe46fa 100644 --- a/sys/dev/null/null.c +++ b/sys/dev/null/null.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -49,6 +50,7 @@ static struct cdev *zero_dev; static d_write_t null_write; static d_ioctl_t null_ioctl; +static d_ioctl_t zero_ioctl; static d_read_t zero_read; static struct cdevsw null_cdevsw = { @@ -63,6 +65,7 @@ static struct cdevsw zero_cdevsw = { .d_version = D_VERSION, .d_read = zero_read, .d_write = null_write, + .d_ioctl = zero_ioctl, .d_name = "zero", .d_flags = D_MMAP_ANON, }; @@ -82,17 +85,50 @@ null_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t data __unused, int flags __unused, struct thread *td) { int error; + error = 0; - if (cmd != DIOCSKERNELDUMP) - return (ENOIOCTL); - error = priv_check(td, PRIV_SETDUMPER); - if (error) - return (error); - return (set_dumper(NULL)); + switch (cmd) { + case DIOCSKERNELDUMP: + error = priv_check(td, PRIV_SETDUMPER); + if (error == 0) + error = set_dumper(NULL); + break; + case FIONBIO: + break; + case FIOASYNC: + if (*(int *)data != 0) + error = EINVAL; + break; + default: + error = ENOIOCTL; + } + return (error); } /* ARGSUSED */ static int +zero_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t data __unused, + int flags __unused, struct thread *td) +{ + int error; + error = 0; + + switch (cmd) { + case FIONBIO: + break; + case FIOASYNC: + if (*(int *)data != 0) + error = EINVAL; + break; + default: + error = ENOIOCTL; + } + return (error); +} + + +/* ARGSUSED */ +static int zero_read(struct cdev *dev __unused, struct uio *uio, int flags __unused) { void *zbuf; -- cgit v1.1