aboutsummaryrefslogtreecommitdiff
path: root/sys/compat/linux
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/linux')
-rw-r--r--sys/compat/linux/linux_misc.c98
-rw-r--r--sys/compat/linux/linux_signal.c58
-rw-r--r--sys/compat/linux/linux_util.c9
3 files changed, 163 insertions, 2 deletions
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index e85fec31ab35..848c11493046 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -74,6 +74,7 @@ __FBSDID("$FreeBSD$");
#include <posix4/sched.h>
#include <compat/linux/linux_sysproto.h>
+#include <compat/linux/linux_emul.h>
#ifdef COMPAT_LINUX32
#include <machine/../linux32/linux.h>
@@ -93,6 +94,9 @@ __FBSDID("$FreeBSD$");
#define BSD_TO_LINUX_SIGNAL(sig) \
(((sig) <= LINUX_SIGTBLSZ) ? bsd_to_linux_signal[_SIG_IDX(sig)] : sig)
+extern struct sx emul_shared_lock;
+extern struct sx emul_lock;
+
static unsigned int linux_to_bsd_resource[LINUX_RLIM_NLIMITS] = {
RLIMIT_CPU, RLIMIT_FSIZE, RLIMIT_DATA, RLIMIT_STACK,
RLIMIT_CORE, RLIMIT_RSS, RLIMIT_NPROC, RLIMIT_NOFILE,
@@ -1330,11 +1334,69 @@ linux_reboot(struct thread *td, struct linux_reboot_args *args)
int
linux_getpid(struct thread *td, struct linux_getpid_args *args)
{
+ struct linux_emuldata *em;
+
+ em = em_find(td->td_proc, EMUL_UNLOCKED);
+
+ KASSERT(em != NULL, ("getpid: emuldata not found.\n"));
+
+ td->td_retval[0] = em->shared->group_pid;
+ EMUL_UNLOCK(&emul_lock);
+ return (0);
+}
+
+int
+linux_gettid(struct thread *td, struct linux_gettid_args *args)
+{
+#ifdef DEBUG
+ if (ldebug(gettid))
+ printf(ARGS(gettid, ""));
+#endif
td->td_retval[0] = td->td_proc->p_pid;
return (0);
}
+
+int
+linux_getppid(struct thread *td, struct linux_getppid_args *args)
+{
+ struct linux_emuldata *em;
+ struct proc *p, *pp;
+
+ em = em_find(td->td_proc, EMUL_UNLOCKED);
+
+ KASSERT(em != NULL, ("getppid: process emuldata not found.\n"));
+
+ /* find the group leader */
+ p = pfind(em->shared->group_pid);
+
+ if (p == NULL) {
+#ifdef DEBUG
+ printf(LMSG("parent process not found.\n"));
+#endif
+ return (0);
+ }
+
+ pp = p->p_pptr; /* switch to parent */
+ PROC_LOCK(pp);
+ PROC_UNLOCK(p);
+
+ /* if its also linux process */
+ if (pp->p_sysent == &elf_linux_sysvec) {
+ em = em_find(pp, EMUL_LOCKED);
+ KASSERT(em != NULL, ("getppid: parent emuldata not found.\n"));
+
+ td->td_retval[0] = em->shared->group_pid;
+ } else
+ td->td_retval[0] = pp->p_pid;
+
+ EMUL_UNLOCK(&emul_lock);
+ PROC_UNLOCK(pp);
+
+ return (0);
+}
+
int
linux_getgid(struct thread *td, struct linux_getgid_args *args)
{
@@ -1394,3 +1456,39 @@ linux_sethostname(struct thread *td, struct linux_sethostname_args *args)
args->len, 0, 0));
}
+int
+linux_exit_group(struct thread *td, struct linux_exit_group_args *args)
+{
+ struct linux_emuldata *em, *td_em, *tmp_em;
+ struct proc *sp;
+
+#ifdef DEBUG
+ if (ldebug(exit_group))
+ printf(ARGS(exit_group, "%i"), args->error_code);
+#endif
+
+ td_em = em_find(td->td_proc, EMUL_UNLOCKED);
+
+ KASSERT(td_em != NULL, ("exit_group: emuldata not found.\n"));
+
+ EMUL_SHARED_RLOCK(&emul_shared_lock);
+ LIST_FOREACH_SAFE(em, &td_em->shared->threads, threads, tmp_em) {
+ if (em->pid == td_em->pid)
+ continue;
+
+ sp = pfind(em->pid);
+ psignal(sp, SIGKILL);
+ PROC_UNLOCK(sp);
+#ifdef DEBUG
+ printf(LMSG("linux_sys_exit_group: kill PID %d\n"), em->pid);
+#endif
+ }
+
+ EMUL_SHARED_RUNLOCK(&emul_shared_lock);
+ EMUL_UNLOCK(&emul_lock);
+
+ exit1(td, W_EXITCODE(args->error_code,0));
+
+ return (0);
+}
+
diff --git a/sys/compat/linux/linux_signal.c b/sys/compat/linux/linux_signal.c
index 081b7c0b8035..50a05fa434e1 100644
--- a/sys/compat/linux/linux_signal.c
+++ b/sys/compat/linux/linux_signal.c
@@ -49,6 +49,10 @@ __FBSDID("$FreeBSD$");
#endif
#include <compat/linux/linux_signal.h>
#include <compat/linux/linux_util.h>
+#include <compat/linux/linux_emul.h>
+
+extern struct sx emul_shared_lock;
+extern struct sx emul_lock;
void
linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss)
@@ -447,3 +451,57 @@ linux_kill(struct thread *td, struct linux_kill_args *args)
tmp.pid = args->pid;
return (kill(td, &tmp));
}
+
+int
+linux_tgkill(struct thread *td, struct linux_tgkill_args *args)
+{
+ struct linux_emuldata *em;
+ struct linux_kill_args ka;
+ struct proc *p;
+
+#ifdef DEBUG
+ if (ldebug(tgkill))
+ printf(ARGS(tgkill, "%d, %d, %d"), args->tgid, args->pid, args->sig);
+#endif
+
+ ka.pid = args->pid;
+ ka.signum = args->sig;
+
+ if (args->tgid == -1)
+ return linux_kill(td, &ka);
+
+ if ((p = pfind(args->pid)) == NULL)
+ return ESRCH;
+
+ if (p->p_sysent != &elf_linux_sysvec)
+ return ESRCH;
+
+ PROC_UNLOCK(p);
+
+ em = em_find(p, EMUL_UNLOCKED);
+
+ if (em == NULL) {
+#ifdef DEBUG
+ printf("emuldata not found in tgkill.\n");
+#endif
+ return ESRCH;
+ }
+
+ if (em->shared->group_pid != args->tgid)
+ return ESRCH;
+
+ EMUL_UNLOCK(&emul_lock);
+
+ return linux_kill(td, &ka);
+}
+
+int
+linux_tkill(struct thread *td, struct linux_tkill_args *args)
+{
+#ifdef DEBUG
+ if (ldebug(tkill))
+ printf(ARGS(tkill, "%i, %i"), args->tid, args->sig);
+#endif
+
+ return (linux_kill(td, (struct linux_kill_args *) args));
+}
diff --git a/sys/compat/linux/linux_util.c b/sys/compat/linux/linux_util.c
index 09c51311dc7c..8103c3a90838 100644
--- a/sys/compat/linux/linux_util.c
+++ b/sys/compat/linux/linux_util.c
@@ -32,6 +32,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_compat.h"
+
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/lock.h>
@@ -47,6 +49,11 @@ __FBSDID("$FreeBSD$");
#include <machine/stdarg.h>
#include <compat/linux/linux_util.h>
+#ifdef COMPAT_LINUX32
+#include <machine/../linux32/linux.h>
+#else
+#include <machine/../linux/linux.h>
+#endif
const char linux_emul_path[] = "/compat/linux";
@@ -85,8 +92,6 @@ linux_msg(const struct thread *td, const char *fmt, ...)
printf("\n");
}
-MALLOC_DECLARE(M_LINUX);
-
struct device_element
{
TAILQ_ENTRY(device_element) list;