Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Apr 2012 10:48:44 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r234172 - in head/sys: kern sys
Message-ID:  <201204121048.q3CAmi06024923@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Thu Apr 12 10:48:43 2012
New Revision: 234172
URL: http://svn.freebsd.org/changeset/base/234172

Log:
  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

Modified:
  head/sys/kern/kern_sig.c
  head/sys/kern/subr_syscall.c
  head/sys/sys/proc.h

Modified: head/sys/kern/kern_sig.c
==============================================================================
--- head/sys/kern/kern_sig.c	Thu Apr 12 10:32:34 2012	(r234171)
+++ head/sys/kern/kern_sig.c	Thu Apr 12 10:48:43 2012	(r234172)
@@ -1465,6 +1465,8 @@ kern_sigsuspend(struct thread *td, sigse
 		mtx_unlock(&p->p_sigacts->ps_mtx);
 	}
 	PROC_UNLOCK(p);
+	td->td_errno = EINTR;
+	td->td_pflags |= TDP_NERRNO;
 	return (EJUSTRETURN);
 }
 

Modified: head/sys/kern/subr_syscall.c
==============================================================================
--- head/sys/kern/subr_syscall.c	Thu Apr 12 10:32:34 2012	(r234171)
+++ head/sys/kern/subr_syscall.c	Thu Apr 12 10:48:43 2012	(r234172)
@@ -136,7 +136,8 @@ syscallenter(struct thread *td, struct s
 		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,
 	    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;

Modified: head/sys/sys/proc.h
==============================================================================
--- head/sys/sys/proc.h	Thu Apr 12 10:32:34 2012	(r234171)
+++ head/sys/sys/proc.h	Thu Apr 12 10:48:43 2012	(r234172)
@@ -418,6 +418,7 @@ do {									\
 #define	TDP_AUDITREC	0x01000000 /* Audit record pending on thread */
 #define	TDP_RFPPWAIT	0x02000000 /* Handle RFPPWAIT on syscall exit */
 #define	TDP_RESETSPUR	0x04000000 /* Reset spurious page fault history. */
+#define	TDP_NERRNO	0x08000000 /* Last errno is already in td_errno */
 
 /*
  * Reasons that the current thread can not be run yet.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201204121048.q3CAmi06024923>