]> git.neil.brown.name Git - history.git/commitdiff
Fix oops when 'cat /dev/uinput' is done. Used wait_event_interruptible().
authorVojtech Pavlik <vojtech@suse.cz>
Wed, 9 Oct 2002 14:12:55 +0000 (16:12 +0200)
committerVojtech Pavlik <vojtech@suse.cz>
Wed, 9 Oct 2002 14:12:55 +0000 (16:12 +0200)
drivers/input/misc/uinput.c

index dc72f6b2c4938918a74402fd887674e5fcea846e..80ae77dfeb001a74ca8e8720d2c0cf5be6b4b131 100644 (file)
@@ -218,43 +218,25 @@ static int uinput_write(struct file *file, const char *buffer, size_t count, lof
 
 static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
 {
-       struct uinput_device    *udev;
+       struct uinput_device *udev = file->private_data;
        int retval = 0;
-       DECLARE_WAITQUEUE(waitq, current);
 
-       udev = (struct uinput_device *)file->private_data;
+       if (udev->head == udev->tail && (udev->state & UIST_CREATED) && (file->f_flags & O_NONBLOCK))
+               return -EAGAIN;
 
-       if (udev->head == udev->tail) {
-               add_wait_queue(&udev->waitq, &waitq);
-               current->state = TASK_INTERRUPTIBLE;
-
-               while (udev->head == udev->tail) {
-                       if (!(udev->state & UIST_CREATED)) {
-                               retval = -ENODEV;
-                               break;
-                       }
-                       if (file->f_flags & O_NONBLOCK) {
-                               retval = -EAGAIN;
-                               break;
-                       }
-                       if (signal_pending(current)) {
-                               retval = -ERESTARTSYS;
-                               break;
-                       }
-                       schedule();
-               }
-               current->state = TASK_RUNNING;
-               remove_wait_queue(&udev->waitq, &waitq);
-       }
+       retval = wait_event_interruptible(udev->waitq,
+               udev->head != udev->tail && (udev->state & UIST_CREATED));
 
        if (retval)
                return retval;
 
+       if (!(udev->state & UIST_CREATED))
+               return -ENODEV;
+
        while (udev->head != udev->tail && retval + sizeof(struct uinput_device) <= count) {
                if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]),
-                   sizeof(struct input_event)))
-                       return -EFAULT;
-               udev->tail = (udev->tail + 1)%(UINPUT_BUFFER_SIZE - 1);
+                   sizeof(struct input_event))) return -EFAULT;
+               udev->tail = (udev->tail + 1) % (UINPUT_BUFFER_SIZE - 1);
                retval += sizeof(struct input_event);
        }