about summary refs log tree commit diff
path: root/sysdeps/unix/sysv
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv')
-rw-r--r--sysdeps/unix/sysv/linux/Makefile2
-rw-r--r--sysdeps/unix/sysv/linux/test-errno-linux.c (renamed from sysdeps/unix/sysv/linux/test-errno.c)46
2 files changed, 41 insertions, 7 deletions
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 6b7aa3fdf8..1872cdb179 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -43,7 +43,7 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
 		  bits/mman-linux.h
 
 tests += tst-clone tst-clone2 tst-fanotify tst-personality tst-quota \
-	 tst-sync_file_range test-errno
+	 tst-sync_file_range test-errno-linux
 
 # Generate the list of SYS_* macros for the system calls (__NR_* macros).
 
diff --git a/sysdeps/unix/sysv/linux/test-errno.c b/sysdeps/unix/sysv/linux/test-errno-linux.c
index ab3735fe87..03a74bd6a1 100644
--- a/sysdeps/unix/sysv/linux/test-errno.c
+++ b/sysdeps/unix/sysv/linux/test-errno-linux.c
@@ -1,4 +1,5 @@
 /* Test that failing system calls do set errno to the correct value.
+   Linux sycalls version.
 
    Copyright (C) 2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
@@ -72,27 +73,55 @@
     rtype ret = syscall (__VA_ARGS__);				\
     int err = errno;						\
     int fail;							\
-    if (ret == (rtype) -1 && err == experr)			\
+    if ((ret == (rtype) -1) && (err == experr))			\
       fail = 0;							\
     else							\
       {								\
         fail = 1;						\
         if (ret != (rtype) -1)					\
           printf ("FAIL: " #syscall ": didn't fail as expected"	\
-               " (return "prtype")\n", ret);			\
+		  " (return "prtype")\n", ret);			\
         else if (err == 0xdead)					\
-          puts("FAIL: " #syscall ": didn't update errno\n");	\
+          puts ("FAIL: " #syscall ": didn't update errno");	\
         else if (err != experr)					\
           printf ("FAIL: " #syscall				\
-               ": errno is: %d (%s) expected: %d (%s)\n",	\
-               err, strerror (err), experr, strerror (experr));	\
+		  ": errno is: %d (%s) expected: %d (%s)\n",	\
+		  err, strerror (err), experr, strerror (experr));\
       }								\
     fail;							\
   }))
 
+#define test_wrp_rv2(rtype, prtype, experr1, experr2, syscall, ...) 	\
+  (__extension__ ({							\
+    errno = 0xdead;							\
+    rtype ret = syscall (__VA_ARGS__);					\
+    int err = errno;							\
+    int fail;								\
+    if ((ret == (rtype) -1) && ((err == experr1) || (err == experr2)))	\
+      fail = 0;								\
+    else								\
+      {									\
+        fail = 1;							\
+        if (ret != (rtype) -1)						\
+          printf ("FAIL: " #syscall ": didn't fail as expected"		\
+		  " (return "prtype")\n", ret);				\
+        else if (err == 0xdead)						\
+          puts ("FAIL: " #syscall ": didn't update errno");		\
+        else if (err != experr1 && err != experr2)			\
+          printf ("FAIL: " #syscall					\
+		  ": errno is: %d (%s) expected: %d (%s) or %d (%s)\n",	\
+		  err, strerror (err), experr1, strerror (experr1),	\
+		  experr2, strerror (experr2));				\
+      }									\
+    fail;								\
+  }))
+
 #define test_wrp(experr, syscall, ...)				\
   test_wrp_rv(int, "%d", experr, syscall, __VA_ARGS__)
 
+#define test_wrp2(experr1, experr2, syscall, ...)		\
+  test_wrp_rv2(int, "%d", experr1, experr2, syscall, __VA_ARGS__)
+
 static int
 do_test (void)
 {
@@ -120,7 +149,12 @@ do_test (void)
   fails |= test_wrp (ESRCH, getpgid, -1);
   fails |= test_wrp (EINVAL, inotify_add_watch, -1, "/", 0);
   fails |= test_wrp (EINVAL, mincore, (void *) -1, 0, vec);
-  fails |= test_wrp (EINVAL, mlock, (void *) -1, 1); // different errors
+  /* mlock fails if the result of the addition addr+len was less than addr
+     (which indicates final address overflow), however on 32 bits binaries
+     running on 64 bits kernels, internal syscall address check won't result
+     in an invalid address and thus syscalls fails later in vma
+     allocation.  */
+  fails |= test_wrp2 (EINVAL, ENOMEM, mlock, (void *) -1, 1);
   fails |= test_wrp (EINVAL, nanosleep, &ts, &ts);
   fails |= test_wrp (EINVAL, poll, &pollfd, -1, 0);
   fails |= test_wrp (ENODEV, quotactl, Q_GETINFO, NULL, -1, (caddr_t) &dqblk);