1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-21 15:45:02 +00:00
Implement prctl().

Submitted by:	rdivacky
Tested with:	LTP
This commit is contained in:
Alexander Leidinger 2006-10-28 10:59:59 +00:00
parent efc7cb843b
commit 955d762aca
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=163734
8 changed files with 123 additions and 5 deletions

View File

@ -53,7 +53,6 @@ DUMMY(bdflush);
DUMMY(sysfs);
DUMMY(query_module);
DUMMY(nfsservctl);
DUMMY(prctl);
DUMMY(rt_sigtimedwait);
DUMMY(rt_sigqueueinfo);
DUMMY(capget);

View File

@ -298,7 +298,8 @@
l_gid16_t egid, l_gid16_t sgid); }
171 AUE_GETRESGID STD { int linux_getresgid16(l_gid16_t *rgid, \
l_gid16_t *egid, l_gid16_t *sgid); }
172 AUE_PRCTL STD { int linux_prctl(void); }
172 AUE_PRCTL STD { int linux_prctl(l_int option, l_int arg2, l_int arg3, \
l_int arg4, l_int arg5); }
173 AUE_NULL STD { int linux_rt_sigreturn( \
struct l_ucontext *ucp); }
174 AUE_NULL STD { int linux_rt_sigaction(l_int sig, \

View File

@ -84,6 +84,7 @@ linux_proc_init(struct thread *td, pid_t child, int flags)
/* non-exec call */
em = malloc(sizeof *em, M_LINUX, M_WAITOK | M_ZERO);
em->pid = child;
em->pdeath_signal = 0;
if (flags & CLONE_VM) {
/* handled later in the code */
} else {
@ -151,6 +152,7 @@ linux_proc_exit(void *arg __unused, struct proc *p)
int error;
struct thread *td = FIRST_THREAD_IN_PROC(p);
int *child_clear_tid;
struct proc *q, *nq;
if (__predict_true(p->p_sysent != &elf_linux_sysvec))
return;
@ -204,6 +206,26 @@ linux_proc_exit(void *arg __unused, struct proc *p)
/* clean the stuff up */
free(em, M_LINUX);
/* this is a little weird but rewritten from exit1() */
sx_xlock(&proctree_lock);
q = LIST_FIRST(&p->p_children);
for (; q != NULL; q = nq) {
nq = LIST_NEXT(q, p_sibling);
if (q->p_flag & P_WEXIT)
continue;
if (__predict_false(q->p_sysent != &elf_linux_sysvec))
continue;
em = em_find(q, EMUL_UNLOCKED);
KASSERT(em != NULL, ("linux_reparent: emuldata not found: %i\n", q->p_pid));
if (em->pdeath_signal != 0) {
PROC_LOCK(q);
psignal(q, em->pdeath_signal);
PROC_UNLOCK(q);
}
EMUL_UNLOCK(&emul_lock);
}
sx_xunlock(&proctree_lock);
}
/*
@ -251,7 +273,7 @@ linux_schedtail(void *arg __unused, struct proc *p)
int error = 0;
int *child_set_tid;
if (p->p_sysent != &elf_linux_sysvec)
if (__predict_true(p->p_sysent != &elf_linux_sysvec))
return;
retry:

View File

@ -50,6 +50,8 @@ struct linux_emuldata {
struct linux_emuldata_shared *shared;
int pdeath_signal; /* parent death signal */
LIST_ENTRY(linux_emuldata) threads; /* list of linux threads */
};

View File

@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$");
#include <compat/linux/linux_sysproto.h>
#include <compat/linux/linux_emul.h>
#include <compat/linux/linux_misc.h>
#ifdef COMPAT_LINUX32
#include <machine/../linux32/linux.h>
@ -86,6 +87,7 @@ __FBSDID("$FreeBSD$");
#endif
#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_signal.h>
#include <compat/linux/linux_util.h>
#ifdef __i386__
@ -1546,3 +1548,52 @@ linux_exit_group(struct thread *td, struct linux_exit_group_args *args)
return (0);
}
int
linux_prctl(struct thread *td, struct linux_prctl_args *args)
{
int error = 0;
struct proc *p = td->td_proc;
char comm[LINUX_MAX_COMM_LEN];
struct linux_emuldata *em;
#ifdef DEBUG
if (ldebug(prctl))
printf(ARGS(prctl, "%d, %d, %d, %d, %d"), args->option, args->arg2,
args->arg3, args->arg4, args->arg5);
#endif
switch (args->option) {
case LINUX_PR_SET_PDEATHSIG:
if (!LINUX_SIG_VALID(args->arg2))
return (EINVAL);
em = em_find(p, EMUL_UNLOCKED);
KASSERT(em != NULL, ("prctl: emuldata not found.\n"));
em->pdeath_signal = args->arg2;
EMUL_UNLOCK(&emul_lock);
break;
case LINUX_PR_GET_PDEATHSIG:
em = em_find(p, EMUL_UNLOCKED);
KASSERT(em != NULL, ("prctl: emuldata not found.\n"));
error = copyout(&em->pdeath_signal, (void *)(register_t) args->arg2, sizeof(em->pdeath_signal));
EMUL_UNLOCK(&emul_lock);
break;
case LINUX_PR_SET_NAME:
comm[LINUX_MAX_COMM_LEN-1] = 0;
error = copyin(comm, (void *)(register_t) args->arg2, LINUX_MAX_COMM_LEN-1);
if (error)
return (error);
PROC_LOCK(p);
strcpy(p->p_comm, comm);
PROC_UNLOCK(p);
break;
case LINUX_PR_GET_NAME:
error = copyout(&p->p_comm, (void *)(register_t) args->arg2, MAXCOMLEN+1);
break;
default:
error = EINVAL;
break;
}
return (error);
}

View File

@ -0,0 +1,43 @@
/*-
* Copyright (c) 2006 Roman Divacky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _LINUX_MISC_H_
#define _LINUX_MISC_H_
/* defines for prctl */
#define LINUX_PR_SET_PDEATHSIG 1 /* Second arg is a signal */
#define LINUX_PR_GET_PDEATHSIG 2 /* Second arg is a ptr to return the signal */
#define LINUX_PR_SET_NAME 15 /* Set process name */
#define LINUX_PR_GET_NAME 16 /* Get process name */
#define LINUX_MAX_COMM_LEN 16 /* max length of the proc name */
#endif /* _LINUX_MISC_H_ */

View File

@ -56,7 +56,6 @@ DUMMY(sysfs);
DUMMY(vm86);
DUMMY(query_module);
DUMMY(nfsservctl);
DUMMY(prctl);
DUMMY(rt_sigtimedwait);
DUMMY(rt_sigqueueinfo);
DUMMY(capget);

View File

@ -301,7 +301,8 @@
l_gid16_t egid, l_gid16_t sgid); }
171 AUE_GETRESGID STD { int linux_getresgid16(l_gid16_t *rgid, \
l_gid16_t *egid, l_gid16_t *sgid); }
172 AUE_PRCTL STD { int linux_prctl(void); }
172 AUE_PRCTL STD { int linux_prctl(l_int option, l_int arg2, l_int arg3, \
l_int arg4, l_int arg5); }
173 AUE_NULL STD { int linux_rt_sigreturn( \
struct l_ucontext *ucp); }
174 AUE_NULL STD { int linux_rt_sigaction(l_int sig, \