+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
- This file is part of systemd.
-
- Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
- Copyright 2009 Alan Jenkins <alan-jenkins@tuffmail.co.uk>
-
- 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/>.
+ Copyright © 2009 Alan Jenkins <alan-jenkins@tuffmail.co.uk>
***/
#include <errno.h>
#include <sys/inotify.h>
#include <unistd.h>
+#include "libudev.h"
+
#include "alloc-util.h"
#include "fd-util.h"
#include "io-util.h"
-#include "libudev-private.h"
/**
* SECTION:libudev-queue
*/
struct udev_queue {
struct udev *udev;
- int refcount;
+ unsigned n_ref;
int fd;
};
*
* Returns: the udev queue context, or #NULL on error.
**/
-_public_ struct udev_queue *udev_queue_new(struct udev *udev)
-{
+_public_ struct udev_queue *udev_queue_new(struct udev *udev) {
struct udev_queue *udev_queue;
- if (udev == NULL) {
- errno = EINVAL;
- return NULL;
- }
+ udev_queue = new(struct udev_queue, 1);
+ if (!udev_queue)
+ return_with_errno(NULL, ENOMEM);
- udev_queue = new0(struct udev_queue, 1);
- if (udev_queue == NULL) {
- errno = ENOMEM;
- return NULL;
- }
+ *udev_queue = (struct udev_queue) {
+ .udev = udev,
+ .n_ref = 1,
+ .fd = -1,
+ };
- udev_queue->refcount = 1;
- udev_queue->udev = udev;
- udev_queue->fd = -1;
return udev_queue;
}
+static struct udev_queue *udev_queue_free(struct udev_queue *udev_queue) {
+ assert(udev_queue);
+
+ safe_close(udev_queue->fd);
+ return mfree(udev_queue);
+}
+
/**
* udev_queue_ref:
* @udev_queue: udev queue context
*
* Returns: the same udev queue context.
**/
-_public_ struct udev_queue *udev_queue_ref(struct udev_queue *udev_queue)
-{
- if (udev_queue == NULL)
- return NULL;
-
- udev_queue->refcount++;
- return udev_queue;
-}
/**
* udev_queue_unref:
*
* Returns: #NULL
**/
-_public_ struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue)
-{
- if (udev_queue == NULL)
- return NULL;
-
- udev_queue->refcount--;
- if (udev_queue->refcount > 0)
- return NULL;
-
- safe_close(udev_queue->fd);
-
- free(udev_queue);
- return NULL;
-}
+DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_queue, udev_queue, udev_queue_free);
/**
* udev_queue_get_udev:
*
* Returns: the udev library context.
**/
-_public_ struct udev *udev_queue_get_udev(struct udev_queue *udev_queue)
-{
- if (udev_queue == NULL) {
- errno = EINVAL;
- return NULL;
- }
+_public_ struct udev *udev_queue_get_udev(struct udev_queue *udev_queue) {
+ assert_return_errno(udev_queue, NULL, EINVAL);
+
return udev_queue->udev;
}
*
* Returns: 0.
**/
-_public_ unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue)
-{
+_public_ unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue) {
return 0;
}
*
* Returns: 0.
**/
-_public_ unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue)
-{
+_public_ unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue) {
return 0;
}
*
* Returns: a flag indicating if udev is active.
**/
-_public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue)
-{
+_public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue) {
return access("/run/udev/control", F_OK) >= 0;
}
*
* Returns: a flag indicating if udev is currently handling events.
**/
-_public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue)
-{
+_public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue) {
return access("/run/udev/queue", F_OK) < 0;
}
* Returns: a flag indicating if udev is currently handling events.
**/
_public_ int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue,
- unsigned long long int start, unsigned long long int end)
-{
+ unsigned long long int start, unsigned long long int end) {
return udev_queue_get_queue_is_empty(udev_queue);
}
*
* Returns: a flag indicating if udev is currently handling events.
**/
-_public_ int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum)
-{
+_public_ int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum) {
return udev_queue_get_queue_is_empty(udev_queue);
}
*
* Returns: NULL.
**/
-_public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue)
-{
- errno = ENODATA;
- return NULL;
+_public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue) {
+ return_with_errno(NULL, ENODATA);
}
/**
* Returns: a file descriptor to watch for a queue to become empty.
*/
_public_ int udev_queue_get_fd(struct udev_queue *udev_queue) {
- int fd;
- int r;
+ _cleanup_close_ int fd = -1;
+
+ assert_return(udev_queue, -EINVAL);
if (udev_queue->fd >= 0)
return udev_queue->fd;
if (fd < 0)
return -errno;
- r = inotify_add_watch(fd, "/run/udev" , IN_DELETE);
- if (r < 0) {
- r = -errno;
- close(fd);
- return r;
- }
+ if (inotify_add_watch(fd, "/run/udev" , IN_DELETE) < 0)
+ return -errno;
- udev_queue->fd = fd;
- return fd;
+ udev_queue->fd = TAKE_FD(fd);
+ return udev_queue->fd;
}
/**
* Returns: the result of clearing the watch for queue changes.
*/
_public_ int udev_queue_flush(struct udev_queue *udev_queue) {
+ int r;
+
+ assert_return(udev_queue, -EINVAL);
+
if (udev_queue->fd < 0)
return -EINVAL;
- return flush_fd(udev_queue->fd);
+ r = flush_fd(udev_queue->fd);
+ if (r < 0)
+ return r;
+
+ return 0;
}