]> granicus.if.org Git - strace/commitdiff
times.test: workaround buggy libc
authorDmitry V. Levin <ldv@altlinux.org>
Sun, 6 Dec 2015 05:28:11 +0000 (05:28 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Sun, 6 Dec 2015 07:59:20 +0000 (07:59 +0000)
* tests/times.c: Include <sys/syscall.h>.
(main): On systems where user's and kernel's long types are the same,
prefer direct times syscall over libc's times function because
the latter is more prone to return value truncation.

tests/times.c

index 0ec301985e13d70b168fecdd3bc587488c8f9c6d..f0e7086b2919e0629da5fe00cf3a9e976d28b1d9 100644 (file)
@@ -13,6 +13,7 @@
 #include <time.h>
 #include <unistd.h>
 
+#include <sys/syscall.h>
 #include <sys/times.h>
 #include <sys/wait.h>
 
@@ -61,16 +62,32 @@ main (void)
        }
 
        struct tms tbuf;
+       unsigned long long llres;
+
+       /*
+        * On systems where user's and kernel's long types are the same,
+        * prefer direct times syscall over libc's times function because
+        * the latter is more prone to return value truncation.
+        */
+#if !defined __NR_times \
+ || defined LINUX_MIPSN32 \
+ || defined __x86_64__ && defined __ILP32__
        clock_t res = times(&tbuf);
 
-       if (res == (clock_t) -1)
+       if ((clock_t) -1 == res)
                return 77;
-
-       unsigned long long llres;
-       if (sizeof(llres) > sizeof(res))
+       if (sizeof(res) < sizeof(unsigned long long))
                llres = (unsigned long) res;
        else
                llres = res;
+#else
+       long res = syscall(__NR_times, &tbuf);
+
+       if (-1L == res)
+               return 77;
+       else
+               llres = (unsigned long) res;
+#endif
 
        printf("times({tms_utime=%llu, tms_stime=%llu, ",
                (unsigned long long) tbuf.tms_utime,