]> granicus.if.org Git - strace/commitdiff
Add is_erestart helper function
authorDmitry V. Levin <ldv@altlinux.org>
Fri, 18 Sep 2015 01:54:59 +0000 (01:54 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Sat, 19 Sep 2015 01:04:49 +0000 (04:04 +0300)
* defs.h (is_erestart): New prototype.
* syscall.c (is_erestart): New function.
* time.c (sys_nanosleep): Use is_erestart,
temporarily_clear_syserror, and restore_cleared_syserror.

defs.h
syscall.c
time.c

diff --git a/defs.h b/defs.h
index 119f9b44e24e7d1a9e7e76990afdd5f8413402f2..b7e008068a253edc747bee69534da7d2f1da5625 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -538,6 +538,7 @@ extern void get_regs(pid_t pid);
 extern int get_scno(struct tcb *tcp);
 extern const char *syscall_name(long scno);
 
+extern bool is_erestart(struct tcb *);
 extern void temporarily_clear_syserror(struct tcb *);
 extern void restore_cleared_syserror(struct tcb *);
 
index aaa44eada74e3a5745a52065254a1c217dcd6c6d..d4599e40e965784985725042c5dda96f60e5a739 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -1131,6 +1131,20 @@ trace_syscall(struct tcb *tcp)
                trace_syscall_exiting(tcp) : trace_syscall_entering(tcp);
 }
 
+bool
+is_erestart(struct tcb *tcp)
+{
+       switch (tcp->u_error) {
+               case ERESTARTSYS:
+               case ERESTARTNOINTR:
+               case ERESTARTNOHAND:
+               case ERESTART_RESTARTBLOCK:
+                       return true;
+               default:
+                       return false;
+       }
+}
+
 static int saved_u_error;
 
 void
diff --git a/time.c b/time.c
index e37f26e0b81c75154b78e35ddc6d9824328fcc45..47023c590bcfff1ba017d0fcfcf75c1beb3cd38c 100644 (file)
--- a/time.c
+++ b/time.c
@@ -203,22 +203,19 @@ SYS_FUNC(nanosleep)
                print_timespec(tcp, tcp->u_arg[0]);
                tprints(", ");
        } else {
-               /* Second (returned) timespec is only significant
-                * if syscall was interrupted. On success, we print
-                * only its address, since kernel doesn't modify it,
+
+               /*
+                * Second (returned) timespec is only significant if syscall
+                * was interrupted.  On success and in case of other errors we
+                * print only its address, since kernel doesn't modify it,
                 * and printing the value may show uninitialized data.
                 */
-               switch (tcp->u_error) {
-               default:
-                       /* Not interrupted (slept entire interval) */
-                       printaddr(tcp->u_arg[1]);
-                       break;
-               case ERESTARTSYS:
-               case ERESTARTNOINTR:
-               case ERESTARTNOHAND:
-               case ERESTART_RESTARTBLOCK:
-                       /* Interrupted */
+               if (is_erestart(tcp)) {
+                       temporarily_clear_syserror(tcp);
                        print_timespec(tcp, tcp->u_arg[1]);
+                       restore_cleared_syserror(tcp);
+               } else {
+                       printaddr(tcp->u_arg[1]);
                }
        }
        return 0;