The following reply was made to PR misc/175425; it has been noted by GNATS.
From: Yuri
To: bug-follo...@freebsd.org
Cc:
Subject: Re: misc/175425: kbdcontrol(1) printout about kbdmux isn't informative
Date: Sun, 20 Jan 2013 22:01:14 -0800
This is a multi-part message in MIME format.
--070002040502000102020100
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Patches:
* patch-ioctl-var-size.txt : implements variable size ioctl(2) data
parameter. This is used by the ioctl in the second patch. Userland
truss(1) is updated accordingly.
* patch-kbd-mux-contents.txt : implements new ioctl KBLSTKBD listing
contents of the kbd mux. Userland kbdcontrol is updated with the new
option -I using KBLSTKBD.
--070002040502000102020100
Content-Type: text/plain; charset=UTF-8;
name="patch-ioctl-var-size.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="patch-ioctl-var-size.txt"
Index: sys/kern/sys_generic.c
===
--- sys/kern/sys_generic.c (revision 245654)
+++ sys/kern/sys_generic.c (working copy)
@@ -640,6 +640,7 @@
int arg, error;
u_int size;
caddr_t data;
+ int vsize;
if (uap->com > 0x) {
printf(
@@ -654,18 +655,30 @@
* copied to/from the user's address space.
*/
size = IOCPARM_LEN(com);
+ /* Both IOC_VOID and IOC_INOUT mean that data has variable size */
+ if (com & IOC_VOID && com & IOC_INOUT) {
+ if (size != 0)
+ return (EINVAL);
+ /* first integer has the length of the memory */
+ error = copyin(uap->data, (caddr_t)&vsize, sizeof(vsize));
+ if (error)
+ return (error);
+ size = (u_int)vsize;
+ if (size > IOCPARM_MAX)
+ return (EINVAL);
+ }
if ((size > IOCPARM_MAX) ||
- ((com & (IOC_VOID | IOC_IN | IOC_OUT)) == 0) ||
+ ((com & IOC_DIRMASK) == 0) ||
#if defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
((com & IOC_OUT) && size == 0) ||
#else
((com & (IOC_IN | IOC_OUT)) && size == 0) ||
#endif
- ((com & IOC_VOID) && size > 0 && size != sizeof(int)))
+ (((com & IOC_DIRMASK) == IOC_VOID) && size > 0 && size !=
sizeof(int)))
return (ENOTTY);
if (size > 0) {
- if (com & IOC_VOID) {
+ if ((com & IOC_DIRMASK) == IOC_VOID) {
/* Integer argument. */
arg = (intptr_t)uap->data;
data = (void *)&arg;
Index: sys/netgraph/ng_eiface.c
===
--- sys/netgraph/ng_eiface.c (revision 245654)
+++ sys/netgraph/ng_eiface.c (working copy)
@@ -325,6 +325,15 @@
case IOC_INOUT:
str = "IORW";
break;
+ case IOC_OUT_EXT:
+ str = "IORE";
+ break;
+ case IOC_IN_EXT:
+ str = "IOWE";
+ break;
+ case IOC_INOUT_EXT:
+ str = "IORWE";
+ break;
default:
str = "IO??";
}
Index: sys/netgraph/ng_fec.c
===
--- sys/netgraph/ng_fec.c (revision 245654)
+++ sys/netgraph/ng_fec.c (working copy)
@@ -1167,6 +1167,15 @@
case IOC_INOUT:
str = "IORW";
break;
+ case IOC_OUT_EXT:
+ str = "IORE";
+ break;
+ case IOC_IN_EXT:
+ str = "IOWE";
+ break;
+ case IOC_INOUT_EXT:
+ str = "IORWE";
+ break;
default:
str = "IO??";
}
Index: sys/netgraph/ng_iface.c
===
--- sys/netgraph/ng_iface.c(revision 245654)
+++ sys/netgraph/ng_iface.c(working copy)
@@ -505,6 +505,15 @@
case IOC_INOUT:
str = "IORW";
break;
+ case IOC_OUT_EXT:
+ str = "IORE";
+ break;
+ case IOC_IN_EXT:
+ str = "IOWE";
+ break;
+ case IOC_INOUT_EXT:
+ str = "IORWE";
+ break;
default:
str = "IO??";
}
Index: sys/sys/ioccom.h
===
--- sys/sys/ioccom.h (revision 245654)
+++ sys/sys/ioccom.h (working copy)
@@ -48,8 +48,11 @@
#define IOC_VOID0x2000 /* no parameters */
#define IOC_OUT 0x4000 /* copy out parameters */
#define IOC_IN 0x8000 /* copy in parameters