summaryrefslogtreecommitdiff
path: root/usr/src/lib/libdevinfo/devinfo_finddev.c
diff options
context:
space:
mode:
authorcth <none@none>2008-02-22 09:02:16 -0800
committercth <none@none>2008-02-22 09:02:16 -0800
commite37c6c376a1a22a828db3bb5ab40c86cb08f9c86 (patch)
tree4e26a9dc4fb51ae3c275b4a874d16228f566782f /usr/src/lib/libdevinfo/devinfo_finddev.c
parent931293416c5362b3d50b217b4390d1c88f7c7500 (diff)
downloadillumos-gate-e37c6c376a1a22a828db3bb5ab40c86cb08f9c86.tar.gz
6453345 devfs_getattr violates devfs locking rules
6527396 devfsadm -C taking hours after reconfiguration reboot 6661843 i_ddi_di_cache_invalidate() should only use taskq_dispatch on valid->invalid 6662461 reserved_links_exist() should be optimized
Diffstat (limited to 'usr/src/lib/libdevinfo/devinfo_finddev.c')
-rw-r--r--usr/src/lib/libdevinfo/devinfo_finddev.c61
1 files changed, 60 insertions, 1 deletions
diff --git a/usr/src/lib/libdevinfo/devinfo_finddev.c b/usr/src/lib/libdevinfo/devinfo_finddev.c
index 3dfb4467c9..eea252358f 100644
--- a/usr/src/lib/libdevinfo/devinfo_finddev.c
+++ b/usr/src/lib/libdevinfo/devinfo_finddev.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -256,6 +256,65 @@ finddev_readdir(const char *path, finddevhdl_t *handlep)
return (finddev_readdir_alt(path, handlep));
}
+/*
+ * Return true if a directory is empty
+ * Use the standard library readdir to determine if a directory is
+ * empty.
+ */
+static int
+finddev_emptydir_alt(const char *path)
+{
+ DIR *dir;
+ struct dirent *dp;
+
+ if ((dir = opendir(path)) == NULL)
+ return (ENOENT);
+
+ while ((dp = readdir(dir)) != NULL) {
+ if ((strcmp(dp->d_name, ".") == 0) ||
+ (strcmp(dp->d_name, "..") == 0))
+ continue;
+ (void) closedir(dir);
+ return (0); /* not empty */
+ }
+ (void) closedir(dir);
+ return (1); /* empty */
+}
+
+/*
+ * Use of the dev filesystem's private readdir does (not trigger
+ * the implicit device reconfiguration) to determine if a directory
+ * is empty.
+ *
+ * Note: only useable with paths mounted on an instance of the
+ * dev filesystem.
+ *
+ * Does not return the . and .. entries.
+ * Empty directories are returned as an zero-length list.
+ * ENOENT is returned as a NULL list pointer.
+ */
+static int
+finddev_emptydir_devfs(const char *path)
+{
+ int rv;
+ int empty;
+
+ rv = modctl(MODDEVEMPTYDIR, path, strlen(path), &empty);
+ if (rv == 0) {
+ return (empty);
+ }
+ return (0);
+}
+
+int
+finddev_emptydir(const char *path)
+{
+ if (GLOBAL_DEV_PATH(path)) {
+ return (finddev_emptydir_devfs(path));
+ }
+ return (finddev_emptydir_alt(path));
+}
+
void
finddev_close(finddevhdl_t arg)
{