[PATCH 2/3] Input: evdev - return proper value for partial reads

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If we encounter an error in middle of transferring several events to
userspace we should return number of bytes successfully transferred
instead of error code. If transfer fails on the very first event then
we can return error code.

Signed-off-by: Dmitry Torokhov <dtor@xxxxxxx>
---
 drivers/input/evdev.c |   26 +++++++++++++++-----------
 1 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 0e32b6a..8f59fc1 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -398,35 +398,39 @@ static ssize_t evdev_read(struct file *file, char __user *buffer,
 	struct evdev_client *client = file->private_data;
 	struct evdev *evdev = client->evdev;
 	struct input_event event;
-	int retval = 0;
+	int read = 0;
+	int error = 0;
 
 	if (count < input_event_size())
 		return -EINVAL;
 
 	if (!(file->f_flags & O_NONBLOCK)) {
-		retval = wait_event_interruptible(evdev->wait,
+		error = wait_event_interruptible(evdev->wait,
 				client->packet_head != client->tail ||
 				!evdev->exist);
-		if (retval)
-			return retval;
+		if (error)
+			return error;
 	}
 
 	if (!evdev->exist)
 		return -ENODEV;
 
-	while (retval + input_event_size() <= count &&
+	while (read + input_event_size() <= count &&
 	       evdev_fetch_next_event(client, &event)) {
 
-		if (input_event_to_user(buffer + retval, &event))
-			return -EFAULT;
+		if (input_event_to_user(buffer + read, &event)) {
+			error = -EFAULT;
+			goto out;
+		}
 
-		retval += input_event_size();
+		read += input_event_size();
 	}
 
-	if (retval == 0 && (file->f_flags & O_NONBLOCK))
-		return -EAGAIN;
+	if (read == 0 && (file->f_flags & O_NONBLOCK))
+		error = -EAGAIN;
 
-	return retval;
+out:
+	return read ?: error;
 }
 
 /* No kernel lock - fine */
-- 
1.7.7.6

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux