From: Kay Sievers <kay.sievers@vrfy.org>
To: linux-hotplug@vger.kernel.org
Subject: Re: [PATCH] dev_d.c file sorting and cleanup
Date: Thu, 25 Mar 2004 13:43:50 +0000 [thread overview]
Message-ID: <20040325134350.GA30182@vrfy.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 529 bytes --]
On Thu, Mar 25, 2004 at 02:52:13AM +0100, Kay Sievers wrote:
> Please have look if it still works for you, I only did a very quick
> test.
Here is a unified version, with all the functions moved to udev_lib.c.
We have a generic function now, to call a given fnct(char *) for every
file ending with a specific suffix, sorted in lexical order. We use it
to execute the dev.d/ files and read our rules.d/ files. The binary
should be a bit smaller now.
I've also changed it, to not do the dev.d/ exec for net devices.
thanks,
Kay
[-- Attachment #2: 02-dev.d.patch --]
[-- Type: text/plain, Size: 11847 bytes --]
===== dev_d.c 1.2 vs edited =====
--- 1.2/dev_d.c Thu Mar 25 00:31:03 2004
+++ edited/dev_d.c Thu Mar 25 14:38:22 2004
@@ -1,30 +1,23 @@
/*
- * dev.d multipleer
+ * dev_d.c - dev.d/ multiplexer
*
* 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;
+ * 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>
@@ -35,73 +28,38 @@
#include "udev_lib.h"
#include "logging.h"
-#define HOTPLUGDIR "/etc/dev.d"
-#define SUFFIX ".dev"
-#define COMMENT_PREFIX '#'
+#define DEVD_DIR "/etc/dev.d/"
+#define DEVD_SUFFIX ".dev"
-static void run_program(char *name)
+static int run_program(char *name)
{
pid_t pid;
dbg("running %s", name);
pid = fork();
-
- if (pid < 0) {
- perror("fork");
- return;
- }
-
- if (pid > 0) {
+ switch (pid) {
+ case 0:
+ /* child */
+ execv(name, main_argv);
+ dbg("exec of child failed");
+ exit(1);
+ case -1:
+ dbg("fork of child failed");
+ break;
+ return -1;
+ default:
wait(NULL);
- return;
- }
-
- execv(name, main_argv);
- exit(1);
-}
-
-static void execute_dir (char *dirname)
-{
- DIR *directory;
- struct dirent *entry;
- char filename[NAME_SIZE];
- int name_len;
-
- 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;
-
- /* Nor do we run files that do not end in ".dev" */
- name_len = strlen(entry->d_name);
- if (name_len < strlen(SUFFIX))
- continue;
- if (strcmp(&entry->d_name[name_len - sizeof (SUFFIX) + 1], SUFFIX) != 0)
- 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);
+ return 0;
}
-/* runs files in these directories in order:
- * name given by udev
- * subsystem
- * default
+/*
+ * runs files in these directories in order:
+ * <node name given by udev>/
+ * subsystem/
+ * default/
*/
void dev_d_send(struct udevice *dev, char *subsystem)
{
@@ -112,15 +70,15 @@
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, DEVD_DIR);
+ strfieldcat(dirname, dev->name);
+ call_foreach_file(run_program, dirname, DEVD_SUFFIX);
+
+ strcpy(dirname, DEVD_DIR);
+ strfieldcat(dirname, subsystem);
+ call_foreach_file(run_program, dirname, DEVD_SUFFIX);
- strcpy(dirname, HOTPLUGDIR "/default/");
- execute_dir(dirname);
+ strcpy(dirname, DEVD_DIR "default");
+ call_foreach_file(run_program, dirname, DEVD_SUFFIX);
}
===== namedev.h 1.29 vs edited =====
--- 1.29/namedev.h Wed Mar 10 23:00:15 2004
+++ edited/namedev.h Thu Mar 25 12:48:30 2004
@@ -53,8 +53,8 @@
#define MAX_SYSFS_PAIRS 5
-#define RULEFILE_EXT ".rules"
-#define PERMFILE_EXT ".permissions"
+#define RULEFILE_SUFFIX ".rules"
+#define PERMFILE_SUFFIX ".permissions"
#define set_empty_perms(dev, m, o, g) \
if (dev->mode == 0) \
===== namedev_parse.c 1.33 vs edited =====
--- 1.33/namedev_parse.c Wed Mar 17 23:40:12 2004
+++ edited/namedev_parse.c Thu Mar 25 13:10:52 2004
@@ -33,7 +33,6 @@
#include <ctype.h>
#include <unistd.h>
#include <sys/stat.h>
-#include <dirent.h>
#include <errno.h>
#include "udev.h"
@@ -41,8 +40,6 @@
#include "logging.h"
#include "namedev.h"
-LIST_HEAD(file_list);
-
static int add_config_dev(struct config_device *new_dev)
{
@@ -416,88 +413,26 @@
return retval;
}
-struct files {
- struct list_head list;
- char name[NAME_SIZE];
-};
-
-/* sort files in lexical order */
-static int file_list_insert(char *filename)
-{
- struct files *loop_file;
- struct files *new_file;
-
- list_for_each_entry(loop_file, &file_list, list) {
- if (strcmp(loop_file->name, filename) > 0) {
- break;
- }
- }
-
- new_file = malloc(sizeof(struct files));
- if (new_file == NULL) {
- dbg("error malloc");
- return -ENOMEM;
- }
-
- strfieldcpy(new_file->name, filename);
- list_add_tail(&new_file->list, &loop_file->list);
- return 0;
-}
-
-/* calls function for file or every file found in directory */
-static int call_foreach_file(int parser (char *f) , char *filename, char *extension)
+int namedev_init_rules()
{
- struct dirent *ent;
- DIR *dir;
- char *ext;
- char file[NAME_SIZE];
struct stat stats;
- struct files *loop_file;
- struct files *tmp_file;
- /* look if we have a plain file or a directory to scan */
- stat(filename, &stats);
+ stat(udev_rules_filename, &stats);
if ((stats.st_mode & S_IFMT) != S_IFDIR)
- return parser(filename);
-
- /* sort matching filename into list */
- dbg("open config as directory '%s'", filename);
- dir = opendir(filename);
- while (1) {
- ent = readdir(dir);
- if (ent == NULL || ent->d_name[0] == '\0')
- break;
-
- dbg("found file '%s'", ent->d_name);
- ext = strrchr(ent->d_name, '.');
- if (ext == NULL)
- continue;
-
- if (strcmp(ext, extension) == 0) {
- dbg("put file in list '%s'", ent->d_name);
- file_list_insert(ent->d_name);
- }
- }
-
- /* parse every file in the list */
- list_for_each_entry_safe(loop_file, tmp_file, &file_list, list) {
- strfieldcpy(file, filename);
- strfieldcat(file, loop_file->name);
- parser(file);
- list_del(&loop_file->list);
- free(loop_file);
- }
-
- closedir(dir);
- return 0;
-}
-
-int namedev_init_rules()
-{
- return call_foreach_file(namedev_parse_rules, udev_rules_filename, RULEFILE_EXT);
+ return namedev_parse_rules(udev_rules_filename);
+ else
+ return call_foreach_file(namedev_parse_rules,
+ udev_rules_filename, RULEFILE_SUFFIX);
}
int namedev_init_permissions()
{
- return call_foreach_file(namedev_parse_permissions, udev_permissions_filename, PERMFILE_EXT);
+ struct stat stats;
+
+ stat(udev_permissions_filename, &stats);
+ if ((stats.st_mode & S_IFMT) != S_IFDIR)
+ return namedev_parse_permissions(udev_permissions_filename);
+ else
+ return call_foreach_file(namedev_parse_permissions,
+ udev_permissions_filename, PERMFILE_SUFFIX);
}
===== udev-add.c 1.66 vs edited =====
--- 1.66/udev-add.c Thu Mar 25 00:14:16 2004
+++ edited/udev-add.c Thu Mar 25 13:25:50 2004
@@ -393,6 +393,7 @@
retval = ioctl(sk, SIOCSIFNAME, &ifr);
if (retval != 0)
dbg("error changing net interface name");
+ close(sk);
return retval;
}
@@ -453,6 +454,8 @@
case 'b':
case 'c':
retval = create_node(&dev, fake);
+ if ((retval == 0) && (!fake))
+ dev_d_send(&dev, subsystem);
break;
case 'n':
@@ -461,9 +464,6 @@
dbg("net device naming failed");
break;
}
-
- if ((retval == 0) && (!fake))
- dev_d_send(&dev, subsystem);
exit:
if (class_dev)
===== udev_lib.c 1.3 vs edited =====
--- 1.3/udev_lib.c Thu Mar 25 00:50:34 2004
+++ edited/udev_lib.c Thu Mar 25 13:29:50 2004
@@ -21,14 +21,19 @@
#include <stdlib.h>
#include <stdio.h>
+#include <stddef.h>
#include <unistd.h>
#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include "libsysfs/sysfs/libsysfs.h"
#include "udev.h"
+#include "logging.h"
#include "udev_lib.h"
+#include "list.h"
char *get_action(void)
@@ -136,3 +141,84 @@
return count - cur;
}
+struct files {
+ struct list_head list;
+ char name[NAME_SIZE];
+};
+
+/* sort files in lexical order */
+static int file_list_insert(char *filename, struct list_head *file_list)
+{
+ struct files *loop_file;
+ struct files *new_file;
+
+ list_for_each_entry(loop_file, file_list, list) {
+ if (strcmp(loop_file->name, filename) > 0) {
+ break;
+ }
+ }
+
+ new_file = malloc(sizeof(struct files));
+ if (new_file == NULL) {
+ dbg("error malloc");
+ return -ENOMEM;
+ }
+
+ strfieldcpy(new_file->name, filename);
+ list_add_tail(&new_file->list, &loop_file->list);
+ return 0;
+}
+
+/* calls function for file or every file found in directory */
+int call_foreach_file(int fnct(char *f) , char *dirname, char *suffix)
+{
+ struct dirent *ent;
+ DIR *dir;
+ char *ext;
+ char file[NAME_SIZE];
+ struct files *loop_file;
+ struct files *tmp_file;
+ LIST_HEAD(file_list);
+
+ dbg("open directory '%s'", dirname);
+ dir = opendir(dirname);
+ if (dir == NULL) {
+ dbg("unable to open '%s'", dirname);
+ return -1;
+ }
+
+ while (1) {
+ ent = readdir(dir);
+ if (ent == NULL || ent->d_name[0] == '\0')
+ break;
+
+ if ((ent->d_name[0] == '.') || (ent->d_name[0] == COMMENT_CHARACTER))
+ continue;
+
+ /* look for file with specified suffix */
+ ext = strrchr(ent->d_name, '.');
+ if (ext == NULL)
+ continue;
+
+ if (strcmp(ext, suffix) != 0)
+ continue;
+
+ dbg("put file '%s/%s' in list", dirname, ent->d_name);
+ file_list_insert(ent->d_name, &file_list);
+ }
+
+ /* call function for every file in the list */
+ list_for_each_entry_safe(loop_file, tmp_file, &file_list, list) {
+ strfieldcpy(file, dirname);
+ strfieldcat(file, "/");
+ strfieldcat(file, loop_file->name);
+
+ fnct(file);
+
+ list_del(&loop_file->list);
+ free(loop_file);
+ }
+
+ closedir(dir);
+ return 0;
+}
===== udev_lib.h 1.3 vs edited =====
--- 1.3/udev_lib.h Thu Mar 25 00:14:20 2004
+++ edited/udev_lib.h Thu Mar 25 12:38:24 2004
@@ -75,6 +75,7 @@
extern int file_map(const char *filename, char **buf, size_t *bufsize);
extern void file_unmap(char *buf, size_t bufsize);
extern size_t buf_get_line(char *buf, size_t buflen, size_t cur);
+extern int call_foreach_file(int fnct(char *f) , char *filename, char *extension);
#endif
===== udevd.c 1.24 vs edited =====
--- 1.24/udevd.c Wed Mar 17 23:40:12 2004
+++ edited/udevd.c Thu Mar 25 12:43:05 2004
@@ -45,9 +45,9 @@
volatile static int children_waiting;
volatile static int msg_q_timeout;
-LIST_HEAD(msg_list);
-LIST_HEAD(exec_list);
-LIST_HEAD(running_list);
+static LIST_HEAD(msg_list);
+static LIST_HEAD(exec_list);
+static LIST_HEAD(running_list);
static void exec_queue_manager(void);
static void msg_queue_manager(void);
===== udevruler.c 1.1 vs edited =====
--- 1.1/udevruler.c Thu Mar 18 04:23:51 2004
+++ edited/udevruler.c Thu Mar 25 12:45:16 2004
@@ -81,8 +81,8 @@
int added;
};
-LIST_HEAD(device_list);
-int device_count;
+static LIST_HEAD(device_list);
+static int device_count;
/* callback for database dump */
static int add_record(char *path, struct udevice *udev)
@@ -149,8 +149,8 @@
char key[NAME_SIZE];
};
-LIST_HEAD(attribute_list);
-int attribute_count;
+static LIST_HEAD(attribute_list);
+static int attribute_count;
static int add_attribute(const char *key, int level)
{
next reply other threads:[~2004-03-25 13:43 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-03-25 13:43 Kay Sievers [this message]
2004-03-27 1:08 ` [PATCH] dev_d.c file sorting and cleanup Greg KH
2004-03-27 1:13 ` Kay Sievers
2004-03-27 1:21 ` Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20040325134350.GA30182@vrfy.org \
--to=kay.sievers@vrfy.org \
--cc=linux-hotplug@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.