summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_syscall.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2012-04-12 10:48:43 +0000
committerkib <kib@FreeBSD.org>2012-04-12 10:48:43 +0000
commit319ab382ef5fd326d3fab25c60ffe55702438a37 (patch)
treeb11cc6ba65a78e38d9da1d9122832b5385fa56c5 /sys/kern/subr_syscall.c
parentaed1b833cf616d6a716d2a947c77fe99d6f3f925 (diff)
downloadFreeBSD-src-319ab382ef5fd326d3fab25c60ffe55702438a37.zip
FreeBSD-src-319ab382ef5fd326d3fab25c60ffe55702438a37.tar.gz
Add thread-private flag to indicate that error value is already placed
in td_errno. Flag is supposed to be used by syscalls returning EJUSTRETURN because errno was already placed into the usermode frame by a call to set_syscall_retval(9). Both ktrace and dtrace get errno value from td_errno if the flag is set. Use the flag to fix sigsuspend(2) error return ktrace records. Requested by: bde MFC after: 1 week
Diffstat (limited to 'sys/kern/subr_syscall.c')
-rw-r--r--sys/kern/subr_syscall.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c
index 367ea67..5b48595 100644
--- a/sys/kern/subr_syscall.c
+++ b/sys/kern/subr_syscall.c
@@ -136,7 +136,8 @@ syscallenter(struct thread *td, struct syscall_args *sa)
AUDIT_SYSCALL_EXIT(error, td);
/* Save the latest error return value. */
- td->td_errno = error;
+ if ((td->td_pflags & TDP_NERRNO) == 0)
+ td->td_errno = error;
#ifdef KDTRACE_HOOKS
/*
@@ -191,9 +192,12 @@ syscallret(struct thread *td, int error, struct syscall_args *sa __unused)
syscallname(p, sa->code), td, td->td_proc->p_pid, td->td_name);
#ifdef KTRACE
- if (KTRPOINT(td, KTR_SYSRET))
- ktrsysret(sa->code, error, td->td_retval[0]);
+ if (KTRPOINT(td, KTR_SYSRET)) {
+ ktrsysret(sa->code, (td->td_pflags & TDP_NERRNO) == 0 ?
+ error : td->td_errno, td->td_retval[0]);
+ }
#endif
+ td->td_pflags &= ~TDP_NERRNO;
if (p->p_flag & P_TRACED) {
traced = 1;
OpenPOWER on IntegriCloud