X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibudev%2Flibudev-monitor.c;h=24efdc65e2908c6cb83f476e4be7ba7a914a70cf;hp=73a9c48993bffd45df4548bc389dd1ffef31d45c;hb=994e023433e020e2b3f683d5d1f2c974db580447;hpb=8fef0ff25c9fd7e5bb99d66f43c6357e4996a3cc diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c index 73a9c4899..24efdc65e 100644 --- a/src/libudev/libudev-monitor.c +++ b/src/libudev/libudev-monitor.c @@ -1,13 +1,21 @@ -/* - * libudev - interface to udev device information - * - * Copyright (C) 2008-2010 Kay Sievers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - */ +/*** + This file is part of systemd. + + Copyright 2008-2012 Kay Sievers + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ #include #include @@ -97,23 +105,6 @@ static struct udev_monitor *udev_monitor_new(struct udev *udev) return udev_monitor; } -/** - * udev_monitor_new_from_socket: - * @udev: udev library context - * @socket_path: unix socket path - * - * This function is removed from libudev and will not do anything. - * - * Returns: #NULL - **/ -struct udev_monitor *udev_monitor_new_from_socket(struct udev *udev, const char *socket_path); -_public_ struct udev_monitor *udev_monitor_new_from_socket(struct udev *udev, const char *socket_path) -{ - err(udev, "udev_monitor_new_from_socket() does not do anything; please migrate to netlink\n"); - errno = ENOSYS; - return NULL; -} - struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const char *name, int fd) { struct udev_monitor *udev_monitor; @@ -124,9 +115,9 @@ struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const c if (name == NULL) group = UDEV_MONITOR_NONE; - else if (strcmp(name, "udev") == 0) + else if (streq(name, "udev")) group = UDEV_MONITOR_UDEV; - else if (strcmp(name, "kernel") == 0) + else if (streq(name, "kernel")) group = UDEV_MONITOR_KERNEL; else return NULL; @@ -138,7 +129,7 @@ struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const c if (fd < 0) { udev_monitor->sock = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT); if (udev_monitor->sock == -1) { - err(udev, "error getting socket: %m\n"); + udev_err(udev, "error getting socket: %m\n"); free(udev_monitor); return NULL; } @@ -297,7 +288,7 @@ _public_ int udev_monitor_filter_update(struct udev_monitor *udev_monitor) bpf_stmt(ins, &i, BPF_RET|BPF_K, 0xffffffff); if (i+1 >= ELEMENTSOF(ins)) - return -1; + return -E2BIG; } /* nothing matched, drop packet */ @@ -312,7 +303,7 @@ _public_ int udev_monitor_filter_update(struct udev_monitor *udev_monitor) filter.len = i; filter.filter = ins; err = setsockopt(udev_monitor->sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)); - return err; + return err < 0 ? -errno : 0; } int udev_monitor_allow_unicast_sender(struct udev_monitor *udev_monitor, struct udev_monitor *sender) @@ -358,8 +349,8 @@ _public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor) if (err == 0) udev_monitor->snl.nl.nl_pid = snl.nl.nl_pid; } else { - err(udev_monitor->udev, "bind failed: %m\n"); - return err; + udev_err(udev_monitor->udev, "bind failed: %m\n"); + return -errno; } /* enable receiving of sender credentials */ @@ -380,7 +371,7 @@ _public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor) _public_ int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor, int size) { if (udev_monitor == NULL) - return -1; + return -EINVAL; return setsockopt(udev_monitor->sock, SOL_SOCKET, SO_RCVBUFFORCE, &size, sizeof(size)); } @@ -390,7 +381,7 @@ int udev_monitor_disconnect(struct udev_monitor *udev_monitor) err = close(udev_monitor->sock); udev_monitor->sock = -1; - return err; + return err < 0 ? -errno : 0; } /** @@ -417,19 +408,21 @@ _public_ struct udev_monitor *udev_monitor_ref(struct udev_monitor *udev_monitor * the bound socket will be closed, and the resources of the monitor * will be released. * + * Returns: the passed udev monitor if it has still an active reference, or #NULL otherwise. **/ -_public_ void udev_monitor_unref(struct udev_monitor *udev_monitor) +_public_ struct udev_monitor *udev_monitor_unref(struct udev_monitor *udev_monitor) { if (udev_monitor == NULL) - return; + return NULL; udev_monitor->refcount--; if (udev_monitor->refcount > 0) - return; + return udev_monitor; if (udev_monitor->sock >= 0) close(udev_monitor->sock); udev_list_cleanup(&udev_monitor->filter_subsystem_list); udev_list_cleanup(&udev_monitor->filter_tag_list); free(udev_monitor); + return NULL; } /** @@ -458,7 +451,7 @@ _public_ struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor) _public_ int udev_monitor_get_fd(struct udev_monitor *udev_monitor) { if (udev_monitor == NULL) - return -1; + return -EINVAL; return udev_monitor->sock; } @@ -474,7 +467,7 @@ static int passes_filter(struct udev_monitor *udev_monitor, struct udev_device * const char *devtype; const char *ddevtype; - if (strcmp(dsubsys, subsys) != 0) + if (!streq(dsubsys, subsys)) continue; devtype = udev_list_entry_get_value(list_entry); @@ -483,7 +476,7 @@ static int passes_filter(struct udev_monitor *udev_monitor, struct udev_device * ddevtype = udev_device_get_devtype(udev_device); if (ddevtype == NULL) continue; - if (strcmp(ddevtype, devtype) == 0) + if (streq(ddevtype, devtype)) goto tag; } return 0; @@ -509,6 +502,11 @@ tag: * * Only socket connections with uid=0 are accepted. * + * The monitor socket is by default set to NONBLOCK. A variant of poll() on + * the file descriptor returned by udev_monitor_get_fd() should to be used to + * wake up when new devices arrive, or alternatively the file descriptor + * switched into blocking mode. + * * The initial refcount is 1, and needs to be decremented to * release the resources of the udev device. * @@ -547,12 +545,12 @@ retry: buflen = recvmsg(udev_monitor->sock, &smsg, 0); if (buflen < 0) { if (errno != EINTR) - dbg(udev_monitor->udev, "unable to receive message\n"); + udev_dbg(udev_monitor->udev, "unable to receive message\n"); return NULL; } if (buflen < 32 || (size_t)buflen >= sizeof(buf)) { - dbg(udev_monitor->udev, "invalid message length\n"); + udev_dbg(udev_monitor->udev, "invalid message length\n"); return NULL; } @@ -561,12 +559,12 @@ retry: /* unicast message, check if we trust the sender */ if (udev_monitor->snl_trusted_sender.nl.nl_pid == 0 || snl.nl.nl_pid != udev_monitor->snl_trusted_sender.nl.nl_pid) { - dbg(udev_monitor->udev, "unicast netlink message ignored\n"); + udev_dbg(udev_monitor->udev, "unicast netlink message ignored\n"); return NULL; } } else if (snl.nl.nl_groups == UDEV_MONITOR_KERNEL) { if (snl.nl.nl_pid > 0) { - dbg(udev_monitor->udev, "multicast kernel netlink message from pid %d ignored\n", + udev_dbg(udev_monitor->udev, "multicast kernel netlink message from pid %d ignored\n", snl.nl.nl_pid); return NULL; } @@ -575,13 +573,13 @@ retry: cmsg = CMSG_FIRSTHDR(&smsg); if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { - dbg(udev_monitor->udev, "no sender credentials received, message ignored\n"); + udev_dbg(udev_monitor->udev, "no sender credentials received, message ignored\n"); return NULL; } cred = (struct ucred *)CMSG_DATA(cmsg); if (cred->uid != 0) { - dbg(udev_monitor->udev, "sender uid=%d, message ignored\n", cred->uid); + udev_dbg(udev_monitor->udev, "sender uid=%d, message ignored\n", cred->uid); return NULL; } @@ -589,24 +587,24 @@ retry: /* udev message needs proper version magic */ nlh = (struct udev_monitor_netlink_header *) buf; if (nlh->magic != htonl(UDEV_MONITOR_MAGIC)) { - err(udev_monitor->udev, "unrecognized message signature (%x != %x)\n", + udev_err(udev_monitor->udev, "unrecognized message signature (%x != %x)\n", nlh->magic, htonl(UDEV_MONITOR_MAGIC)); return NULL; } - if (nlh->properties_off+32 > buflen) + if (nlh->properties_off+32 > (size_t)buflen) return NULL; bufpos = nlh->properties_off; } else { /* kernel message with header */ bufpos = strlen(buf) + 1; if ((size_t)bufpos < sizeof("a@/d") || bufpos >= buflen) { - dbg(udev_monitor->udev, "invalid message length\n"); + udev_dbg(udev_monitor->udev, "invalid message length\n"); return NULL; } /* check message header */ if (strstr(buf, "@/") == NULL) { - dbg(udev_monitor->udev, "unrecognized message header\n"); + udev_dbg(udev_monitor->udev, "unrecognized message header\n"); return NULL; } } @@ -629,7 +627,7 @@ retry: } if (udev_device_add_property_from_string_parse_finish(udev_device) < 0) { - dbg(udev_monitor->udev, "missing values, invalid device\n"); + udev_dbg(udev_monitor->udev, "missing values, invalid device\n"); udev_device_unref(udev_device); return NULL; } @@ -716,7 +714,7 @@ int udev_monitor_send_device(struct udev_monitor *udev_monitor, smsg.msg_name = &udev_monitor->snl_destination; smsg.msg_namelen = sizeof(struct sockaddr_nl); count = sendmsg(udev_monitor->sock, &smsg, 0); - dbg(udev_monitor->udev, "passed %zi bytes to netlink monitor %p\n", count, udev_monitor); + udev_dbg(udev_monitor->udev, "passed %zi bytes to netlink monitor %p\n", count, udev_monitor); return count; }