]> git.ipfire.org Git - thirdparty/systemd.git/blame - udev_multiplex.c
[PATCH] udevinfo: print SUBSYSTEM and DRIVER
[thirdparty/systemd.git] / udev_multiplex.c
CommitLineData
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 34static 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 74void 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}