usr/src/uts/common/os/modctl.c
changeset 6065 b05c5c670963
parent 5331 3047ad28a67b
child 6855 18f1316f1bed
--- a/usr/src/uts/common/os/modctl.c	Fri Feb 22 08:41:57 2008 -0800
+++ b/usr/src/uts/common/os/modctl.c	Fri Feb 22 09:02:16 2008 -0800
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -2046,7 +2046,7 @@
 		goto err;
 
 	if ((ret = sdev_modctl_readdir(dir, &dirlist,
-	    &npaths, &npaths_alloc)) != 0) {
+	    &npaths, &npaths_alloc, 0)) != 0) {
 		ASSERT(dirlist == NULL);
 		goto err;
 	}
@@ -2093,6 +2093,42 @@
 	return (ret);
 }
 
+static int
+modctl_devemptydir(const char *udir, int udirlen, int *uempty)
+{
+	char	*dir;
+	int	ret;
+	char	**dirlist = NULL;
+	int	npaths;
+	int	npaths_alloc;
+	int	empty;
+
+	/*
+	 * copyin the /dev path including terminating null
+	 */
+	udirlen++;
+	if (udirlen <= 1 || udirlen > MAXPATHLEN)
+		return (EINVAL);
+	dir = kmem_zalloc(udirlen + 1, KM_SLEEP);
+	if ((ret = copyinstr(udir, dir, udirlen, NULL)) != 0)
+		goto err;
+
+	if ((ret = sdev_modctl_readdir(dir, &dirlist,
+	    &npaths, &npaths_alloc, 1)) != 0) {
+		goto err;
+	}
+
+	empty = npaths ? 0 : 1;
+	if (copyout(&empty, uempty, sizeof (empty)))
+		ret = EFAULT;
+
+err:
+	if (dirlist)
+		sdev_modctl_readdir_free(dirlist, npaths, npaths_alloc);
+	kmem_free(dir, udirlen + 1);
+	return (ret);
+}
+
 int
 modctl_moddevname(int subcmd, uintptr_t a1, uintptr_t a2)
 {
@@ -2347,6 +2383,11 @@
 		    (char *)a3, (int64_t *)a4);
 		break;
 
+	case MODDEVEMPTYDIR:	/* non-reconfiguring /dev emptydir */
+		error = modctl_devemptydir((const char *)a1, (size_t)a2,
+		    (int *)a3);
+		break;
+
 	case MODDEVNAME:
 		error = modctl_moddevname((int)a1, a2, a3);
 		break;