Fix thread/process tracking and differentiation for Linux threads emulation.
Submitted by: Richard Seaman, Jr." <dick@tar.com> Also clean some compiler warnings in surrounding code.
This commit is contained in:
parent
0674f5c758
commit
7e163b4f03
@ -25,7 +25,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: linux_misc.c,v 1.51 1999/01/06 23:05:38 julian Exp $
|
||||
* $Id: linux_misc.c,v 1.52 1999/01/26 02:38:10 julian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -554,7 +554,7 @@ linux_fork(struct proc *p, struct linux_fork_args *args)
|
||||
#ifdef DEBUG
|
||||
printf("Linux-emul(%d): fork()\n", p->p_pid);
|
||||
#endif
|
||||
if (error = fork(p, (struct fork_args *)args))
|
||||
if ((error = fork(p, (struct fork_args *)args)) != 0)
|
||||
return error;
|
||||
if (p->p_retval[1] == 1)
|
||||
p->p_retval[0] = 0;
|
||||
@ -589,6 +589,7 @@ linux_clone(struct proc *p, struct linux_clone_args *args)
|
||||
|
||||
if (!args->stack)
|
||||
return (EINVAL);
|
||||
|
||||
exit_signal = args->flags & 0x000000ff;
|
||||
if (exit_signal >= LINUX_NSIG)
|
||||
return EINVAL;
|
||||
@ -608,7 +609,7 @@ linux_clone(struct proc *p, struct linux_clone_args *args)
|
||||
start = 0;
|
||||
|
||||
rf_args.flags = ff;
|
||||
if (error = rfork(p, &rf_args))
|
||||
if ((error = rfork(p, &rf_args)) != 0)
|
||||
return error;
|
||||
|
||||
p2 = pfind(p->p_retval[0]);
|
||||
@ -936,6 +937,8 @@ linux_utime(struct proc *p, struct linux_utime_args *args)
|
||||
return utimes(p, &bsdutimes);
|
||||
}
|
||||
|
||||
#define __WCLONE 0x80000000
|
||||
|
||||
int
|
||||
linux_waitpid(struct proc *p, struct linux_waitpid_args *args)
|
||||
{
|
||||
@ -953,20 +956,17 @@ linux_waitpid(struct proc *p, struct linux_waitpid_args *args)
|
||||
#endif
|
||||
tmp.pid = args->pid;
|
||||
tmp.status = args->status;
|
||||
/* This filters out the linux option _WCLONE. I don't
|
||||
* think we need it, but I could be wrong. If we need
|
||||
* it, we need to fix wait4, since it will give us an
|
||||
* error return of EINVAL if we pass in _WCLONE, and
|
||||
* of course, it won't do anything with it.
|
||||
*/
|
||||
tmp.options = (args->options & (WNOHANG | WUNTRACED));
|
||||
/* WLINUXCLONE should be equal to __WCLONE, but we make sure */
|
||||
if (args->options & __WCLONE)
|
||||
tmp.options |= WLINUXCLONE;
|
||||
tmp.rusage = NULL;
|
||||
|
||||
if (error = wait4(p, &tmp))
|
||||
if ((error = wait4(p, &tmp)) != 0)
|
||||
return error;
|
||||
|
||||
if (args->status) {
|
||||
if (error = copyin(args->status, &tmpstat, sizeof(int)))
|
||||
if ((error = copyin(args->status, &tmpstat, sizeof(int))) != 0)
|
||||
return error;
|
||||
if (WIFSIGNALED(tmpstat))
|
||||
tmpstat = (tmpstat & 0xffffff80) |
|
||||
@ -997,22 +997,19 @@ linux_wait4(struct proc *p, struct linux_wait4_args *args)
|
||||
#endif
|
||||
tmp.pid = args->pid;
|
||||
tmp.status = args->status;
|
||||
/* This filters out the linux option _WCLONE. I don't
|
||||
* think we need it, but I could be wrong. If we need
|
||||
* it, we need to fix wait4, since it will give us an
|
||||
* error return of EINVAL if we pass in _WCLONE, and
|
||||
* of course, it won't do anything with it.
|
||||
*/
|
||||
tmp.options = (args->options & (WNOHANG | WUNTRACED));
|
||||
/* WLINUXCLONE should be equal to __WCLONE, but we make sure */
|
||||
if (args->options & __WCLONE)
|
||||
tmp.options |= WLINUXCLONE;
|
||||
tmp.rusage = args->rusage;
|
||||
|
||||
if (error = wait4(p, &tmp))
|
||||
if ((error = wait4(p, &tmp)) != 0)
|
||||
return error;
|
||||
|
||||
p->p_siglist &= ~sigmask(SIGCHLD);
|
||||
|
||||
if (args->status) {
|
||||
if (error = copyin(args->status, &tmpstat, sizeof(int)))
|
||||
if ((error = copyin(args->status, &tmpstat, sizeof(int))) != 0)
|
||||
return error;
|
||||
if (WIFSIGNALED(tmpstat))
|
||||
tmpstat = (tmpstat & 0xffffff80) |
|
||||
|
@ -25,7 +25,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: linux_misc.c,v 1.51 1999/01/06 23:05:38 julian Exp $
|
||||
* $Id: linux_misc.c,v 1.52 1999/01/26 02:38:10 julian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -554,7 +554,7 @@ linux_fork(struct proc *p, struct linux_fork_args *args)
|
||||
#ifdef DEBUG
|
||||
printf("Linux-emul(%d): fork()\n", p->p_pid);
|
||||
#endif
|
||||
if (error = fork(p, (struct fork_args *)args))
|
||||
if ((error = fork(p, (struct fork_args *)args)) != 0)
|
||||
return error;
|
||||
if (p->p_retval[1] == 1)
|
||||
p->p_retval[0] = 0;
|
||||
@ -589,6 +589,7 @@ linux_clone(struct proc *p, struct linux_clone_args *args)
|
||||
|
||||
if (!args->stack)
|
||||
return (EINVAL);
|
||||
|
||||
exit_signal = args->flags & 0x000000ff;
|
||||
if (exit_signal >= LINUX_NSIG)
|
||||
return EINVAL;
|
||||
@ -608,7 +609,7 @@ linux_clone(struct proc *p, struct linux_clone_args *args)
|
||||
start = 0;
|
||||
|
||||
rf_args.flags = ff;
|
||||
if (error = rfork(p, &rf_args))
|
||||
if ((error = rfork(p, &rf_args)) != 0)
|
||||
return error;
|
||||
|
||||
p2 = pfind(p->p_retval[0]);
|
||||
@ -936,6 +937,8 @@ linux_utime(struct proc *p, struct linux_utime_args *args)
|
||||
return utimes(p, &bsdutimes);
|
||||
}
|
||||
|
||||
#define __WCLONE 0x80000000
|
||||
|
||||
int
|
||||
linux_waitpid(struct proc *p, struct linux_waitpid_args *args)
|
||||
{
|
||||
@ -953,20 +956,17 @@ linux_waitpid(struct proc *p, struct linux_waitpid_args *args)
|
||||
#endif
|
||||
tmp.pid = args->pid;
|
||||
tmp.status = args->status;
|
||||
/* This filters out the linux option _WCLONE. I don't
|
||||
* think we need it, but I could be wrong. If we need
|
||||
* it, we need to fix wait4, since it will give us an
|
||||
* error return of EINVAL if we pass in _WCLONE, and
|
||||
* of course, it won't do anything with it.
|
||||
*/
|
||||
tmp.options = (args->options & (WNOHANG | WUNTRACED));
|
||||
/* WLINUXCLONE should be equal to __WCLONE, but we make sure */
|
||||
if (args->options & __WCLONE)
|
||||
tmp.options |= WLINUXCLONE;
|
||||
tmp.rusage = NULL;
|
||||
|
||||
if (error = wait4(p, &tmp))
|
||||
if ((error = wait4(p, &tmp)) != 0)
|
||||
return error;
|
||||
|
||||
if (args->status) {
|
||||
if (error = copyin(args->status, &tmpstat, sizeof(int)))
|
||||
if ((error = copyin(args->status, &tmpstat, sizeof(int))) != 0)
|
||||
return error;
|
||||
if (WIFSIGNALED(tmpstat))
|
||||
tmpstat = (tmpstat & 0xffffff80) |
|
||||
@ -997,22 +997,19 @@ linux_wait4(struct proc *p, struct linux_wait4_args *args)
|
||||
#endif
|
||||
tmp.pid = args->pid;
|
||||
tmp.status = args->status;
|
||||
/* This filters out the linux option _WCLONE. I don't
|
||||
* think we need it, but I could be wrong. If we need
|
||||
* it, we need to fix wait4, since it will give us an
|
||||
* error return of EINVAL if we pass in _WCLONE, and
|
||||
* of course, it won't do anything with it.
|
||||
*/
|
||||
tmp.options = (args->options & (WNOHANG | WUNTRACED));
|
||||
/* WLINUXCLONE should be equal to __WCLONE, but we make sure */
|
||||
if (args->options & __WCLONE)
|
||||
tmp.options |= WLINUXCLONE;
|
||||
tmp.rusage = args->rusage;
|
||||
|
||||
if (error = wait4(p, &tmp))
|
||||
if ((error = wait4(p, &tmp)) != 0)
|
||||
return error;
|
||||
|
||||
p->p_siglist &= ~sigmask(SIGCHLD);
|
||||
|
||||
if (args->status) {
|
||||
if (error = copyin(args->status, &tmpstat, sizeof(int)))
|
||||
if ((error = copyin(args->status, &tmpstat, sizeof(int))) != 0)
|
||||
return error;
|
||||
if (WIFSIGNALED(tmpstat))
|
||||
tmpstat = (tmpstat & 0xffffff80) |
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
|
||||
* $Id: kern_exit.c,v 1.74 1999/01/31 03:15:13 newton Exp $
|
||||
* $Id: kern_exit.c,v 1.75 1999/02/19 14:25:34 luoqi Exp $
|
||||
*/
|
||||
|
||||
#include "opt_compat.h"
|
||||
@ -283,7 +283,7 @@ exit1(p, rv)
|
||||
LIST_REMOVE(q, p_sibling);
|
||||
LIST_INSERT_HEAD(&initproc->p_children, q, p_sibling);
|
||||
q->p_pptr = initproc;
|
||||
q->p_sigparent = 0;
|
||||
q->p_sigparent = SIGCHLD;
|
||||
/*
|
||||
* Traced processes are killed
|
||||
* since their existence means someone is screwing up.
|
||||
@ -420,7 +420,7 @@ wait1(q, uap, compat)
|
||||
|
||||
if (uap->pid == 0)
|
||||
uap->pid = -q->p_pgid;
|
||||
if (uap->options &~ (WUNTRACED|WNOHANG))
|
||||
if (uap->options &~ (WUNTRACED|WNOHANG|WLINUXCLONE))
|
||||
return (EINVAL);
|
||||
loop:
|
||||
nfound = 0;
|
||||
@ -428,6 +428,17 @@ wait1(q, uap, compat)
|
||||
if (uap->pid != WAIT_ANY &&
|
||||
p->p_pid != uap->pid && p->p_pgid != -uap->pid)
|
||||
continue;
|
||||
|
||||
/* This special case handles a kthread spawned by linux_clone
|
||||
* (see linux_misc.c). The linux_wait4 and linux_waitpid functions
|
||||
* need to be able to distinguish between waiting on a process and
|
||||
* waiting on a thread. It is a thread if p_sigparent is not SIGCHLD,
|
||||
* and the WLINUXCLONE option signifies we want to wait for threads
|
||||
* and not processes.
|
||||
*/
|
||||
if ((p->p_sigparent != SIGCHLD) ^ ((uap->options & WLINUXCLONE) != 0))
|
||||
continue;
|
||||
|
||||
nfound++;
|
||||
if (p->p_stat == SZOMB) {
|
||||
/* charge childs scheduling cpu usage to parent */
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
|
||||
* $Id: kern_fork.c,v 1.54 1999/01/07 21:23:42 julian Exp $
|
||||
* $Id: kern_fork.c,v 1.55 1999/01/26 02:38:10 julian Exp $
|
||||
*/
|
||||
|
||||
#include "opt_ktrace.h"
|
||||
@ -361,9 +361,10 @@ fork1(p1, flags)
|
||||
/* Note that we fill in the values of sigacts in vm_fork */
|
||||
p2->p_sigacts = NULL;
|
||||
}
|
||||
if (flags & RFLINUXTHPN) {
|
||||
if (flags & RFLINUXTHPN)
|
||||
p2->p_sigparent = SIGUSR1;
|
||||
}
|
||||
else
|
||||
p2->p_sigparent = SIGCHLD;
|
||||
|
||||
/* bump references to the text vnode (for procfs) */
|
||||
p2->p_textvp = p1->p_textvp;
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)wait.h 8.2 (Berkeley) 7/10/94
|
||||
* $Id$
|
||||
* $Id: wait.h,v 1.8 1997/02/22 09:46:31 peter Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_WAIT_H_
|
||||
@ -79,6 +79,7 @@
|
||||
*/
|
||||
#define WNOHANG 1 /* don't hang in wait */
|
||||
#define WUNTRACED 2 /* tell about stopped, untraced children */
|
||||
#define WLINUXCLONE 0x80000000 /* wait for kthread spawned from linux_clone */
|
||||
|
||||
#ifndef _POSIX_SOURCE
|
||||
/* POSIX extensions and 4.2/4.3 compatibility: */
|
||||
|
Loading…
Reference in New Issue
Block a user