]>
Commit | Line | Data |
---|---|---|
dd64e26b | 1 | /* |
4a539daf | 2 | * dev_d.c - dev.d/ 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 GKH |
30 | #include "udev.h" |
31 | #include "udev_lib.h" | |
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 | */ |
8673dcb8 | 74 | void dev_d_execute(struct udevice *udev, const char *basedir, const char *suffix) |
dd64e26b | 75 | { |
5d24c6ca KS |
76 | char dirname[PATH_MAX]; |
77 | char devname[NAME_SIZE]; | |
a3e6c800 | 78 | char *temp; |
dd64e26b | 79 | |
5d24c6ca | 80 | /* skip if UDEV_NO_DEVD is set */ |
bbbe503e KS |
81 | if (udev_dev_d == 0) |
82 | return; | |
83 | ||
5d24c6ca | 84 | strfieldcpy(devname, udev->name); |
a3e6c800 | 85 | |
8673dcb8 | 86 | /* chop the device name up into pieces based on '/' */ |
a3e6c800 GKH |
87 | temp = strchr(devname, '/'); |
88 | while (temp != NULL) { | |
5d24c6ca | 89 | temp[0] = '\0'; |
8673dcb8 KS |
90 | snprintf(dirname, PATH_MAX, "%s/%s", basedir, devname); |
91 | dirname[PATH_MAX-1] = '\0'; | |
92 | call_foreach_file(run_program, dirname, suffix, udev); | |
a3e6c800 | 93 | |
5d24c6ca | 94 | temp[0] = '/'; |
a3e6c800 GKH |
95 | ++temp; |
96 | temp = strchr(temp, '/'); | |
97 | } | |
dd64e26b | 98 | |
8673dcb8 KS |
99 | snprintf(dirname, PATH_MAX, "%s/%s", basedir, udev->name); |
100 | dirname[PATH_MAX-1] = '\0'; | |
101 | call_foreach_file(run_program, dirname, suffix, udev); | |
dd64e26b | 102 | |
8673dcb8 KS |
103 | snprintf(dirname, PATH_MAX, "%s/%s", basedir, udev->subsystem); |
104 | dirname[PATH_MAX-1] = '\0'; | |
105 | call_foreach_file(run_program, dirname, suffix, udev); | |
dd64e26b | 106 | |
8673dcb8 KS |
107 | snprintf(dirname, PATH_MAX, "%s/default", basedir); |
108 | dirname[PATH_MAX-1] = '\0'; | |
109 | call_foreach_file(run_program, dirname, suffix, udev); | |
dd64e26b | 110 | } |