2 * Copyright (C) 2004-2009 Kay Sievers <kay.sievers@vrfy.org>
4 * + Trimmed from udev-149. Fixed passing of devtype parameter.
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #ifndef _POSIX_C_SOURCE
21 #define _POSIX_C_SOURCE 1
37 #include <sys/socket.h>
39 #include <sys/select.h>
40 #include <linux/types.h>
41 #include <linux/netlink.h>
44 static volatile sig_atomic_t udev_exit
;
46 static void sig_handler(int signum
)
48 if (signum
== SIGINT
|| signum
== SIGTERM
)
52 static int print_device(struct udev_device
*device
, const char *f_action
, const char *f_devsuffix
)
56 const char *action
= udev_device_get_action(device
);
57 const char *devpath
= udev_device_get_devpath(device
);
60 gettimeofday(&tv
, NULL
);
61 printf("%lu.%06u %s %s\n",
62 (unsigned long) tv
.tv_sec
, (unsigned int) tv
.tv_usec
,
65 if (! strcmp(f_action
, action
)) {
66 f_len
= strlen(f_devsuffix
);
67 d_len
= strlen(devpath
);
69 if (d_len
>= f_len
&& !strcmp(devpath
+(d_len
-f_len
), f_devsuffix
))
76 int main(int argc
, char *argv
[])
84 struct udev_monitor
*kernel_monitor
= NULL
;
87 const char *filter_subsys
= "block";
88 /* const char *filter_devtype = "partition"; */
89 const char *filter_devsuffix
;
90 const char *filter_devtype
;
91 const char *filter_action
;
100 filter_devsuffix
= argv
[1];
101 filter_devtype
= argv
[2];
103 if (strcmp(filter_devtype
, "cd") == 0) {
104 filter_action
= "change";
105 } else if (strcmp(filter_devtype
, "disk") == 0) {
106 filter_action
= "remove";
109 /* set signal handlers */
110 memset(&act
, 0x00, sizeof(struct sigaction
));
111 act
.sa_handler
= sig_handler
;
112 sigemptyset(&act
.sa_mask
);
113 act
.sa_flags
= SA_RESTART
;
114 sigaction(SIGINT
, &act
, NULL
);
115 sigaction(SIGTERM
, &act
, NULL
);
117 sigaddset(&mask
, SIGINT
);
118 sigaddset(&mask
, SIGTERM
);
119 sigprocmask(SIG_UNBLOCK
, &mask
, NULL
);
121 kernel_monitor
= udev_monitor_new_from_netlink(udev
, "kernel");
122 if (kernel_monitor
== NULL
) {
123 fprintf(stderr
, "error: unable to create netlink socket\n");
128 if (udev_monitor_filter_add_match_subsystem_devtype(kernel_monitor
, filter_subsys
, NULL
/* filter_devtype */) < 0)
129 fprintf(stderr
, "error: unable to apply subsystem filter '%s:%s'\n", filter_subsys
, "NULL" /* filter_devtype */);
131 if (udev_monitor_enable_receiving(kernel_monitor
) < 0) {
132 fprintf(stderr
, "error: unable to subscribe to kernel events\n");
141 if (kernel_monitor
!= NULL
)
142 FD_SET(udev_monitor_get_fd(kernel_monitor
), &readfds
);
144 fdcount
= select(udev_monitor_get_fd(kernel_monitor
)+1,
145 &readfds
, NULL
, NULL
, NULL
);
148 fprintf(stderr
, "error receiving uevent message: %s\n", strerror(errno
));
152 if ((kernel_monitor
!= NULL
) && FD_ISSET(udev_monitor_get_fd(kernel_monitor
), &readfds
)) {
153 struct udev_device
*device
;
155 device
= udev_monitor_receive_device(kernel_monitor
);
158 if (print_device(device
, filter_action
, filter_devsuffix
))
161 udev_device_unref(device
);
166 udev_monitor_unref(kernel_monitor
);