patch-2.2.13 linux/arch/i386/lib/usercopy.c

Next file: linux/arch/i386/mm/init.c
Previous file: linux/arch/i386/kernel/smp.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.12/linux/arch/i386/lib/usercopy.c linux/arch/i386/lib/usercopy.c
@@ -117,26 +117,31 @@
 /*
  * Return the size of a string (including the ending 0)
  *
- * Return 0 for error
+ * Return 0 on exception, a value greater than N if too long
  */
 
-long strlen_user(const char *s)
+long strnlen_user(const char *s, long n)
 {
-	unsigned long res;
+	unsigned long mask = -__addr_ok(s);
+	unsigned long res, tmp;
 
 	__asm__ __volatile__(
+		"	andl %0,%%ecx\n"
 		"0:	repne; scasb\n"
-		"	notl %0\n"
+		"	setne %%al\n"
+		"	subl %%ecx,%0\n"
+		"	addl %0,%%eax\n"
 		"1:\n"
 		".section .fixup,\"ax\"\n"
-		"2:	xorl %0,%0\n"
+		"2:	xorl %%eax,%%eax\n"
 		"	jmp 1b\n"
 		".previous\n"
 		".section __ex_table,\"a\"\n"
 		"	.align 4\n"
 		"	.long 0b,2b\n"
 		".previous"
-		:"=c" (res), "=D" (s)
-		:"1" (s), "a" (0), "0" (-__addr_ok(s)));
-	return res & -__addr_ok(s);
+		:"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
+		:"0" (n), "1" (s), "2" (0), "3" (mask)
+		:"cc");
+	return res & mask;
 }

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