libudev-queue.c revision 090be8653471e1abe3f1cdd32eaad0fbd65f85cd
/***
This file is part of systemd.
Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
Copyright 2009 Alan Jenkins <alan-jenkins@tuffmail.co.uk>
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>
#include <stddef.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <dirent.h>
#include <fcntl.h>
#include <limits.h>
#include "libudev.h"
#include "libudev-private.h"
/**
* SECTION:libudev-queue
* @short_description: access to currently active events
*
* The udev daemon processes events asynchronously. All events which do not have
* interdependencies run in parallel. This exports the current state of the
* event processing queue, and the current event sequence numbers from the kernel
* and the udev daemon.
*/
/**
* udev_queue:
*
* Opaque object representing the current event queue in the udev daemon.
*/
struct udev_queue {
int refcount;
struct udev_list queue_list;
};
/**
* udev_queue_new:
* @udev: udev library context
*
* The initial refcount is 1, and needs to be decremented to
* release the resources of the udev queue context.
*
* Returns: the udev queue context, or #NULL on error.
**/
{
struct udev_queue *udev_queue;
return NULL;
if (udev_queue == NULL)
return NULL;
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.
**/
{
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: the passed queue context if it has still an active reference, or #NULL otherwise.
**/
{
if (udev_queue == NULL)
return NULL;
udev_queue->refcount--;
if (udev_queue->refcount > 0)
return 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.
**/
{
if (udev_queue == NULL)
return NULL;
return udev_queue->udev;
}
{
unsigned long long int seqnum;
int fd;
char buf[32];
if (fd < 0)
return 0;
if (len <= 2)
return 0;
return seqnum;
}
/**
* udev_queue_get_kernel_seqnum:
* @udev_queue: udev queue context
*
* Get the current kernel event sequence number.
*
* Returns: the sequence number.
**/
{
unsigned long long int seqnum;
if (udev_queue == NULL)
return -EINVAL;
return seqnum;
}
{
return -1;
return 0;
}
{
unsigned short int len;
/* use fread to skip, fseek might drop buffered data */
return len;
}
return -1;
}
{
unsigned short int read_bytes = 0;
unsigned short int len;
return -1;
return -1;
/* if devpath was too long, skip unread characters */
if (read_bytes != len) {
return -1;
}
return read_bytes;
}
{
if (queue_file == NULL)
return NULL;
return NULL;
}
return queue_file;
}
/**
* udev_queue_get_udev_seqnum:
* @udev_queue: udev queue context
*
* Get the last known udev event sequence number.
*
* Returns: the sequence number.
**/
{
unsigned long long int seqnum_udev;
if (queue_file == NULL)
return 0;
for (;;) {
unsigned long long int seqnum;
break;
if (devpath_len < 0)
break;
if (devpath_len > 0)
}
return seqnum_udev;
}
/**
* 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.
**/
{
unsigned long long int seqnum_start;
if (queue_file == NULL)
return 0;
return 1;
}
/**
* 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.
**/
{
unsigned long long int seqnum_kernel;
unsigned long long int seqnum_udev = 0;
int queued = 0;
int is_empty = 0;
if (udev_queue == NULL)
return -EINVAL;
if (queue_file == NULL)
return 1;
for (;;) {
unsigned long long int seqnum;
break;
if (devpath_len < 0)
break;
if (devpath_len > 0) {
queued++;
} else {
queued--;
}
}
if (queued > 0)
goto out;
if (seqnum_udev < seqnum_kernel)
goto out;
is_empty = 1;
out:
return is_empty;
}
/**
* udev_queue_get_seqnum_sequence_is_finished:
* @udev_queue: udev queue context
* @start: first event sequence number
* @end: last event sequence number
*
* Check if udev is currently processing any events in a given sequence number range.
*
* Returns: a flag indicating if any of the sequence numbers in the given range is currently active.
**/
{
unsigned long long int seqnum;
int unfinished;
if (udev_queue == NULL)
return -EINVAL;
if (queue_file == NULL)
return 1;
return 1;
}
return -EOVERFLOW;
}
/*
* we might start with 0, and handle the initial seqnum
* only when we find an entry in the queue file
**/
do {
break;
if (devpath_len < 0)
break;
/*
* we might start with an empty or re-build queue file, where
* the initial seqnum is not recorded as finished
*/
unfinished++;
if (devpath_len == 0) {
unfinished--;
}
} while (unfinished > 0);
return (unfinished == 0);
}
/**
* udev_queue_get_seqnum_is_finished:
* @udev_queue: udev queue context
* @seqnum: sequence number
*
* Check if udev is currently processing a given sequence number.
*
* Returns: a flag indicating if the given sequence number is currently active.
**/
_public_ int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum)
{
return 0;
return 1;
}
/**
* udev_queue_get_queued_list_entry:
* @udev_queue: udev queue context
*
* Get the first entry of the list of queued events.
*
* Returns: a udev_list_entry.
**/
{
unsigned long long int seqnum;
if (udev_queue == NULL)
return NULL;
if (queue_file == NULL)
return NULL;
for (;;) {
char syspath[UTIL_PATH_SIZE];
char *s;
size_t l;
char seqnum_str[32];
struct udev_list_entry *list_entry;
break;
s = syspath;
if (len < 0)
break;
if (len > 0) {
} else {
break;
}
}
}
}
}