tprints("], ");
}
+ /*
+ * Since the timeout parameter is read by the kernel
+ * on entering syscall, it has to be decoded the same way
+ * whether the syscall has failed or not.
+ */
+ temporarily_clear_syserror(tcp);
print_timespec(tcp, tcp->u_arg[4]);
+ restore_cleared_syserror(tcp);
}
return 0;
}
extern int get_scno(struct tcb *tcp);
extern const char *syscall_name(long scno);
+extern void temporarily_clear_syserror(struct tcb *);
+extern void restore_cleared_syserror(struct tcb *);
+
extern int umoven(struct tcb *, long, unsigned int, void *);
#define umove(pid, addr, objp) \
umoven((pid), (addr), sizeof(*(objp)), (void *) (objp))
else {
printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
tprintf(", %lu, %ld, ", tcp->u_arg[2], tcp->u_arg[3]);
+ /*
+ * Since the timeout parameter is read by the kernel
+ * on entering syscall, it has to be decoded the same way
+ * whether the syscall has failed or not.
+ */
+ temporarily_clear_syserror(tcp);
printtv(tcp, tcp->u_arg[4]);
+ restore_cleared_syserror(tcp);
}
return 0;
}
/* syscall exit, and u_arg[1] was NULL */
return 0;
}
+
+ /*
+ * Since the timeout parameter is read by the kernel
+ * on entering syscall, it has to be decoded the same way
+ * whether the syscall has failed or not.
+ */
+ temporarily_clear_syserror(tcp);
print_timespec(tcp, tcp->u_arg[2]);
+ restore_cleared_syserror(tcp);
+
tprintf(", %lu", tcp->u_arg[3]);
return 0;
};
trace_syscall_exiting(tcp) : trace_syscall_entering(tcp);
}
+static int saved_u_error;
+
+void
+temporarily_clear_syserror(struct tcb *tcp)
+{
+ saved_u_error = tcp->u_error;
+ tcp->u_error = 0;
+}
+
+void
+restore_cleared_syserror(struct tcb *tcp)
+{
+ tcp->u_error = saved_u_error;
+}
+
/*
* Cannot rely on __kernel_[u]long_t being defined,
* it is quite a recent feature of <asm/posix_types.h>.