Module Name:    othersrc
Committed By:   jmcneill
Date:           Wed Aug  3 00:06:00 UTC 2011

Modified Files:
        othersrc/external/bsd/udevfsd: udevfsd.c

Log Message:
Scan already attached devices at startup and post 'device-attach' events for
them to the hooks scripts.


To generate a diff of this commit:
cvs rdiff -u -r1.1.1.1 -r1.2 othersrc/external/bsd/udevfsd/udevfsd.c

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

Modified files:

Index: othersrc/external/bsd/udevfsd/udevfsd.c
diff -u othersrc/external/bsd/udevfsd/udevfsd.c:1.1.1.1 othersrc/external/bsd/udevfsd/udevfsd.c:1.2
--- othersrc/external/bsd/udevfsd/udevfsd.c:1.1.1.1	Tue Aug  2 23:19:26 2011
+++ othersrc/external/bsd/udevfsd/udevfsd.c	Wed Aug  3 00:06:00 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: udevfsd.c,v 1.1.1.1 2011/08/02 23:19:26 jmcneill Exp $ */
+/* $NetBSD: udevfsd.c,v 1.2 2011/08/03 00:06:00 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2011 Jared D. McNeill <jmcne...@invisible.ca>
@@ -35,7 +35,7 @@
 #include <sys/cdefs.h>
 __COPYRIGHT("@(#) Copyright (c) 2011\
 Jared D. McNeill <jmcne...@invisible.ca>. All rights reserved.");
-__RCSID("$NetBSD: udevfsd.c,v 1.1.1.1 2011/08/02 23:19:26 jmcneill Exp $");
+__RCSID("$NetBSD: udevfsd.c,v 1.2 2011/08/03 00:06:00 jmcneill Exp $");
 
 #include <sys/types.h>
 #include <sys/ioctl.h>
@@ -56,6 +56,9 @@
 static int drvctl_fd = -1;
 static const char *udevfsd_script = UDEVFSD_RUN_HOOKS;
 
+#define	UDEVFSD_ATTACH_EVENT	"device-attach"
+#define	UDEVFSD_DETACH_EVENT	"device-detach"
+
 static void
 udevfsd_exec(const char *path, const char *event, const char *device)
 {
@@ -129,6 +132,69 @@
 }
 
 static void
+udevfsd_probe(const char *device)
+{
+	struct devlistargs laa;
+	size_t len, children, n;
+	void *p;
+	int error;
+
+	assert(drvctl_fd != -1);
+
+	memset(&laa, 0, sizeof(laa));
+	if (device)
+		strlcpy(laa.l_devname, device, sizeof(laa.l_devname));
+
+	/* Get the child device count for this device */
+	error = ioctl(drvctl_fd, DRVLISTDEV, &laa);
+	if (error) {
+		syslog(LOG_ERR, "DRVLISTDEV failed: %m");
+		return;
+	}
+
+child_count_changed:
+	/* If this device has no children, return */
+	if (laa.l_children == 0)
+		return;
+
+	/* Allocate a buffer large enough to hold the child device names */
+	p = laa.l_childname;
+	children = laa.l_children;
+
+	len = children * sizeof(laa.l_childname[0]);
+	laa.l_childname = realloc(laa.l_childname, len);
+	if (laa.l_childname == NULL) {
+		syslog(LOG_ERR, "couldn't allocate %zu bytes", len);
+		laa.l_childname = p;
+		goto done;
+	}
+
+	/* Get a list of child devices */
+	error = ioctl(drvctl_fd, DRVLISTDEV, &laa);
+	if (error) {
+		syslog(LOG_ERR, "DRVLISTDEV failed: %m");
+		goto done;
+	}
+
+	/* If the child count changed between DRVLISTDEV calls, retry */
+	if (children != laa.l_children)
+		goto child_count_changed;
+
+	/*
+	 * For each child device, first post an attach event and
+	 * then scan each one for additional devices.
+	 */
+	for (n = 0; n < laa.l_children; n++)
+		udevfsd_eventhandler(UDEVFSD_ATTACH_EVENT, laa.l_childname[n]);
+	for (n = 0; n < laa.l_children; n++)
+		udevfsd_probe(laa.l_childname[n]);
+
+done:
+	free(laa.l_childname);
+	return;
+}
+
+static void
 usage(void)
 {
 	fprintf(stderr, "usage: %s [-f]\n", getprogname());
@@ -170,6 +236,10 @@
 			err(EXIT_FAILURE, "couldn't fork");
 		}
 	}
+
+	/* Look for devices that are already present */
+	udevfsd_probe(NULL);
+
 	udevfsd_eventloop();
 
 	return EXIT_SUCCESS;

Reply via email to