[PATCH] move execute_program to utils + add action to init_device

This commit is contained in:
kay.sievers@vrfy.org 2005-03-29 11:25:52 +02:00 committed by Greg KH
parent 7ff56624f8
commit fb39f0566e
8 changed files with 104 additions and 65 deletions

5
udev.c
View file

@ -141,7 +141,7 @@ int main(int argc, char *argv[], char *envp[])
if (!subsystem && argc == 2)
subsystem = argv[1];
udev_init_device(&udev, devpath, subsystem);
udev_init_device(&udev, devpath, subsystem, action);
if (!action || !subsystem || !devpath) {
err("action, subsystem or devpath missing");
@ -230,10 +230,11 @@ int main(int argc, char *argv[], char *envp[])
}
hotplug:
udev_cleanup_device(&udev);
if (udev_hotplug_d && managed_event)
udev_multiplex_directory(&udev, HOTPLUGD_DIR, HOTPLUG_SUFFIX);
udev_cleanup_device(&udev);
logging_close();
return retval;
}

View file

@ -32,38 +32,6 @@
#include "udev_utils.h"
#include "logging.h"
static int run_program(struct udevice *udev, const char *filename)
{
pid_t pid;
int fd;
dbg("running %s", filename);
pid = fork();
switch (pid) {
case 0:
/* child */
fd = open("/dev/null", O_RDWR);
if ( fd >= 0) {
dup2(fd, STDOUT_FILENO);
dup2(fd, STDIN_FILENO);
dup2(fd, STDERR_FILENO);
}
close(fd);
execl(filename, filename, udev->subsystem, NULL);
dbg("exec of child failed");
_exit(1);
case -1:
dbg("fork of child failed");
break;
return -1;
default:
waitpid(pid, NULL, 0);
}
return 0;
}
/*
* runs files in these directories in order:
@ -117,7 +85,7 @@ void udev_multiplex_directory(struct udevice *udev, const char *basedir, const c
add_matching_files(&name_list, dirname, suffix);
list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) {
run_program(udev, name_loop->name);
execute_command(name_loop->name, udev->subsystem);
list_del(&name_loop->node);
}

View file

@ -31,7 +31,6 @@
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include "libsysfs/sysfs/libsysfs.h"
#include "list.h"
@ -327,7 +326,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize,
struct udevice udev_parent;
dbg("found parent '%s', get the node name", class_dev_parent->path);
udev_init_device(&udev_parent, NULL, NULL);
udev_init_device(&udev_parent, NULL, NULL, NULL);
/* lookup the name in the udev_db with the DEVPATH of the parent */
if (udev_db_get_device(&udev_parent, &class_dev_parent->path[strlen(sysfs_path)]) == 0) {
strlcat(string, udev_parent.name, maxsize);
@ -364,21 +363,22 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize,
}
}
static int execute_program(struct udevice *udev, const char *path, char *value, int len)
static int execute_program_pipe(const char *command, const char *subsystem, char *value, int len)
{
int retval;
int count;
int status;
int fds[2];
int pipefds[2];
pid_t pid;
char *pos;
char arg[PATH_SIZE];
char *argv[(sizeof(arg) / 2) + 1];
int devnull;
int i;
strlcpy(arg, path, sizeof(arg));
strlcpy(arg, command, sizeof(arg));
i = 0;
if (strchr(path, ' ')) {
if (strchr(arg, ' ')) {
pos = arg;
while (pos != NULL) {
if (pos[0] == '\'') {
@ -397,12 +397,12 @@ static int execute_program(struct udevice *udev, const char *path, char *value,
dbg("execute '%s' with parsed arguments", arg);
} else {
argv[0] = arg;
argv[1] = udev->subsystem;
argv[1] = (char *) subsystem;
argv[2] = NULL;
dbg("execute '%s' with subsystem '%s' argument", arg, argv[1]);
}
retval = pipe(fds);
retval = pipe(pipefds);
if (retval != 0) {
err("pipe failed");
return -1;
@ -412,22 +412,27 @@ static int execute_program(struct udevice *udev, const char *path, char *value,
switch(pid) {
case 0:
/* child dup2 write side of pipe to STDOUT */
dup2(fds[1], STDOUT_FILENO);
devnull = open("/dev/null", O_RDWR);
if (devnull >= 0) {
dup2(devnull, STDIN_FILENO);
dup2(devnull, STDERR_FILENO);
close(devnull);
}
dup2(pipefds[1], STDOUT_FILENO);
retval = execv(arg, argv);
err("exec of program failed");
_exit(1);
case -1:
err("fork of '%s' failed", path);
err("fork of '%s' failed", arg);
retval = -1;
break;
default:
/* parent reads from fds[0] */
close(fds[1]);
/* parent reads from pipefds[0] */
close(pipefds[1]);
retval = 0;
i = 0;
while (1) {
count = read(fds[0], value + i, len - i-1);
count = read(pipefds[0], value + i, len - i-1);
if (count < 0) {
err("read failed with '%s'", strerror(errno));
retval = -1;
@ -445,7 +450,7 @@ static int execute_program(struct udevice *udev, const char *path, char *value,
}
value[i] = '\0';
close(fds[0]);
close(pipefds[0]);
waitpid(pid, &status, 0);
if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) {
@ -470,9 +475,9 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule,
struct sysfs_device *parent_device = sysfs_device;
if (rule->kernel_operation != KEY_OP_UNSET) {
dbg("check for " KEY_KERNEL " rule->kernel='%s' class_dev->name='%s'",
rule->kernel, class_dev->name);
if (strcmp_pattern(rule->kernel, class_dev->name) != 0) {
dbg("check for " KEY_KERNEL " rule->kernel='%s' udev_kernel_name='%s'",
rule->kernel, udev->kernel_name);
if (strcmp_pattern(rule->kernel, udev->kernel_name) != 0) {
dbg(KEY_KERNEL " is not matching");
if (rule->kernel_operation != KEY_OP_NOMATCH)
goto exit;
@ -485,8 +490,8 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule,
}
if (rule->subsystem_operation != KEY_OP_UNSET) {
dbg("check for " KEY_SUBSYSTEM " rule->subsystem='%s' class_dev->name='%s'",
rule->subsystem, class_dev->name);
dbg("check for " KEY_SUBSYSTEM " rule->subsystem='%s' udev->subsystem='%s'",
rule->subsystem, udev->subsystem);
if (strcmp_pattern(rule->subsystem, udev->subsystem) != 0) {
dbg(KEY_SUBSYSTEM " is not matching");
if (rule->subsystem_operation != KEY_OP_NOMATCH)
@ -642,7 +647,8 @@ try_parent:
dbg("check " KEY_PROGRAM);
strlcpy(program, rule->program, sizeof(program));
apply_format(udev, program, sizeof(program), class_dev, sysfs_device);
if (execute_program(udev, program, udev->program_result, sizeof(udev->program_result)) != 0) {
if (execute_program_pipe(program, udev->subsystem,
udev->program_result, sizeof(udev->program_result)) != 0) {
dbg(KEY_PROGRAM " returned nonzero");
if (rule->program_operation != KEY_OP_NOMATCH)
goto exit;

View file

@ -27,6 +27,7 @@
#include <errno.h>
#include <ctype.h>
#include <dirent.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/utsname.h>
@ -38,7 +39,7 @@
#include "list.h"
int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem)
int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem, const char *action)
{
char *pos;
@ -317,3 +318,64 @@ int add_matching_files(struct list_head *name_list, const char *dirname, const c
closedir(dir);
return 0;
}
int execute_command(const char *command, const char *subsystem)
{
int retval;
pid_t pid;
char arg[PATH_SIZE];
char *argv[(PATH_SIZE / 2) + 1];
char *pos;
int devnull;
int i;
strlcpy(arg, command, sizeof(arg));
i = 0;
if (strchr(arg, ' ')) {
pos = arg;
while (pos != NULL) {
if (pos[0] == '\'') {
/* don't separate if in apostrophes */
pos++;
argv[i] = strsep(&pos, "\'");
while (pos && pos[0] == ' ')
pos++;
} else {
argv[i] = strsep(&pos, " ");
}
dbg("arg[%i] '%s'", i, argv[i]);
i++;
}
argv[i] = NULL;
dbg("execute '%s' with parsed arguments", arg);
} else {
argv[0] = arg;
argv[1] = (char *) subsystem;
argv[2] = NULL;
dbg("execute '%s' with subsystem '%s' argument", arg, argv[1]);
}
pid = fork();
switch (pid) {
case 0:
/* child */
devnull = open("/dev/null", O_RDWR);
if (devnull >= 0) {
dup2(devnull, STDIN_FILENO);
dup2(devnull, STDOUT_FILENO);
dup2(devnull, STDERR_FILENO);
close(devnull);
}
retval = execv(arg, argv);
err("exec of child failed");
_exit(1);
case -1:
dbg("fork of child failed");
break;
return -1;
default:
waitpid(pid, NULL, 0);
}
return 0;
}

View file

@ -29,7 +29,7 @@ struct name_entry {
char name[PATH_SIZE];
};
extern int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem);
extern int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem, const char *action);
extern void udev_cleanup_device(struct udevice *udev);
extern int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel);
@ -43,5 +43,6 @@ extern void remove_trailing_char(char *path, char c);
extern void replace_untrusted_chars(char *string);
extern int name_list_add(struct list_head *name_list, const char *name, int sort);
extern int add_matching_files(struct list_head *name_list, const char *dirname, const char *suffix);
extern int execute_command(const char *command, const char *subsystem);
#endif

View file

@ -199,7 +199,7 @@ int main(int argc, char *argv[], char *envp[])
logging_init("udevinfo");
udev_init_config();
udev_init_device(&udev, NULL, NULL);
udev_init_device(&udev, NULL, NULL, NULL);
/* get command line options */
while (1) {

View file

@ -123,7 +123,7 @@ static int add_device(const char *path, const char *subsystem)
return -ENODEV;
}
udev_init_device(&udev, devpath, subsystem);
udev_init_device(&udev, devpath, subsystem, "add");
udev_add_device(&udev, class_dev);
/* run dev.d/ scripts if we created a node or changed a netif name */

View file

@ -86,16 +86,17 @@ int main(int argc, char *argv[], char *envp[])
} else
devpath = argv[1];
info("looking at '%s'", devpath);
subsystem = argv[2];
setenv("DEVPATH", devpath, 1);
setenv("SUBSYSTEM", subsystem, 1);
setenv("ACTION", "add", 1);
info("looking at device '%s' from subsystem '%s'", devpath, subsystem);
/* initialize the naming deamon */
udev_rules_init();
if (argc == 3)
subsystem = argv[2];
/* fill in values and test_run flag*/
udev_init_device(&udev, devpath, subsystem);
udev_init_device(&udev, devpath, subsystem, "add");
/* skip subsystems without "dev", but handle net devices */
if (udev.type != DEV_NET && subsystem_expect_no_dev(udev.subsystem)) {