Example #1
0
static ssize_t uinput_inject_events(struct uinput_device *udev,
                                    const char __user *buffer, size_t count)
{
    struct input_event ev;
    size_t bytes = 0;

    if (count != 0 && count < input_event_size())
        return -EINVAL;

    while (bytes + input_event_size() <= count) {
        /*
         * Note that even if some events were fetched successfully
         * we are still going to return EFAULT instead of partial
         * count to let userspace know that it got it's buffers
         * all wrong.
         */
        if (input_event_from_user(buffer + bytes, &ev))
            return -EFAULT;

        input_event(udev->dev, ev.type, ev.code, ev.value);
        bytes += input_event_size();
    }

    return bytes;
}
Example #2
0
static inline ssize_t uinput_inject_event(struct uinput_device *udev, const char __user *buffer, size_t count)
{
	struct input_event ev;

	if (count < input_event_size())
		return -EINVAL;

	if (input_event_from_user(buffer, &ev))
		return -EFAULT;

	input_event(udev->dev, ev.type, ev.code, ev.value);

	return input_event_size();
}
Example #3
0
static ssize_t uinput_read(struct file *file, char __user *buffer,
                           size_t count, loff_t *ppos)
{
    struct uinput_device *udev = file->private_data;
    ssize_t retval;

    if (count != 0 && count < input_event_size())
        return -EINVAL;

    do {
        retval = mutex_lock_interruptible(&udev->mutex);
        if (retval)
            return retval;

        if (udev->state != UIST_CREATED)
            retval = -ENODEV;
        else if (udev->head == udev->tail &&
                 (file->f_flags & O_NONBLOCK))
            retval = -EAGAIN;
        else
            retval = uinput_events_to_user(udev, buffer, count);

        mutex_unlock(&udev->mutex);

        if (retval || count == 0)
            break;

        if (!(file->f_flags & O_NONBLOCK))
            retval = wait_event_interruptible(udev->waitq,
                                              udev->head != udev->tail ||
                                              udev->state != UIST_CREATED);
    } while (retval == 0);

    return retval;
}
Example #4
0
static ssize_t uinput_events_to_user(struct uinput_device *udev,
                                     char __user *buffer, size_t count)
{
    struct input_event event;
    size_t read = 0;

    while (read + input_event_size() <= count &&
            uinput_fetch_next_event(udev, &event)) {

        if (input_event_to_user(buffer + read, &event))
            return -EFAULT;

        read += input_event_size();
    }

    return read;
}
Example #5
0
static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
	struct uinput_device *udev = file->private_data;
	int retval = 0;

	if (udev->state != UIST_CREATED)
		return -ENODEV;

	if (udev->head == udev->tail && (file->f_flags & O_NONBLOCK))
		return -EAGAIN;

	retval = wait_event_interruptible(udev->waitq,
			udev->head != udev->tail || udev->state != UIST_CREATED);
	if (retval)
		return retval;

	retval = mutex_lock_interruptible(&udev->mutex);
	if (retval)
		return retval;

	if (udev->state != UIST_CREATED) {
		retval = -ENODEV;
		goto out;
	}

	while (udev->head != udev->tail && retval + input_event_size() <= count) {
		if (input_event_to_user(buffer + retval, &udev->buff[udev->tail])) {
			retval = -EFAULT;
			goto out;
		}
		udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE;
		retval += input_event_size();
	}

 out:
	mutex_unlock(&udev->mutex);

	return retval;
}