diff options
author | sobomax <sobomax@FreeBSD.org> | 2002-10-11 11:43:09 +0000 |
---|---|---|
committer | sobomax <sobomax@FreeBSD.org> | 2002-10-11 11:43:09 +0000 |
commit | 591d270f4cb78aa28bf4425bd40ffa64369adf01 (patch) | |
tree | dd3429246e9b840440a70d3aa3d72b2350dbe054 /sys/i386/linux | |
parent | 7d25fb4f0a7f37f8e156559c3326d143e998bb41 (diff) | |
download | FreeBSD-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.c | 2 | ||||
-rw-r--r-- | sys/i386/linux/linux_ipc64.h | 145 | ||||
-rw-r--r-- | sys/i386/linux/linux_machdep.c | 99 |
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); +} |