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:
julian 1999-03-02 00:28:09 +00:00
parent 0674f5c758
commit 7e163b4f03
5 changed files with 52 additions and 45 deletions

View File

@ -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) |

View File

@ -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) |

View File

@ -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 */

View File

@ -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;

View File

@ -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: */