summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgreg@kroah.com <greg@kroah.com>2004-03-24 20:46:58 -0800
committerGreg KH <gregkh@suse.de>2005-04-26 21:35:11 -0700
commitdd64e26b0c88892b367f57c4c7a7484e35641c7c (patch)
tree6eb28d0faabe982a9746a9c4aa986547f68cf8f3
parent615ba3e82b2e49e06bbf9ad3e6a8ab6f0446ee26 (diff)
[PATCH] add /etc/dev.d/ support for udev add and remove events.
-rw-r--r--Makefile1
-rw-r--r--dev_d.c117
-rw-r--r--udev-add.c4
-rw-r--r--udev-remove.c1
-rw-r--r--udev.h1
5 files changed, 123 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index bd511a83ae..f20337bb54 100644
--- a/Makefile
+++ b/Makefile
@@ -209,6 +209,7 @@ OBJS = udev_lib.o \
udevdb.o \
namedev.o \
namedev_parse.o \
+ dev_d.o \
$(SYSFS) \
$(TDB)
diff --git a/dev_d.c b/dev_d.c
new file mode 100644
index 0000000000..36bee33bd9
--- /dev/null
+++ b/dev_d.c
@@ -0,0 +1,117 @@
+/*
+ * dev.d multipleer
+ *
+ * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 of the License.
+ *
+ * Based on the klibc version of hotplug written by:
+ * Author(s) Christian Borntraeger <cborntra@de.ibm.com>
+ * which was based on the shell script written by:
+ * Greg Kroah-Hartman <greg@kroah.com>
+ *
+ */
+
+/*
+ * This essentially emulates the following shell script logic in C:
+ DIR="/etc/dev.d"
+ export DEVNODE="whatever_dev_name_udev_just_gave"
+ for I in "${DIR}/$DEVNODE/"*.dev "${DIR}/$1/"*.dev "${DIR}/default/"*.dev ; do
+ if [ -f $I ]; then $I $1 ; fi
+ done
+ exit 1;
+ */
+
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include "udev.h"
+#include "udev_lib.h"
+#include "logging.h"
+
+#define HOTPLUGDIR "/etc/dev.d"
+#define COMMENT_PREFIX '#'
+
+static void run_program(char *name)
+{
+ pid_t pid;
+
+ dbg("running %s", name);
+
+ pid = fork();
+
+ if (pid < 0) {
+ perror("fork");
+ return;
+ }
+
+ if (pid > 0) {
+ wait(NULL);
+ return;
+ }
+
+ execv(name, main_argv);
+ exit(1);
+}
+
+static void execute_dir (char *dirname)
+{
+ DIR *directory;
+ struct dirent *entry;
+ char filename[256];
+
+ dbg("opening %s", dirname);
+ directory = opendir(dirname);
+ if (!directory)
+ return;
+
+ while ((entry = readdir(directory))) {
+ if (entry->d_name[0] == '\0')
+ break;
+ /* Don't run the files '.', '..', or hidden files,
+ * or files that start with a '#' */
+ if ((entry->d_name[0] == '.') ||
+ (entry->d_name[0] == COMMENT_PREFIX))
+ continue;
+
+ /* FIXME - need to use file_list_insert() here to run these in sorted order... */
+ snprintf(filename, sizeof(filename), "%s%s", dirname, entry->d_name);
+ filename[sizeof(filename)-1] = '\0';
+ run_program(filename);
+ }
+
+ closedir(directory);
+}
+
+/* runs files in these directories in order:
+ * name given by udev
+ * subsystem
+ * default
+ */
+void dev_d_send(struct udevice *dev, char *subsystem)
+{
+ char dirname[256];
+ char devnode[NAME_SIZE];
+
+ strfieldcpy(devnode, udev_root);
+ strfieldcat(devnode, dev->name);
+ setenv("DEVNODE", devnode, 1);
+
+ snprintf(dirname, sizeof(dirname), HOTPLUGDIR "/%s/", dev->name);
+ dirname[sizeof(dirname)-1] = '\0';
+ execute_dir(dirname);
+
+ snprintf(dirname, sizeof(dirname), HOTPLUGDIR "/%s/", subsystem);
+ dirname[sizeof(dirname)-1] = '\0';
+ execute_dir(dirname);
+
+ strcpy(dirname, HOTPLUGDIR "/default/");
+ execute_dir(dirname);
+}
+
diff --git a/udev-add.c b/udev-add.c
index 2bd16014f5..94a423dc6e 100644
--- a/udev-add.c
+++ b/udev-add.c
@@ -417,8 +417,10 @@ int udev_add_device(char *path, char *subsystem, int fake)
dbg("name='%s'", dev.name);
retval = create_node(&dev, fake);
- if ((retval == 0) && (!fake))
+ if ((retval == 0) && (!fake)) {
+ dev_d_send(&dev, subsystem);
sysbus_send_create(&dev, path);
+ }
exit:
if (class_dev)
diff --git a/udev-remove.c b/udev-remove.c
index d909713450..dc6fcfc331 100644
--- a/udev-remove.c
+++ b/udev-remove.c
@@ -150,6 +150,7 @@ int udev_remove_device(char *path, char *subsystem)
dbg("name is '%s'", dev.name);
udevdb_delete_dev(path);
+ dev_d_send(&dev, subsystem);
sysbus_send_remove(dev.name, path);
retval = delete_node(&dev);
diff --git a/udev.h b/udev.h
index 16a212cd2c..eb42edce10 100644
--- a/udev.h
+++ b/udev.h
@@ -65,6 +65,7 @@ extern int udev_add_device(char *path, char *subsystem, int fake);
extern int udev_remove_device(char *path, char *subsystem);
extern void udev_init_config(void);
extern int parse_get_pair(char **orig_string, char **left, char **right);
+extern void dev_d_send(struct udevice *dev, char *subsystem);
extern char **main_argv;
extern char **main_envp;