patch-2.4.27 linux-2.4.27/drivers/char/vc_screen.c

Next file: linux-2.4.27/drivers/gsc/eisa_eeprom.c
Previous file: linux-2.4.27/drivers/char/tpqic02.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.26/drivers/char/vc_screen.c linux-2.4.27/drivers/char/vc_screen.c
@@ -64,12 +64,25 @@
 	return size;
 }
 
+/* We share this temporary buffer with the console write code
+ * so that we can easily avoid touching user space while holding the
+ * console spinlock.
+ */
+extern char con_buf[PAGE_SIZE];
+#define CON_BUF_SIZE	PAGE_SIZE
+extern struct semaphore con_buf_sem;
+
 static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
 {
-	int size = vcs_size(file->f_dentry->d_inode);
+	int size;
+
+	down(&con_buf_sem);
+
+	size = vcs_size(file->f_dentry->d_inode);
 
 	switch (orig) {
 		default:
+			up(&con_buf_sem);
 			return -EINVAL;
 		case 2:
 			offset += size;
@@ -79,26 +92,22 @@
 		case 0:
 			break;
 	}
-	if (offset < 0 || offset > size)
+	if (offset < 0 || offset > size) {
+		up(&con_buf_sem);
 		return -EINVAL;
+	}
 	file->f_pos = offset;
+	up (&con_buf_sem);
 	return file->f_pos;
 }
 
-/* We share this temporary buffer with the console write code
- * so that we can easily avoid touching user space while holding the
- * console spinlock.
- */
-extern char con_buf[PAGE_SIZE];
-#define CON_BUF_SIZE	PAGE_SIZE
-extern struct semaphore con_buf_sem;
-
 static ssize_t
 vcs_read(struct file *file, char *buf, size_t count, loff_t *ppos)
 {
 	struct inode *inode = file->f_dentry->d_inode;
 	unsigned int currcons = MINOR(inode->i_rdev);
-	long pos = *ppos;
+	loff_t n;
+	unsigned pos;
 	long viewed, attr, read;
 	int col, maxcol;
 	unsigned short *org = NULL;
@@ -106,6 +115,9 @@
 
 	down(&con_buf_sem);
 
+	n = *ppos; 
+	pos = n;
+
 	/* Select the proper current console and verify
 	 * sanity of the situation under the console lock.
 	 */
@@ -124,11 +136,10 @@
 	if (!vc_cons_allocated(currcons))
 		goto unlock_out;
 
-	ret = -EINVAL;
-	if (pos < 0)
-		goto unlock_out;
 	read = 0;
 	ret = 0;
+	if (pos != n)
+		goto unlock_out;
 	while (count) {
 		char *con_buf0, *con_buf_start;
 		long this_round, size;
@@ -244,16 +255,15 @@
 		acquire_console_sem();
 
 		if (ret) {
-			read += (orig_count - ret);
 			ret = -EFAULT;
-			break;
+			goto unlock_out;
 		}
 		buf += orig_count;
 		pos += orig_count;
 		read += orig_count;
 		count -= orig_count;
 	}
-	*ppos += read;
+	*ppos = pos;
 	if (read)
 		ret = read;
 unlock_out:
@@ -267,7 +277,8 @@
 {
 	struct inode *inode = file->f_dentry->d_inode;
 	unsigned int currcons = MINOR(inode->i_rdev);
-	long pos = *ppos;
+	loff_t n;
+	unsigned pos;
 	long viewed, attr, size, written;
 	char *con_buf0;
 	int col, maxcol;
@@ -276,6 +287,9 @@
 
 	down(&con_buf_sem);
 
+	n = *ppos;
+	pos = n;
+
 	/* Select the proper current console and verify
 	 * sanity of the situation under the console lock.
 	 */
@@ -297,7 +311,7 @@
 
 	size = vcs_size(inode);
 	ret = -EINVAL;
-	if (pos < 0 || pos > size)
+	if (pos != n || pos > size)
 		goto unlock_out;
 	if (count > size - pos)
 		count = size - pos;
@@ -435,7 +449,7 @@
 		if (org0)
 			update_region(currcons, (unsigned long)(org0), org-org0);
 	}
-	*ppos += written;
+	*ppos = pos;
 	ret = written;
 
 unlock_out:

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)