summaryrefslogtreecommitdiffstats
path: root/sys/i386/linux
diff options
context:
space:
mode:
authorsobomax <sobomax@FreeBSD.org>2002-10-11 11:43:09 +0000
committersobomax <sobomax@FreeBSD.org>2002-10-11 11:43:09 +0000
commit591d270f4cb78aa28bf4425bd40ffa64369adf01 (patch)
treedd3429246e9b840440a70d3aa3d72b2350dbe054 /sys/i386/linux
parent7d25fb4f0a7f37f8e156559c3326d143e998bb41 (diff)
downloadFreeBSD-src-591d270f4cb78aa28bf4425bd40ffa64369adf01.zip
FreeBSD-src-591d270f4cb78aa28bf4425bd40ffa64369adf01.tar.gz
- Add support for IPC_64 extensions into shmctl(2), semctl(2) and msgctl(2);
- add wrappers for mmap2(2) and ftruncate64(2) system calls; - don't spam console with printf's when VFAT_READDIR_BOTH ioctl(2) is invoked; - add support for SOUND_MIXER_READ_STEREODEVS ioctl(2); - make msgctl(IPC_STAT) and IPC_SET actually working by converting from BSD msqid_ds to Linux and vice versa; - properly return EINVAL if semget(2) is called with nsems being negative. Reviewed by: marcel Approved by: marcel Tested with: LSB runtime test
Diffstat (limited to 'sys/i386/linux')
-rw-r--r--sys/i386/linux/linux_dummy.c2
-rw-r--r--sys/i386/linux/linux_ipc64.h145
-rw-r--r--sys/i386/linux/linux_machdep.c99
3 files changed, 218 insertions, 28 deletions
diff --git a/sys/i386/linux/linux_dummy.c b/sys/i386/linux/linux_dummy.c
index 2d278e8..f94f88e 100644
--- a/sys/i386/linux/linux_dummy.c
+++ b/sys/i386/linux/linux_dummy.c
@@ -63,9 +63,7 @@ DUMMY(rt_sigqueueinfo);
DUMMY(capget);
DUMMY(capset);
DUMMY(sendfile);
-DUMMY(mmap2);
DUMMY(truncate64);
-DUMMY(ftruncate64);
DUMMY(setfsuid);
DUMMY(setfsgid);
DUMMY(pivot_root);
diff --git a/sys/i386/linux/linux_ipc64.h b/sys/i386/linux/linux_ipc64.h
new file mode 100644
index 0000000..04ff5f4
--- /dev/null
+++ b/sys/i386/linux/linux_ipc64.h
@@ -0,0 +1,145 @@
+/*-
+ * Copyright (c) 2002 Maxim Sobolev <sobomax@FreeBSD.org>
+ * 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 _I386_LINUX_LINUX_IPC64_H_
+#define _I386_LINUX_LINUX_IPC64_H_
+
+/*
+ * The ipc64_perm structure for i386 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct l_ipc64_perm
+{
+ l_key_t key;
+ l_uid_t uid;
+ l_gid_t gid;
+ l_uid_t cuid;
+ l_gid_t cgid;
+ l_mode_t mode;
+ l_ushort __pad1;
+ l_ushort seq;
+ l_ushort __pad2;
+ l_ulong __unused1;
+ l_ulong __unused2;
+};
+
+/*
+ * The msqid64_ds structure for i386 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct l_msqid64_ds {
+ struct l_ipc64_perm msg_perm;
+ l_time_t msg_stime; /* last msgsnd time */
+ l_ulong __unused1;
+ l_time_t msg_rtime; /* last msgrcv time */
+ l_ulong __unused2;
+ l_time_t msg_ctime; /* last change time */
+ l_ulong __unused3;
+ l_ulong msg_cbytes; /* current number of bytes on queue */
+ l_ulong msg_qnum; /* number of messages in queue */
+ l_ulong msg_qbytes; /* max number of bytes on queue */
+ l_pid_t msg_lspid; /* pid of last msgsnd */
+ l_pid_t msg_lrpid; /* last receive pid */
+ l_ulong __unused4;
+ l_ulong __unused5;
+};
+
+/*
+ * The semid64_ds structure for i386 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct l_semid64_ds {
+ struct l_ipc64_perm sem_perm; /* permissions */
+ l_time_t sem_otime; /* last semop time */
+ l_ulong __unused1;
+ l_time_t sem_ctime; /* last change time */
+ l_ulong __unused2;
+ l_ulong sem_nsems; /* no. of semaphores in array */
+ l_ulong __unused3;
+ l_ulong __unused4;
+};
+
+/*
+ * The shmid64_ds structure for i386 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct l_shmid64_ds {
+ struct l_ipc64_perm shm_perm; /* operation perms */
+ l_size_t shm_segsz; /* size of segment (bytes) */
+ l_time_t shm_atime; /* last attach time */
+ l_ulong __unused1;
+ l_time_t shm_dtime; /* last detach time */
+ l_ulong __unused2;
+ l_time_t shm_ctime; /* last change time */
+ l_ulong __unused3;
+ l_pid_t shm_cpid; /* pid of creator */
+ l_pid_t shm_lpid; /* pid of last operator */
+ l_ulong shm_nattch; /* no. of current attaches */
+ l_ulong __unused4;
+ l_ulong __unused5;
+};
+
+struct l_shminfo64 {
+ l_ulong shmmax;
+ l_ulong shmmin;
+ l_ulong shmmni;
+ l_ulong shmseg;
+ l_ulong shmall;
+ l_ulong __unused1;
+ l_ulong __unused2;
+ l_ulong __unused3;
+ l_ulong __unused4;
+};
+
+#endif /* !_I386_LINUX_LINUX_IPC64_H_ */
diff --git a/sys/i386/linux/linux_machdep.c b/sys/i386/linux/linux_machdep.c
index c468d89..8977c8d 100644
--- a/sys/i386/linux/linux_machdep.c
+++ b/sys/i386/linux/linux_machdep.c
@@ -385,19 +385,33 @@ struct l_mmap_argv {
#define STACK_SIZE (2 * 1024 * 1024)
#define GUARD_SIZE (4 * PAGE_SIZE)
+static int linux_mmap_common(struct thread *, struct l_mmap_argv *);
+
+int
+linux_mmap2(struct thread *td, struct linux_mmap2_args *args)
+{
+ struct l_mmap_argv linux_args;
+
+#ifdef DEBUG
+ if (ldebug(mmap2))
+ printf(ARGS(mmap2, "%p, %d, %d, 0x%08x, %d, %d"),
+ (void *)args->addr, args->len, args->prot,
+ args->flags, args->fd, args->pgoff);
+#endif
+
+ linux_args.addr = (l_caddr_t)args->addr;
+ linux_args.len = args->len;
+ linux_args.prot = args->prot;
+ linux_args.flags = args->flags;
+ linux_args.fd = args->fd;
+ linux_args.pos = args->pgoff * PAGE_SIZE;
+
+ return (linux_mmap_common(td, &linux_args));
+}
+
int
linux_mmap(struct thread *td, struct linux_mmap_args *args)
{
- struct proc *p = td->td_proc;
- struct mmap_args /* {
- caddr_t addr;
- size_t len;
- int prot;
- int flags;
- int fd;
- long pad;
- off_t pos;
- } */ bsd_args;
int error;
struct l_mmap_argv linux_args;
@@ -408,22 +422,39 @@ linux_mmap(struct thread *td, struct linux_mmap_args *args)
#ifdef DEBUG
if (ldebug(mmap))
printf(ARGS(mmap, "%p, %d, %d, 0x%08x, %d, %d"),
- (void *)linux_args.addr, linux_args.len, linux_args.prot,
- linux_args.flags, linux_args.fd, linux_args.pos);
+ (void *)linux_args->addr, linux_args->len, linux_args->prot,
+ linux_args->flags, linux_args->fd, linux_args->pos);
#endif
+ return (linux_mmap_common(td, &linux_args));
+}
+
+static int
+linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args)
+{
+ struct proc *p = td->td_proc;
+ struct mmap_args /* {
+ caddr_t addr;
+ size_t len;
+ int prot;
+ int flags;
+ int fd;
+ long pad;
+ off_t pos;
+ } */ bsd_args;
+
bsd_args.flags = 0;
- if (linux_args.flags & LINUX_MAP_SHARED)
+ if (linux_args->flags & LINUX_MAP_SHARED)
bsd_args.flags |= MAP_SHARED;
- if (linux_args.flags & LINUX_MAP_PRIVATE)
+ if (linux_args->flags & LINUX_MAP_PRIVATE)
bsd_args.flags |= MAP_PRIVATE;
- if (linux_args.flags & LINUX_MAP_FIXED)
+ if (linux_args->flags & LINUX_MAP_FIXED)
bsd_args.flags |= MAP_FIXED;
- if (linux_args.flags & LINUX_MAP_ANON)
+ if (linux_args->flags & LINUX_MAP_ANON)
bsd_args.flags |= MAP_ANON;
else
bsd_args.flags |= MAP_NOSYNC;
- if (linux_args.flags & LINUX_MAP_GROWSDOWN) {
+ if (linux_args->flags & LINUX_MAP_GROWSDOWN) {
bsd_args.flags |= MAP_STACK;
/* The linux MAP_GROWSDOWN option does not limit auto
@@ -448,7 +479,7 @@ linux_mmap(struct thread *td, struct linux_mmap_args *args)
*/
/* This gives us TOS */
- bsd_args.addr = linux_args.addr + linux_args.len;
+ bsd_args.addr = linux_args->addr + linux_args->len;
if (bsd_args.addr > p->p_vmspace->vm_maxsaddr) {
/* Some linux apps will attempt to mmap
@@ -472,8 +503,8 @@ linux_mmap(struct thread *td, struct linux_mmap_args *args)
}
/* This gives us our maximum stack size */
- if (linux_args.len > STACK_SIZE - GUARD_SIZE)
- bsd_args.len = linux_args.len;
+ if (linux_args->len > STACK_SIZE - GUARD_SIZE)
+ bsd_args.len = linux_args->len;
else
bsd_args.len = STACK_SIZE - GUARD_SIZE;
@@ -485,16 +516,16 @@ linux_mmap(struct thread *td, struct linux_mmap_args *args)
*/
bsd_args.addr -= bsd_args.len;
} else {
- bsd_args.addr = linux_args.addr;
- bsd_args.len = linux_args.len;
+ bsd_args.addr = linux_args->addr;
+ bsd_args.len = linux_args->len;
}
- bsd_args.prot = linux_args.prot | PROT_READ; /* always required */
- if (linux_args.flags & LINUX_MAP_ANON)
+ bsd_args.prot = linux_args->prot | PROT_READ; /* always required */
+ if (linux_args->flags & LINUX_MAP_ANON)
bsd_args.fd = -1;
else
- bsd_args.fd = linux_args.fd;
- bsd_args.pos = linux_args.pos;
+ bsd_args.fd = linux_args->fd;
+ bsd_args.pos = linux_args->pos;
bsd_args.pad = 0;
#ifdef DEBUG
@@ -776,3 +807,19 @@ linux_sigaltstack(struct thread *td, struct linux_sigaltstack_args *uap)
return (error);
}
+
+int
+linux_ftruncate64(struct thread *td, struct linux_ftruncate64_args *args)
+{
+ struct ftruncate_args sa;
+
+#ifdef DEBUG
+ if (ldebug(ftruncate64))
+ printf(ARGS(ftruncate64, "%d, %d"), args->fd, args->length);
+#endif
+
+ sa.fd = args->fd;
+ sa.pad = 0;
+ sa.length = args->length;
+ return ftruncate(td, &sa);
+}
OpenPOWER on IntegriCloud