chiark / gitweb /
[PATCH] add /etc/dev.d/ support for udev add and remove events.
authorgreg@kroah.com <greg@kroah.com>
Thu, 25 Mar 2004 04:46:58 +0000 (20:46 -0800)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 04:35:11 +0000 (21:35 -0700)
Makefile
dev_d.c [new file with mode: 0644]
udev-add.c
udev-remove.c
udev.h

index bd511a8..f20337b 100644 (file)
--- 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 (file)
index 0000000..36bee33
--- /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);
+}
+
index 2bd1601..94a423d 100644 (file)
@@ -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)
index d909713..dc6fcfc 100644 (file)
@@ -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 16a212c..eb42edc 100644 (file)
--- 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;