summaryrefslogtreecommitdiffstats
path: root/sys/compat/linux/linux_misc.c
diff options
context:
space:
mode:
authornetchild <netchild@FreeBSD.org>2006-08-15 12:54:30 +0000
committernetchild <netchild@FreeBSD.org>2006-08-15 12:54:30 +0000
commitec2ba5d85d7c127eef674f77e45cc0bea81d8850 (patch)
treeeefd61a061ceacbae59d210a958f6ea28f9d2b34 /sys/compat/linux/linux_misc.c
parente8cb5b55782d998cb82d772021c355c69edfaf5e (diff)
downloadFreeBSD-src-ec2ba5d85d7c127eef674f77e45cc0bea81d8850.zip
FreeBSD-src-ec2ba5d85d7c127eef674f77e45cc0bea81d8850.tar.gz
Add the linux 2.6.x stuff (not used by default!):
- TLS - complete - pid/tid mangling - complete - thread area - complete - futexes - complete with issues - clone() extension - complete with some possible minor issues - mq*/timer*/clock* stuff - complete but untested and the mq* stuff is disabled when not build as part of the kernel with native FreeBSD mq* support (module support for this will come later) Tested with: - linux-firefox - works, tested - linux-opera - works, tested - linux-realplay - doesnt work, issue with futexes - linux-skype - doesnt work, issue with futexes - linux-rt2-demo - works, tested - linux-acroread - doesnt work, unknown reason (coredump) and sometimes issue with futexes - various unix utilities in linux-base-gentoo3 and linux-base-fc4: everything tried worked On amd64 not everything is supported like on i386, the catchup is planned for later when the remaining bugs in the new functions are fixed. To test this new stuff, you have to run sysctl compat.linux.osrelease=2.6.16 to switch back use sysctl compat.linux.osrelease=2.4.2 Don't switch while running a linux program, strange things may or may not happen. Sponsored by: Google SoC 2006 Submitted by: rdivacky Some suggestions/help by: jhb, kib, manu@NetBSD.org, netchild
Diffstat (limited to 'sys/compat/linux/linux_misc.c')
-rw-r--r--sys/compat/linux/linux_misc.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index e85fec3..848c114 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);
+}
+
OpenPOWER on IntegriCloud