mirror of
https://github.com/AuxXxilium/eudev.git
synced 2025-01-20 02:59:08 +07:00
[PATCH] move execute_program to utils + add action to init_device
This commit is contained in:
parent
7ff56624f8
commit
fb39f0566e
5
udev.c
5
udev.c
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
48
udev_rules.c
48
udev_rules.c
@ -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;
|
||||
|
64
udev_utils.c
64
udev_utils.c
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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 */
|
||||
|
11
udevtest.c
11
udevtest.c
@ -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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user