Module Name:    src
Committed By:   haad
Date:           Thu Aug 13 08:57:43 UTC 2009

Modified Files:
        src/sys/kern: sys_generic.c

Log Message:
Allow undescribed, direct ioctls as used by Unix. This capability was removed 
in BSD, presumably because nothing used it any more.
Third party system software written for Unix (like ZFS) requires this to work 
without significant modifications.

Ok supremeleader@


To generate a diff of this commit:
cvs rdiff -u -r1.123 -r1.124 src/sys/kern/sys_generic.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/sys_generic.c
diff -u src/sys/kern/sys_generic.c:1.123 src/sys/kern/sys_generic.c:1.124
--- src/sys/kern/sys_generic.c:1.123	Sun May 24 21:41:26 2009
+++ src/sys/kern/sys_generic.c	Thu Aug 13 08:57:43 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_generic.c,v 1.123 2009/05/24 21:41:26 ad Exp $	*/
+/*	$NetBSD: sys_generic.c,v 1.124 2009/08/13 08:57:43 haad Exp $	*/
 
 /*-
  * Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_generic.c,v 1.123 2009/05/24 21:41:26 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_generic.c,v 1.124 2009/08/13 08:57:43 haad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -565,31 +565,40 @@
 		goto out;
 	}
 	memp = NULL;
-	if (size > sizeof(stkbuf)) {
-		memp = kmem_alloc(size, KM_SLEEP);
-		data = memp;
-	} else
-		data = (void *)stkbuf;
-	if (com&IOC_IN) {
-		if (size) {
-			error = copyin(SCARG(uap, data), data, size);
-			if (error) {
-				if (memp)
-					kmem_free(memp, size);
-				goto out;
+	if ((com >> IOCPARM_SHIFT) == 0)  {
+		/* UNIX-style ioctl. */
+		data = SCARG(uap, data);
+	} else {
+		if (size > sizeof(stkbuf)) {
+			memp = kmem_alloc(size, KM_SLEEP);
+			data = memp;
+		} else {
+			data = (void *)stkbuf;
+		}
+		if (com&IOC_IN) {
+			if (size) {
+				error = copyin(SCARG(uap, data), data, size);
+				if (error) {
+					if (memp) {
+						kmem_free(memp, size);
+					}
+					goto out;
+				}
+				ktrgenio(SCARG(uap, fd), UIO_WRITE,
+				    SCARG(uap, data), size, 0);
+			} else {
+				*(void **)data = SCARG(uap, data);
 			}
-			ktrgenio(SCARG(uap, fd), UIO_WRITE, SCARG(uap, data),
-			    size, 0);
-		} else
+		} else if ((com&IOC_OUT) && size) {
+			/*
+			 * Zero the buffer so the user always
+			 * gets back something deterministic.
+			 */
+			memset(data, 0, size);
+		} else if (com&IOC_VOID) {
 			*(void **)data = SCARG(uap, data);
-	} else if ((com&IOC_OUT) && size)
-		/*
-		 * Zero the buffer so the user always
-		 * gets back something deterministic.
-		 */
-		memset(data, 0, size);
-	else if (com&IOC_VOID)
-		*(void **)data = SCARG(uap, data);
+		}
+	}
 
 	switch (com) {
 

Reply via email to