chiark / gitweb /
libudev: always return valid negative error codes on API functions
[elogind.git] / src / libudev / libudev-monitor.c
index 32319aca7b195ee13bb1f0110e1f2148ce66ffa3..24efdc65e2908c6cb83f476e4be7ba7a914a70cf 100644 (file)
@@ -1,13 +1,21 @@
-/*
- * libudev - interface to udev device information
- *
- * Copyright (C) 2008-2010 Kay Sievers <kay.sievers@vrfy.org>
- *
- * 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 <kay@vrfy.org>
+
+  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 <http://www.gnu.org/licenses/>.
+***/
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -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;
 }
 
 /**
@@ -443,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;
 }
 
@@ -459,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);
@@ -468,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;
@@ -494,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.
  *