udevmonitor.c revision 593453115b777368252ca4231537ad2a9e6d8ffb
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov/*
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov * Copyright (C) 2004-2006 Kay Sievers <kay.sievers@vrfy.org>
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov *
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov * This program is free software; you can redistribute it and/or modify it
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov * under the terms of the GNU General Public License as published by the
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov * Free Software Foundation version 2 of the License.
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov *
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov * This program is distributed in the hope that it will be useful, but
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov * WITHOUT ANY WARRANTY; without even the implied warranty of
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov * General Public License for more details.
d0800999b2aff2c2445e1ac18905fddbfe71cb8cJohn Lane *
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov * You should have received a copy of the GNU General Public License along
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov * with this program; if not, write to the Free Software Foundation, Inc.,
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov *
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov */
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov#include <unistd.h>
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov#include <stdio.h>
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov#include <stdlib.h>
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov#include <stddef.h>
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov#include <string.h>
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov#include <fcntl.h>
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov#include <errno.h>
250b1eec71b074acdff1c5f6b5a1f0d7d2c20b77Stéphane Graber#include <signal.h>
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov#include <getopt.h>
8ec981fc8b0105da5f071e40811e0c2472a6c3c9Stéphane Graber#include <sys/time.h>
8ec981fc8b0105da5f071e40811e0c2472a6c3c9Stéphane Graber#include <sys/socket.h>
8ec981fc8b0105da5f071e40811e0c2472a6c3c9Stéphane Graber#include <sys/un.h>
8ec981fc8b0105da5f071e40811e0c2472a6c3c9Stéphane Graber#include <sys/select.h>
8ec981fc8b0105da5f071e40811e0c2472a6c3c9Stéphane Graber#include <linux/types.h>
8ec981fc8b0105da5f071e40811e0c2472a6c3c9Stéphane Graber#include <linux/netlink.h>
8ec981fc8b0105da5f071e40811e0c2472a6c3c9Stéphane Graber
8ec981fc8b0105da5f071e40811e0c2472a6c3c9Stéphane Graber#include "udev.h"
8ec981fc8b0105da5f071e40811e0c2472a6c3c9Stéphane Graber#include "udevd.h"
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirovstatic int uevent_netlink_sock = -1;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirovstatic int udev_monitor_sock = -1;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirovstatic volatile int udev_exit;
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirovstatic int init_udev_monitor_socket(void)
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov{
148315348760faf4ad822ded7c416d2de8050937Alexander Vladimirov struct sockaddr_un saddr;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov socklen_t addrlen;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov int retval;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov memset(&saddr, 0x00, sizeof(saddr));
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov saddr.sun_family = AF_LOCAL;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov /* use abstract namespace for socket path */
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov strcpy(&saddr.sun_path[1], "/org/kernel/udev/monitor");
4852d800d11740225072579e8bd8c4b56df581eeAlexander Vladimirov addrlen = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(&saddr.sun_path[1]);
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov udev_monitor_sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov if (udev_monitor_sock == -1) {
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov fprintf(stderr, "error getting socket: %s\n", strerror(errno));
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov return -1;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov }
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov /* the bind takes care of ensuring only one copy running */
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov retval = bind(udev_monitor_sock, (struct sockaddr *) &saddr, addrlen);
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov if (retval < 0) {
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov fprintf(stderr, "bind failed: %s\n", strerror(errno));
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov close(udev_monitor_sock);
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov udev_monitor_sock = -1;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov return -1;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov }
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov return 0;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov}
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirovstatic int init_uevent_netlink_sock(void)
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov{
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov struct sockaddr_nl snl;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov int retval;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov memset(&snl, 0x00, sizeof(struct sockaddr_nl));
17abf2784de1047fb2904ff130ee5efe4ea7b598Elan Ruusamäe snl.nl_family = AF_NETLINK;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov snl.nl_pid = getpid();
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov snl.nl_groups = 1;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov uevent_netlink_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov if (uevent_netlink_sock == -1) {
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov fprintf(stderr, "error getting socket: %s\n", strerror(errno));
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov return -1;
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov }
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov retval = bind(uevent_netlink_sock, (struct sockaddr *) &snl,
17abf2784de1047fb2904ff130ee5efe4ea7b598Elan Ruusamäe sizeof(struct sockaddr_nl));
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov if (retval < 0) {
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov fprintf(stderr, "bind failed: %s\n", strerror(errno));
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov close(uevent_netlink_sock);
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov uevent_netlink_sock = -1;
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov return -1;
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov }
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov return 0;
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov}
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirovstatic void asmlinkage sig_handler(int signum)
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov{
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov if (signum == SIGINT || signum == SIGTERM)
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov udev_exit = 1;
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov}
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirovstatic const char *search_key(const char *searchkey, const char *buf, size_t buflen)
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov{
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov size_t bufpos = 0;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov size_t searchkeylen = strlen(searchkey);
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov while (bufpos < buflen) {
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov const char *key;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov int keylen;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov key = &buf[bufpos];
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov keylen = strlen(key);
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov if (keylen == 0)
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov break;
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov if ((strncmp(searchkey, key, searchkeylen) == 0) && key[searchkeylen] == '=')
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov return &key[searchkeylen + 1];
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov bufpos += keylen + 1;
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov }
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov return NULL;
148315348760faf4ad822ded7c416d2de8050937Alexander Vladimirov}
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirovint udevmonitor(int argc, char *argv[])
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov{
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov struct sigaction act;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov int option;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov int env = 0;
17abf2784de1047fb2904ff130ee5efe4ea7b598Elan Ruusamäe int kernel = 0;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov int udev = 0;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov fd_set readfds;
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov int retval = 0;
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov static const struct option options[] = {
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov { "environment", 0, NULL, 'e' },
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov { "kernel", 0, NULL, 'k' },
d8c77af0ae59a3c48a44a11c95b991bd10473713John Lane { "udev", 0, NULL, 'u' },
6139e7e52d914af89f2a204512c1345af56ce6e9Alexander Vladimirov { "help", 0, NULL, 'h' },
6139e7e52d914af89f2a204512c1345af56ce6e9Alexander Vladimirov {}
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov };
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov while (1) {
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov option = getopt_long(argc, argv, "ekuh", options, NULL);
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov if (option == -1)
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov break;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov switch (option) {
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov case 'e':
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov env = 1;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov break;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov case 'k':
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov kernel = 1;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov break;
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov case 'u':
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov udev = 1;
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov break;
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov case 'h':
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov printf("Usage: udevadm monitor [--environment] [--kernel] [--udev] [--help]\n"
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov " --env print the whole event environment\n"
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov " --kernel print kernel uevents\n"
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov " --udev print udev events\n"
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov " --help print this help text\n\n");
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn default:
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn goto out;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov }
b335cf8d4b56a49d5bc3fd1229139c2595779891Stéphane Graber }
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov if (!kernel && !udev) {
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov kernel = 1;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov udev =1;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov }
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov if (getuid() != 0 && kernel) {
17abf2784de1047fb2904ff130ee5efe4ea7b598Elan Ruusamäe fprintf(stderr, "root privileges needed to subscribe to kernel events\n");
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane goto out;
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane }
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane /* set signal handlers */
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane memset(&act, 0x00, sizeof(struct sigaction));
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane act.sa_handler = (void (*)(int)) sig_handler;
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane sigemptyset(&act.sa_mask);
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane act.sa_flags = SA_RESTART;
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane sigaction(SIGINT, &act, NULL);
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane sigaction(SIGTERM, &act, NULL);
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane printf("udevmonitor will print the received events for:\n");
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane if (udev) {
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane retval = init_udev_monitor_socket();
148315348760faf4ad822ded7c416d2de8050937Alexander Vladimirov if (retval)
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov goto out;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov printf("UDEV the event which udev sends out after rule processing\n");
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov }
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane if (kernel) {
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane retval = init_uevent_netlink_sock();
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane if (retval)
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane goto out;
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane printf("UEVENT the kernel uevent\n");
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane }
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane printf("\n");
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov while (!udev_exit) {
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov char buf[UEVENT_BUFFER_SIZE*2];
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov ssize_t buflen;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov ssize_t bufpos;
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov ssize_t keys;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov int fdcount;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov struct timeval tv;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov struct timezone tz;
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov char timestr[64];
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov const char *source = NULL;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov const char *devpath, *action, *subsys;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov buflen = 0;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov FD_ZERO(&readfds);
012f591a7df0a3cb025905ba2e7d2033b550dac1John Lane if (uevent_netlink_sock >= 0)
148315348760faf4ad822ded7c416d2de8050937Alexander Vladimirov FD_SET(uevent_netlink_sock, &readfds);
b408e70daff7b36ac1f0ef4c86f70072c2f38480Stéphane Graber if (udev_monitor_sock >= 0)
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov FD_SET(udev_monitor_sock, &readfds);
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov
d0800999b2aff2c2445e1ac18905fddbfe71cb8cJohn Lane fdcount = select(UDEV_MAX(uevent_netlink_sock, udev_monitor_sock)+1, &readfds, NULL, NULL, NULL);
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov if (fdcount < 0) {
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov if (errno != EINTR)
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov fprintf(stderr, "error receiving uevent message: %s\n", strerror(errno));
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov continue;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov }
d0800999b2aff2c2445e1ac18905fddbfe71cb8cJohn Lane
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov if (gettimeofday(&tv, &tz) == 0) {
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov snprintf(timestr, sizeof(timestr), "%llu.%06u",
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov (unsigned long long) tv.tv_sec, (unsigned int) tv.tv_usec);
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov } else
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov timestr[0] = '\0';
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov if ((uevent_netlink_sock >= 0) && FD_ISSET(uevent_netlink_sock, &readfds)) {
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov buflen = recv(uevent_netlink_sock, &buf, sizeof(buf), 0);
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov if (buflen <= 0) {
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov fprintf(stderr, "error receiving uevent message: %s\n", strerror(errno));
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov continue;
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov }
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn source = "UEVENT";
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov }
012f591a7df0a3cb025905ba2e7d2033b550dac1John Lane
148315348760faf4ad822ded7c416d2de8050937Alexander Vladimirov if ((udev_monitor_sock >= 0) && FD_ISSET(udev_monitor_sock, &readfds)) {
734d0bed55ea17793510e1ce1de34ebc8c5eb6abJohn Lane buflen = recv(udev_monitor_sock, &buf, sizeof(buf), 0);
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov if (buflen <= 0) {
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov fprintf(stderr, "error receiving udev message: %s\n", strerror(errno));
d0800999b2aff2c2445e1ac18905fddbfe71cb8cJohn Lane continue;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov }
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov source = "UDEV ";
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov }
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov if (buflen == 0)
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov continue;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov keys = strlen(buf) + 1; /* start of payload */
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov devpath = search_key("DEVPATH", &buf[keys], buflen);
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov action = search_key("ACTION", &buf[keys], buflen);
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov subsys = search_key("SUBSYSTEM", &buf[keys], buflen);
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov printf("%s[%s] %-8s %s (%s)\n", source, timestr, action, devpath, subsys);
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov /* print environment */
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov bufpos = keys;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov if (env) {
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov while (bufpos < buflen) {
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov int keylen;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov char *key;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov key = &buf[bufpos];
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov keylen = strlen(key);
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov if (keylen == 0)
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov break;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov printf("%s\n", key);
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov bufpos += keylen + 1;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov }
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov printf("\n");
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov }
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov }
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallynout:
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn if (uevent_netlink_sock >= 0)
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov close(uevent_netlink_sock);
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov if (udev_monitor_sock >= 0)
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov close(udev_monitor_sock);
f3849d01d8f31785bf933ffcf91a419c4ff2257dAlexander Vladimirov
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov if (retval)
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov return 1;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov return 0;
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov}
f6267d9011eea5074028dc44b49df3bd3df7443cAlexander Vladimirov