mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
[PATCH] dev_d.c file sorting and cleanup
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.
This commit is contained in:
parent
949e32f224
commit
4a539daf1e
114
dev_d.c
114
dev_d.c
@ -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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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 @@ void dev_d_send(struct udevice *dev, char *subsystem)
|
||||
strfieldcat(devnode, dev->name);
|
||||
setenv("DEVNODE", devnode, 1);
|
||||
|
||||
snprintf(dirname, sizeof(dirname), HOTPLUGDIR "/%s/", dev->name);
|
||||
dirname[sizeof(dirname)-1] = '\0';
|
||||
execute_dir(dirname);
|
||||
strcpy(dirname, DEVD_DIR);
|
||||
strfieldcat(dirname, dev->name);
|
||||
call_foreach_file(run_program, dirname, DEVD_SUFFIX);
|
||||
|
||||
snprintf(dirname, sizeof(dirname), HOTPLUGDIR "/%s/", subsystem);
|
||||
dirname[sizeof(dirname)-1] = '\0';
|
||||
execute_dir(dirname);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -53,8 +53,8 @@ struct sysfs_class_device;
|
||||
|
||||
#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) \
|
||||
|
@ -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 @@ exit:
|
||||
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)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
struct stat stats;
|
||||
|
||||
stat(udev_rules_filename, &stats);
|
||||
if ((stats.st_mode & S_IFMT) != S_IFDIR)
|
||||
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);
|
||||
}
|
||||
|
@ -393,6 +393,7 @@ static int rename_net_if(struct udevice *dev)
|
||||
retval = ioctl(sk, SIOCSIFNAME, &ifr);
|
||||
if (retval != 0)
|
||||
dbg("error changing net interface name");
|
||||
close(sk);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -453,6 +454,8 @@ int udev_add_device(char *path, char *subsystem, int fake)
|
||||
case 'b':
|
||||
case 'c':
|
||||
retval = create_node(&dev, fake);
|
||||
if ((retval == 0) && (!fake))
|
||||
dev_d_send(&dev, subsystem);
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
@ -462,9 +465,6 @@ int udev_add_device(char *path, char *subsystem, int fake)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((retval == 0) && (!fake))
|
||||
dev_d_send(&dev, subsystem);
|
||||
|
||||
exit:
|
||||
if (class_dev)
|
||||
sysfs_close_class_device(class_dev);
|
||||
|
86
udev_lib.c
86
udev_lib.c
@ -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 @@ size_t buf_get_line(char *buf, size_t buflen, size_t cur)
|
||||
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;
|
||||
}
|
||||
|
@ -75,6 +75,7 @@ extern char get_device_type(const char *path, const char *subsystem);
|
||||
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
|
||||
|
6
udevd.c
6
udevd.c
@ -45,9 +45,9 @@ static int expected_seqnum = 0;
|
||||
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);
|
||||
|
@ -81,8 +81,8 @@ struct device {
|
||||
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 @@ struct attribute {
|
||||
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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user