about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/i386/sysdep.h
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/i386/sysdep.h')
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.h25
1 files changed, 18 insertions, 7 deletions
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index 1bf20bd718..b00c976351 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -37,16 +37,25 @@ Cambridge, MA 02139, USA.  */
 
 #ifdef ASSEMBLER
 
-/* Linux uses a negative return value to indicate syscall errors, unlike
-   most Unices, which use the condition codes' carry flag.  */
+/* Linux uses a negative return value to indicate syscall errors,
+   unlike most Unices, which use the condition codes' carry flag.
+
+   Since version 2.1 the return value of a system call might be
+   negative even if the call succeeded.  E.g., the `lseek' system call
+   might return a large offset.  Therefore we must not anymore test
+   for < 0, but test for a real error by making sure the value in %eax
+   is a real error number.  For now (as of 2.1.1) 122 is the largest
+   defined error number.  Given a bit room for development, Linus
+   chose in <asm/unistd.h> to use the values -125 to -1 for error
+   values.  We follow him here.  */
 #undef	PSEUDO
 #define	PSEUDO(name, syscall_name, args)				      \
   .text;								      \
   SYSCALL_ERROR_HANDLER							      \
   ENTRY (name)								      \
     DO_CALL (args, syscall_name);					      \
-    testl %eax, %eax;							      \
-    jl syscall_error;
+    cmpl $-125, %eax;							      \
+    jae syscall_error;
 
 #ifndef PIC
 #define SYSCALL_ERROR_HANDLER	/* Nothing here; code in sysdep.S is used.  */
@@ -70,9 +79,10 @@ syscall_error:								      \
   popl %ebx;								      \
   movl %ecx, (%eax);							      \
   movl $-1, %eax;							      \
-  ret;
+  ret;									      \
+  .size syscall_error,.-syscall-error;
 /* A quick note: it is assumed that the call to `__errno_location' does
-   not modify the parameter value!  */
+   not modify the stack!  */
 #else
 #define SYSCALL_ERROR_HANDLER						      \
   .type syscall_error,@function;					      \
@@ -85,7 +95,8 @@ syscall_error:								      \
   movl errno@GOT(%ecx), %ecx;						      \
   movl %edx, (%ecx);							      \
   movl $-1, %eax;							      \
-  ret;
+  ret;									      \
+  .size syscall_error,.-syscall-error;
 #endif	/* _LIBC_REENTRANT */
 #endif	/* PIC */