libudev-queue.c revision 93a1e66efd4b0f4cda29c467d20d0f7510c0b3a8
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering/***
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering This file is part of systemd.
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering Copyright 2009 Alan Jenkins <alan-jenkins@tuffmail.co.uk>
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering systemd is free software; you can redistribute it and/or modify it
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering under the terms of the GNU Lesser General Public License as published by
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering (at your option) any later version.
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering systemd is distributed in the hope that it will be useful, but
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering Lesser General Public License for more details.
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering You should have received a copy of the GNU Lesser General Public License
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering***/
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering#include <stdio.h>
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering#include <stdlib.h>
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering#include <stddef.h>
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering#include <unistd.h>
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering#include <errno.h>
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering#include <string.h>
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering#include <limits.h>
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering#include <sys/stat.h>
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering#include <sys/inotify.h>
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering#include "libudev.h"
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering#include "libudev-private.h"
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering/**
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering * SECTION:libudev-queue
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering * @short_description: access to currently active events
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering *
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering * This exports the current state of the udev processing queue.
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering */
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering/**
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering * udev_queue:
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering *
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering * Opaque object representing the current event queue in the udev daemon.
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering */
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poetteringstruct udev_queue {
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering struct udev *udev;
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering int refcount;
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering int fd;
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering};
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering/**
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering * udev_queue_new:
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering * @udev: udev library context
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering *
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering * The initial refcount is 1, and needs to be decremented to
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering * release the resources of the udev queue context.
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering *
f0213e3796b4dd66e546e2de4d677db319f9171bTom Gundersen * Returns: the udev queue context, or #NULL on error.
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering **/
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering_public_ struct udev_queue *udev_queue_new(struct udev *udev)
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering{
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering struct udev_queue *udev_queue;
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering if (udev == NULL)
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering return NULL;
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering udev_queue = new0(struct udev_queue, 1);
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering if (udev_queue == NULL)
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering return NULL;
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering udev_queue->refcount = 1;
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering udev_queue->udev = udev;
udev_queue->fd = -1;
return udev_queue;
}
/**
* udev_queue_ref:
* @udev_queue: udev queue context
*
* Take a reference of a 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:
* @udev_queue: udev queue context
*
* Drop a reference of a udev queue context. If the refcount reaches zero,
* the resources of the queue context will be released.
*
* 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;
}
/**
* udev_queue_get_udev:
* @udev_queue: udev queue context
*
* Retrieve the udev library context the queue context was created with.
*
* Returns: the udev library context.
**/
_public_ struct udev *udev_queue_get_udev(struct udev_queue *udev_queue)
{
if (udev_queue == NULL)
return NULL;
return udev_queue->udev;
}
/**
* udev_queue_get_kernel_seqnum:
* @udev_queue: udev queue context
*
* This function is deprecated.
*
* Returns: 0.
**/
_public_ unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue)
{
return 0;
}
/**
* udev_queue_get_udev_seqnum:
* @udev_queue: udev queue context
*
* This function is deprecated.
*
* Returns: 0.
**/
_public_ unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue)
{
return 0;
}
/**
* udev_queue_get_udev_is_active:
* @udev_queue: udev queue context
*
* Check if udev is active on the system.
*
* Returns: a flag indicating if udev is active.
**/
_public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue)
{
return access("/run/udev/control", F_OK) >= 0;
}
/**
* udev_queue_get_queue_is_empty:
* @udev_queue: udev queue context
*
* Check if udev is currently processing any events.
*
* Returns: a flag indicating if udev is currently handling events.
**/
_public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue)
{
return access("/run/udev/queue", F_OK) < 0;
}
/**
* udev_queue_get_seqnum_sequence_is_finished:
* @udev_queue: udev queue context
* @start: first event sequence number
* @end: last event sequence number
*
* This function is deprecated, it just returns the result of
* udev_queue_get_queue_is_empty().
*
* 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)
{
return udev_queue_get_queue_is_empty(udev_queue);
}
/**
* udev_queue_get_seqnum_is_finished:
* @udev_queue: udev queue context
* @seqnum: sequence number
*
* This function is deprecated, it just returns the result of
* udev_queue_get_queue_is_empty().
*
* 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)
{
return udev_queue_get_queue_is_empty(udev_queue);
}
/**
* udev_queue_get_queued_list_entry:
* @udev_queue: udev queue context
*
* This function is deprecated.
*
* Returns: NULL.
**/
_public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue)
{
return NULL;
}
/**
* udev_queue_get_fd:
* @udev_queue: udev queue context
*
* 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;
if (udev_queue->fd >= 0)
return udev_queue->fd;
fd = inotify_init1(IN_CLOEXEC);
if (fd < 0)
return -errno;
r = inotify_add_watch(fd, "/run/udev" , IN_DELETE);
if (r < 0) {
r = -errno;
close(fd);
return r;
}
udev_queue->fd = fd;
return fd;
}
/**
* udev_queue_flush:
* @udev_queue: udev queue context
*
* Returns: the result of clearing the watch for queue changes.
*/
_public_ int udev_queue_flush(struct udev_queue *udev_queue) {
if (udev_queue->fd < 0)
return -EINVAL;
return flush_fd(udev_queue->fd);
}
__asm__(".symver udev_queue_flush,udev_queue_flush@LIBUDEV_183");
__asm__(".symver udev_queue_get_fd,udev_queue_get_fd@LIBUDEV_183");