]>
Commit | Line | Data |
---|---|---|
dd64e26b | 1 | /* |
9af5bb2f | 2 | * udev_multiplex.c directory multiplexer |
dd64e26b GKH |
3 | * |
4 | * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com> | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify it | |
7 | * under the terms of the GNU General Public License as published by the | |
8 | * Free Software Foundation version 2 of the License. | |
dd64e26b GKH |
9 | */ |
10 | ||
4a539daf | 11 | /* |
dd64e26b | 12 | * This essentially emulates the following shell script logic in C: |
4a539daf | 13 | * DIR="/etc/dev.d" |
4b06c852 | 14 | * export DEVNAME="whatever_dev_name_udev_just_gave" |
15 | * for I in "${DIR}/$DEVNAME/"*.dev "${DIR}/$1/"*.dev "${DIR}/default/"*.dev ; do | |
4a539daf KS |
16 | * if [ -f $I ]; then $I $1 ; fi |
17 | * done | |
18 | * exit 1; | |
dd64e26b GKH |
19 | */ |
20 | ||
dd64e26b GKH |
21 | #include <stdio.h> |
22 | #include <stdlib.h> | |
23 | #include <string.h> | |
24 | #include <sys/types.h> | |
25 | #include <sys/wait.h> | |
6e3e3c34 | 26 | #include <sys/stat.h> |
dd64e26b | 27 | #include <unistd.h> |
6e3e3c34 HH |
28 | #include <fcntl.h> |
29 | ||
dd64e26b | 30 | #include "udev.h" |
9af5bb2f | 31 | #include "udev_utils.h" |
dd64e26b GKH |
32 | #include "logging.h" |
33 | ||
af4b05d4 | 34 | static int run_program(const char *filename, void *data) |
dd64e26b GKH |
35 | { |
36 | pid_t pid; | |
6e3e3c34 | 37 | int fd; |
af4b05d4 | 38 | struct udevice *udev = data; |
dd64e26b | 39 | |
af4b05d4 | 40 | dbg("running %s", filename); |
dd64e26b GKH |
41 | |
42 | pid = fork(); | |
4a539daf KS |
43 | switch (pid) { |
44 | case 0: | |
45 | /* child */ | |
6e3e3c34 HH |
46 | fd = open("/dev/null", O_RDWR); |
47 | if ( fd >= 0) { | |
48 | dup2(fd, STDOUT_FILENO); | |
49 | dup2(fd, STDIN_FILENO); | |
50 | dup2(fd, STDERR_FILENO); | |
51 | } | |
52 | close(fd); | |
1059b07a | 53 | |
af4b05d4 | 54 | execl(filename, filename, udev->subsystem, NULL); |
4a539daf | 55 | dbg("exec of child failed"); |
5d24c6ca | 56 | _exit(1); |
4a539daf KS |
57 | case -1: |
58 | dbg("fork of child failed"); | |
59 | break; | |
60 | return -1; | |
61 | default: | |
e920fed3 | 62 | waitpid(pid, NULL, 0); |
dd64e26b GKH |
63 | } |
64 | ||
4a539daf | 65 | return 0; |
dd64e26b GKH |
66 | } |
67 | ||
4a539daf KS |
68 | /* |
69 | * runs files in these directories in order: | |
70 | * <node name given by udev>/ | |
71 | * subsystem/ | |
72 | * default/ | |
dd64e26b | 73 | */ |
9af5bb2f | 74 | void udev_multiplex_directory(struct udevice *udev, const char *basedir, const char *suffix) |
dd64e26b | 75 | { |
5d24c6ca | 76 | char dirname[PATH_MAX]; |
a3e6c800 | 77 | |
8673dcb8 | 78 | /* chop the device name up into pieces based on '/' */ |
7757db1f KS |
79 | if (udev->name[0] != '\0') { |
80 | char devname[NAME_SIZE]; | |
81 | char *temp; | |
82 | ||
83 | strfieldcpy(devname, udev->name); | |
84 | temp = strchr(devname, '/'); | |
85 | while (temp != NULL) { | |
86 | temp[0] = '\0'; | |
87 | ||
88 | /* don't call the subsystem directory here */ | |
89 | if (strcmp(devname, udev->subsystem) != 0) { | |
90 | snprintf(dirname, PATH_MAX, "%s/%s", basedir, devname); | |
91 | dirname[PATH_MAX-1] = '\0'; | |
92 | call_foreach_file(run_program, dirname, suffix, udev); | |
93 | } | |
94 | ||
95 | temp[0] = '/'; | |
96 | ++temp; | |
97 | temp = strchr(temp, '/'); | |
98 | } | |
a3e6c800 | 99 | } |
dd64e26b | 100 | |
491b02ac KS |
101 | if (udev->name[0] != '\0') { |
102 | snprintf(dirname, PATH_MAX, "%s/%s", basedir, udev->name); | |
103 | dirname[PATH_MAX-1] = '\0'; | |
104 | call_foreach_file(run_program, dirname, suffix, udev); | |
105 | } | |
dd64e26b | 106 | |
491b02ac KS |
107 | if (udev->subsystem[0] != '\0') { |
108 | snprintf(dirname, PATH_MAX, "%s/%s", basedir, udev->subsystem); | |
109 | dirname[PATH_MAX-1] = '\0'; | |
110 | call_foreach_file(run_program, dirname, suffix, udev); | |
111 | } | |
dd64e26b | 112 | |
8673dcb8 KS |
113 | snprintf(dirname, PATH_MAX, "%s/default", basedir); |
114 | dirname[PATH_MAX-1] = '\0'; | |
115 | call_foreach_file(run_program, dirname, suffix, udev); | |
dd64e26b | 116 | } |