X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibudev%2Flibudev-monitor.c;h=56a6c5e39a6c1cdfed19a37c7e33fadec3859de9;hb=e7176abbe818c75c6acd90227a7a84c3e05fee31;hp=96506fe580c73a8d74a2fafd844a9c2950456d1d;hpb=20bbd54f603994a3cc211d2795de16550882ed8d;p=elogind.git diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c index 96506fe58..56a6c5e39 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 @@ -107,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; @@ -280,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 */ @@ -295,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) @@ -342,7 +350,7 @@ _public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor) udev_monitor->snl.nl.nl_pid = snl.nl.nl_pid; } else { udev_err(udev_monitor->udev, "bind failed: %m\n"); - return err; + return -errno; } /* enable receiving of sender credentials */ @@ -363,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)); } @@ -373,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; } /** @@ -400,6 +408,7 @@ _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: #NULL **/ _public_ struct udev_monitor *udev_monitor_unref(struct udev_monitor *udev_monitor) { @@ -407,7 +416,7 @@ _public_ struct udev_monitor *udev_monitor_unref(struct udev_monitor *udev_monit return NULL; udev_monitor->refcount--; if (udev_monitor->refcount > 0) - return udev_monitor; + return NULL; if (udev_monitor->sock >= 0) close(udev_monitor->sock); udev_list_cleanup(&udev_monitor->filter_subsystem_list); @@ -442,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; } @@ -458,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); @@ -467,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; @@ -493,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. * @@ -577,7 +591,7 @@ retry: 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 {