diff options
author | gnn <gnn@FreeBSD.org> | 2012-01-11 15:00:16 +0000 |
---|---|---|
committer | gnn <gnn@FreeBSD.org> | 2012-01-11 15:00:16 +0000 |
commit | a2848bd240339bb07b647bb82bc7a4043e977d3f (patch) | |
tree | 8edcc6e286e9c9f66173cbc26ddee81f7bac2758 /sys/dev/null/null.c | |
parent | 9ecb48ad84eea94108927842f4ce71b06ac25407 (diff) | |
download | FreeBSD-src-a2848bd240339bb07b647bb82bc7a4043e977d3f.zip FreeBSD-src-a2848bd240339bb07b647bb82bc7a4043e977d3f.tar.gz |
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
Diffstat (limited to 'sys/dev/null/null.c')
-rw-r--r-- | sys/dev/null/null.c | 48 |
1 files changed, 42 insertions, 6 deletions
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 <sys/priv.h> #include <sys/disk.h> #include <sys/bus.h> +#include <sys/filio.h> #include <machine/bus.h> #include <machine/vmparam.h> @@ -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; |