First incarnation of our Linux emulator or rather compatibility code.

This first shot only incorporaties so much functionality that DOOM
can run (the X version), signal handling is VERY weak, so is many
other things. But it meets my milestone number one (you guessed it
- running DOOM).

Uses /compat/linux as prefix for loading shared libs, so it won't
conflict with our own libs.

Kernel must be compiled with "options COMPAT_LINUX" for this to work.
This commit is contained in:
Søren Schmidt 1995-06-25 17:32:43 +00:00
parent 0f72d204e6
commit c21dee177f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=9313
30 changed files with 8322 additions and 4 deletions

View File

@ -1,7 +1,7 @@
# $Id: Makefile,v 1.9 1995/03/20 19:25:38 wollman Exp $
# $Id: Makefile,v 1.10 1995/06/13 20:51:13 wollman Exp $
SUBDIR= cd9660 coff fdesc ibcs2 if_disc if_ppp if_sl if_tun \
ipfw kernfs msdos nfs nullfs \
ipfw kernfs linux msdos nfs nullfs \
portal procfs socksys syscons umapfs union
#
# Doesn't work:

16
lkm/linux/Makefile Normal file
View File

@ -0,0 +1,16 @@
# $Id$
.PATH: ${.CURDIR}/../../sys/i386/linux
KMOD= linux_mod
SRCS= linux.c linux_file.c linux_ioctl.c linux_misc.c linux_signal.c \
linux_generic.c linux_ipc.c linux_socket.c linux_stats.c \
linux_dummy.c linux_sysent.c imgact_linux.c vnode_if.h
NOMAN=
CFLAGS+= -DLKM -I. -DCOMPAT_LINUX -DSYSVSHM #-DSYSVMSG -DSYSVSEM #-DDEBUG
CLEANFILES+= vnode_if.h vnode_if.c
afterinstall:
${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
${.CURDIR}/linux /usr/bin
.include <bsd.kmod.mk>

3
lkm/linux/linux Normal file
View File

@ -0,0 +1,3 @@
#!/bin/sh
# $Id$
modload -e linux_init /lkm/linux_mod.o

58
lkm/linux/linux.c Normal file
View File

@ -0,0 +1,58 @@
/*-
* Copyright (c) 1994 Søren Schmidt
* 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 withough 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.
*
* $Id: linux.c,v 1.1 1994/10/14 08:46:12 sos Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/exec.h>
#include <sys/conf.h>
#include <sys/sysent.h>
#include <sys/lkm.h>
#include <sys/errno.h>
extern const struct execsw linux_execsw;
MOD_EXEC("linux_emulator", -1, (struct execsw*)&linux_execsw)
linux_load(struct lkm_table *lkmtp, int cmd)
{
uprintf("Linux emulator installed\n");
return 0;
}
linux_unload(struct lkm_table *lkmtp, int cmd)
{
uprintf("Linux emulator removed\n");
return 0;
}
linux_init(struct lkm_table *lkmtp, int cmd, int ver)
{
DISPATCH(lkmtp, cmd, ver, linux_load, linux_unload, nosys);
}

406
sys/alpha/linux/linux.h Normal file
View File

@ -0,0 +1,406 @@
/*-
* Copyright (c) 1994-1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux.h,v 1.3 1995/06/08 13:50:52 sos Exp $
*/
#ifndef LINUX_H
#define LINUX_H
typedef unsigned short linux_uid_t;
typedef unsigned short linux_gid_t;
typedef unsigned short linux_dev_t;
typedef unsigned long linux_ino_t;
typedef unsigned short linux_mode_t;
typedef unsigned short linux_nlink_t;
typedef long linux_time_t;
typedef long linux_clock_t;
typedef char * linux_caddr_t;
typedef long linux_off_t;
typedef struct {
long val[2];
} linux_fsid_t;
typedef int linux_pid_t;
typedef unsigned long linux_sigset_t;
typedef void (*linux_handler_t)(int);
typedef struct {
void (*sa_handler)(int);
linux_sigset_t sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void);
} linux_sigaction_t;
typedef int linux_key_t;
extern int bsd_to_linux_signal[];
extern int linux_to_bsd_signal[];
/* misc defines */
#define LINUX_NAME_MAX 255
/* signal numbers */
#define LINUX_SIGHUP 1
#define LINUX_SIGINT 2
#define LINUX_SIGQUIT 3
#define LINUX_SIGILL 4
#define LINUX_SIGTRAP 5
#define LINUX_SIGABRT 6
#define LINUX_SIGIOT 6
#define LINUX_SIGUNUSED 7
#define LINUX_SIGFPE 8
#define LINUX_SIGKILL 9
#define LINUX_SIGUSR1 10
#define LINUX_SIGSEGV 11
#define LINUX_SIGUSR2 12
#define LINUX_SIGPIPE 13
#define LINUX_SIGALRM 14
#define LINUX_SIGTERM 15
#define LINUX_SIGSTKFLT 16
#define LINUX_SIGCHLD 17
#define LINUX_SIGCONT 18
#define LINUX_SIGSTOP 19
#define LINUX_SIGTSTP 20
#define LINUX_SIGTTIN 21
#define LINUX_SIGTTOU 22
#define LINUX_SIGIO 23
#define LINUX_SIGPOLL LINUX_SIGIO
#define LINUX_SIGURG LINUX_SIGIO
#define LINUX_SIGXCPU 24
#define LINUX_SIGXFSZ 25
#define LINUX_SIGVTALRM 26
#define LINUX_SIGPROF 27
#define LINUX_SIGWINCH 28
#define LINUX_SIGLOST 29
#define LINUX_SIGPWR 30
#define LINUX_SIGBUS LINUX_SIGUNUSED
#define LINUX_NSIG 32
/* sigaction flags */
#define LINUX_SA_NOCLDSTOP 0x00000001
#define LINUX_SA_ONSTACK 0x08000000
#define LINUX_SA_RESTART 0x10000000
#define LINUX_SA_INTERRUPT 0x20000000
#define LINUX_SA_NOMASK 0x40000000
#define LINUX_SA_ONESHOT 0x80000000
/* sigprocmask actions */
#define LINUX_SIG_BLOCK 0
#define LINUX_SIG_UNBLOCK 1
#define LINUX_SIG_SETMASK 2
/* termio commands */
#define LINUX_TCGETS 0x5401
#define LINUX_TCSETS 0x5402
#define LINUX_TCSETSW 0x5403
#define LINUX_TCSETSF 0x5404
#define LINUX_TCGETA 0x5405
#define LINUX_TCSETA 0x5406
#define LINUX_TCSETAW 0x5407
#define LINUX_TCSETAF 0x5408
#define LINUX_TCSBRK 0x5409
#define LINUX_TCXONC 0x540A
#define LINUX_TCFLSH 0x540B
#define LINUX_TIOCEXCL 0x540C
#define LINUX_TIOCNXCL 0x540D
#define LINUX_TIOCSCTTY 0x540E
#define LINUX_TIOCGPGRP 0x540F
#define LINUX_TIOCSPGRP 0x5410
#define LINUX_TIOCOUTQ 0x5411
#define LINUX_TIOCSTI 0x5412
#define LINUX_TIOCGWINSZ 0x5413
#define LINUX_TIOCSWINSZ 0x5414
#define LINUX_TIOCMGET 0x5415
#define LINUX_TIOCMBIS 0x5416
#define LINUX_TIOCMBIC 0x5417
#define LINUX_TIOCMSET 0x5418
#define LINUX_TIOCGSOFTCAR 0x5419
#define LINUX_TIOCSSOFTCAR 0x541A
#define LINUX_FIONREAD 0x541B
#define LINUX_TIOCINQ FIONREAD
#define LINUX_TIOCLINUX 0x541C
#define LINUX_TIOCCONS 0x541D
#define LINUX_TIOCGSERIAL 0x541E
#define LINUX_TIOCSSERIAL 0x541F
#define LINUX_TIOCPKT 0x5420
#define LINUX_FIONBIO 0x5421
#define LINUX_TIOCNOTTY 0x5422
#define LINUX_TIOCSETD 0x5423
#define LINUX_TIOCGETD 0x5424
#define LINUX_TCSBRKP 0x5425
#define LINUX_TIOCTTYGSTRUCT 0x5426
#define LINUX_FIONCLEX 0x5450
#define LINUX_FIOCLEX 0x5451
#define LINUX_FIOASYNC 0x5452
#define LINUX_TIOCSERCONFIG 0x5453
#define LINUX_TIOCSERGWILD 0x5454
#define LINUX_TIOCSERSWILD 0x5455
#define LINUX_TIOCGLCKTRMIOS 0x5456
#define LINUX_TIOCSLCKTRMIOS 0x5457
/* line disciplines */
#define LINUX_N_TTY 0
#define LINUX_N_SLIP 1
#define LINUX_N_MOUSE 2
#define LINUX_N_PPP 3
/* Linux termio c_cc values */
#define LINUX_VINTR 0
#define LINUX_VQUIT 1
#define LINUX_VERASE 2
#define LINUX_VKILL 3
#define LINUX_VEOF 4
#define LINUX_VTIME 5
#define LINUX_VMIN 6
#define LINUX_VSWTC 7
#define LINUX_NCC 8
/* Linux termios c_cc values */
#define LINUX_VSTART 8
#define LINUX_VSTOP 9
#define LINUX_VSUSP 10
#define LINUX_VEOL 11
#define LINUX_VREPRINT 12
#define LINUX_VDISCARD 13
#define LINUX_VWERASE 14
#define LINUX_VLNEXT 15
#define LINUX_VEOL2 16
#define LINUX_NCCS 17
/* Linux c_iflag masks */
#define LINUX_IGNBRK 0x0000001
#define LINUX_BRKINT 0x0000002
#define LINUX_IGNPAR 0x0000004
#define LINUX_PARMRK 0x0000008
#define LINUX_INPCK 0x0000010
#define LINUX_ISTRIP 0x0000020
#define LINUX_INLCR 0x0000040
#define LINUX_IGNCR 0x0000080
#define LINUX_ICRNL 0x0000100
#define LINUX_IUCLC 0x0000200
#define LINUX_IXON 0x0000400
#define LINUX_IXANY 0x0000800
#define LINUX_IXOFF 0x0001000
#define LINUX_IMAXBEL 0x0002000
/* Linux c_oflag masks */
#define LINUX_OPOST 0x0000001
#define LINUX_OLCUC 0x0000002
#define LINUX_ONLCR 0x0000004
#define LINUX_OCRNL 0x0000008
#define LINUX_ONOCR 0x0000010
#define LINUX_ONLRET 0x0000020
#define LINUX_OFILL 0x0000040
#define LINUX_OFDEL 0x0000080
#define LINUX_NLDLY 0x0000100
#define LINUX_NL0 0x0000000
#define LINUX_NL1 0x0000100
#define LINUX_CRDLY 0x0000600
#define LINUX_CR0 0x0000000
#define LINUX_CR1 0x0000200
#define LINUX_CR2 0x0000400
#define LINUX_CR3 0x0000600
#define LINUX_TABDLY 0x0001800
#define LINUX_TAB0 0x0000000
#define LINUX_TAB1 0x0000800
#define LINUX_TAB2 0x0001000
#define LINUX_TAB3 0x0001800
#define LINUX_XTABS 0x0001800
#define LINUX_BSDLY 0x0002000
#define LINUX_BS0 0x0000000
#define LINUX_BS1 0x0002000
#define LINUX_VTDLY 0x0004000
#define LINUX_VT0 0x0000000
#define LINUX_VT1 0x0004000
#define LINUX_FFDLY 0x0008000
#define LINUX_FF0 0x0000000
#define LINUX_FF1 0x0008000
#define LINUX_CBAUD 0x0000100f
#define LINUX_B0 0x00000000
#define LINUX_B50 0x00000001
#define LINUX_B75 0x00000002
#define LINUX_B110 0x00000003
#define LINUX_B134 0x00000004
#define LINUX_B150 0x00000005
#define LINUX_B200 0x00000006
#define LINUX_B300 0x00000007
#define LINUX_B600 0x00000008
#define LINUX_B1200 0x00000009
#define LINUX_B1800 0x0000000a
#define LINUX_B2400 0x0000000b
#define LINUX_B4800 0x0000000c
#define LINUX_B9600 0x0000000d
#define LINUX_B19200 0x0000000e
#define LINUX_B38400 0x0000000f
#define LINUX_EXTA LINUX_B19200
#define LINUX_EXTB LINUX_B38400
#define LINUX_CBAUDEX 0x00001000
#define LINUX_B57600 0x00001001
#define LINUX_B115200 0x00001002
#define LINUX_CSIZE 0x00000030
#define LINUX_CS5 0x00000000
#define LINUX_CS6 0x00000010
#define LINUX_CS7 0x00000020
#define LINUX_CS8 0x00000030
#define LINUX_CSTOPB 0x00000040
#define LINUX_CREAD 0x00000080
#define LINUX_PARENB 0x00000100
#define LINUX_PARODD 0x00000200
#define LINUX_HUPCL 0x00000400
#define LINUX_CLOCAL 0x00000800
#define LINUX_CRTSCTS 0x80000000
/* Linux c_lflag masks */
#define LINUX_ISIG 0x00000001
#define LINUX_ICANON 0x00000002
#define LINUX_XCASE 0x00000004
#define LINUX_ECHO 0x00000008
#define LINUX_ECHOE 0x00000010
#define LINUX_ECHOK 0x00000020
#define LINUX_ECHONL 0x00000040
#define LINUX_NOFLSH 0x00000080
#define LINUX_TOSTOP 0x00000100
#define LINUX_ECHOCTL 0x00000200
#define LINUX_ECHOPRT 0x00000400
#define LINUX_ECHOKE 0x00000800
#define LINUX_FLUSHO 0x00001000
#define LINUX_PENDIN 0x00002000
#define LINUX_IEXTEN 0x00008000
/* open/fcntl flags */
#define LINUX_O_RDONLY 00
#define LINUX_O_WRONLY 01
#define LINUX_O_RDWR 02
#define LINUX_O_CREAT 0100
#define LINUX_O_EXCL 0200
#define LINUX_O_NOCTTY 0400
#define LINUX_O_TRUNC 01000
#define LINUX_O_APPEND 02000
#define LINUX_O_NONBLOCK 04000
#define LINUX_O_NDELAY LINUX_O_NONBLOCK
#define LINUX_O_SYNC 010000
#define LINUX_FASYNC 020000
/* fcntl flags */
#define LINUX_F_DUPFD 0
#define LINUX_F_GETFD 1
#define LINUX_F_SETFD 2
#define LINUX_F_GETFL 3
#define LINUX_F_SETFL 4
#define LINUX_F_GETLK 5
#define LINUX_F_SETLK 6
#define LINUX_F_SETLKW 7
#define LINUX_F_SETOWN 8
#define LINUX_F_GETOWN 9
#define LINUX_F_RDLCK 0
#define LINUX_F_WRLCK 1
#define LINUX_F_UNLCK 2
/* mmap options */
#define LINUX_MAP_SHARED 0x0001
#define LINUX_MAP_PRIVATE 0x0002
#define LINUX_MAP_FIXED 0x0010
#define LINUX_MAP_ANON 0x0020
/* SystemV ipc defines */
#define LINUX_SEMOP 1
#define LINUX_SEMGET 2
#define LINUX_SEMCTL 3
#define LINUX_MSGSND 11
#define LINUX_MSGRCV 12
#define LINUX_MSGGET 13
#define LINUX_MSGCTL 14
#define LINUX_SHMAT 21
#define LINUX_SHMDT 22
#define LINUX_SHMGET 23
#define LINUX_SHMCTL 24
#define LINUX_IPC_RMID 0
#define LINUX_IPC_SET 1
#define LINUX_IPC_STAT 2
#define LINUX_IPC_INFO 3
#define LINUX_SHM_LOCK 11
#define LINUX_SHM_UNLOCK 12
#define LINUX_SHM_STAT 13
#define LINUX_SHM_INFO 14
#define LINUX_SHM_RDONLY 0x1000
#define LINUX_SHM_RND 0x2000
#define LINUX_SHM_REMAP 0x4000
/* Socket defines */
#define LINUX_SOCKET 1
#define LINUX_BIND 2
#define LINUX_CONNECT 3
#define LINUX_LISTEN 4
#define LINUX_ACCEPT 5
#define LINUX_GETSOCKNAME 6
#define LINUX_GETPEERNAME 7
#define LINUX_SOCKETPAIR 8
#define LINUX_SEND 9
#define LINUX_RECV 10
#define LINUX_SENDTO 11
#define LINUX_RECVFROM 12
#define LINUX_SHUTDOWN 13
#define LINUX_SETSOCKOPT 14
#define LINUX_GETSOCKOPT 15
#define LINUX_AF_UNSPEC 0
#define LINUX_AF_UNIX 1
#define LINUX_AF_INET 2
#define LINUX_AF_AX25 3
#define LINUX_AF_IPX 4
#define LINUX_AF_APPLETALK 5
#define LINUX_SOL_SOCKET 1
#define LINUX_SOL_IP 0
#define LINUX_SOL_IPX 256
#define LINUX_SOL_AX25 257
#define LINUX_SOL_TCP 6
#define LINUX_SOL_UDP 17
#define LINUX_SO_DEBUG 1
#define LINUX_SO_REUSEADDR 2
#define LINUX_SO_TYPE 3
#define LINUX_SO_ERROR 4
#define LINUX_SO_DONTROUTE 5
#define LINUX_SO_BROADCAST 6
#define LINUX_SO_SNDBUF 7
#define LINUX_SO_RCVBUF 8
#define LINUX_SO_KEEPALIVE 9
#define LINUX_SO_OOBINLINE 10
#define LINUX_SO_NO_CHECK 11
#define LINUX_SO_PRIORITY 12
#define LINUX_SO_LINGER 13
#define LINUX_IP_TOS 1
#define LINUX_IP_TTL 2
#endif /* LINUX_H */

View File

@ -0,0 +1,316 @@
/*-
* Copyright (c) 1994-1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux_dummy.c,v 1.3 1995/06/08 13:50:52 sos Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/resourcevar.h>
#include <sys/errno.h>
#include <vm/vm.h>
int
linux_setup(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): setup() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_break(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): break() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_stat(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): stat() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_fstat(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): fstat() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_mount(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): mount() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_umount(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): umount() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_stime(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): stime() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_ptrace(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): ptrace() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_pause(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): pause() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_stty(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): stty() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_gtty(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): gtty() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_nice(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): nice() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_ftime(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): ftime() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_prof(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): prof() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_signal(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): signal() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_phys(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): phys() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_lock(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): lock() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_mpx(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): mpx() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_ulimit(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): ulimit() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_olduname(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): olduname() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_ustat(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): ustat() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_ioperm(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): ioperm() not supported\n", p->p_pid);
return 0; /* EINVAL SOS XXX */
}
int
linux_syslog(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): syslog() not supported (BSD sigreturn)\n",p->p_pid);
return sigreturn(p, args, retval);
}
int
linux_iopl(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): iopl() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_vhangup(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): vhangup() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_idle(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): idle() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_vm86(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): vm86() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_swapoff(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): swapoff() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_sysinfo(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): sysinfo() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_sigreturn(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): sigreturn() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_clone(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): clone() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_uname(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): uname() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_modify_ldt(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): modify_ldt() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_adjtimex(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): adjtimex() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_create_module(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): create_module() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_init_module(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): init_module() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_delete_module(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): delete_module() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_get_kernel_syms(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): get_kernel_syms() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_quotactl(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): quotactl() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_bdflush(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): bdflush() not supported\n", p->p_pid);
return ENOSYS;
}

View File

@ -0,0 +1,436 @@
/*-
* Copyright (c) 1994-1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux_file.c,v 1.2 1995/06/07 21:27:57 sos Exp $
*/
#include <i386/linux/linux.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/proc.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/vnode.h>
#include <sys/malloc.h>
#include <sys/exec.h>
#include <sys/dirent.h>
#include <vm/vm.h>
#include <ufs/ufs/dir.h>
struct linux_creat_args {
char *path;
int mode;
};
int
linux_creat(struct proc *p, struct linux_creat_args *args, int *retval)
{
struct {
char *path;
int flags;
int mode;
} bsd_open_args;
#ifdef DEBUG
printf("Linux-emul(%d): creat(%s, %d)\n",
p->p_pid, args->path, args->mode);
#endif
bsd_open_args.path = args->path;
bsd_open_args.mode = args->mode;
bsd_open_args.flags = O_WRONLY | O_CREAT | O_TRUNC;
return open(p, &bsd_open_args, retval);
}
struct linux_open_args {
char *path;
int flags;
int mode;
};
int
linux_open(struct proc *p, struct linux_open_args *args, int *retval)
{
struct {
char *path;
int flags;
int mode;
} bsd_open_args;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): open(%s, 0x%x, 0x%x)\n",
p->p_pid, args->path, args->flags, args->mode);
#endif
bsd_open_args.flags = 0;
if (args->flags & LINUX_O_RDONLY)
bsd_open_args.flags |= O_RDONLY;
if (args->flags & LINUX_O_WRONLY)
bsd_open_args.flags |= O_WRONLY;
if (args->flags & LINUX_O_RDWR)
bsd_open_args.flags |= O_RDWR;
if (args->flags & LINUX_O_NDELAY)
bsd_open_args.flags |= O_NONBLOCK;
if (args->flags & LINUX_O_APPEND)
bsd_open_args.flags |= O_APPEND;
if (args->flags & LINUX_O_SYNC)
bsd_open_args.flags |= O_FSYNC;
if (args->flags & LINUX_O_NONBLOCK)
bsd_open_args.flags |= O_NONBLOCK;
if (args->flags & LINUX_FASYNC)
bsd_open_args.flags |= O_ASYNC;
if (args->flags & LINUX_O_CREAT)
bsd_open_args.flags |= O_CREAT;
if (args->flags & LINUX_O_TRUNC)
bsd_open_args.flags |= O_TRUNC;
if (args->flags & LINUX_O_EXCL)
bsd_open_args.flags |= O_EXCL;
if (args->flags & LINUX_O_NOCTTY)
bsd_open_args.flags |= O_NOCTTY;
bsd_open_args.path = args->path;
bsd_open_args.mode = args->mode;
error = open(p, &bsd_open_args, retval);
if (!error && !(bsd_open_args.flags & O_NOCTTY) &&
SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
struct filedesc *fdp = p->p_fd;
struct file *fp = fdp->fd_ofiles[*retval];
if (fp->f_type == DTYPE_VNODE)
(fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, (caddr_t) 0, p);
}
return error;
}
struct linux_flock {
short l_type;
short l_whence;
linux_off_t l_start;
linux_off_t l_len;
linux_pid_t l_pid;
};
static void
linux_to_bsd_flock(struct linux_flock *linux_flock, struct flock *bsd_flock)
{
switch (linux_flock->l_type) {
case LINUX_F_RDLCK:
bsd_flock->l_type = F_RDLCK;
break;
case LINUX_F_WRLCK:
bsd_flock->l_type = F_WRLCK;
break;
case LINUX_F_UNLCK:
bsd_flock->l_type = F_UNLCK;
break;
}
bsd_flock->l_whence = linux_flock->l_whence;
bsd_flock->l_start = (off_t)linux_flock->l_start;
bsd_flock->l_len = (off_t)linux_flock->l_len;
bsd_flock->l_pid = (pid_t)linux_flock->l_pid;
}
static void
bsd_to_linux_flock(struct flock *bsd_flock, struct linux_flock *linux_flock)
{
switch (bsd_flock->l_type) {
case F_RDLCK:
linux_flock->l_type = LINUX_F_RDLCK;
break;
case F_WRLCK:
linux_flock->l_type = LINUX_F_WRLCK;
break;
case F_UNLCK:
linux_flock->l_type = LINUX_F_UNLCK;
break;
}
linux_flock->l_whence = bsd_flock->l_whence;
linux_flock->l_start = (linux_off_t)bsd_flock->l_start;
linux_flock->l_len = (linux_off_t)bsd_flock->l_len;
linux_flock->l_pid = (linux_pid_t)bsd_flock->l_pid;
}
struct linux_fcntl_args {
int fd;
int cmd;
int arg;
};
int
linux_fcntl(struct proc *p, struct linux_fcntl_args *args, int *retval)
{
int error, result;
struct fcntl_args {
int fd;
int cmd;
int arg;
} fcntl_args;
struct linux_flock linux_flock;
struct flock *bsd_flock =
(struct flock *)ua_alloc_init(sizeof(struct flock));
#ifdef DEBUG
printf("Linux-emul(%d): fcntl(%d, %08x, *)\n",
p->p_pid, args->fd, args->cmd);
#endif
fcntl_args.fd = args->fd;
fcntl_args.arg = 0;
switch (args->cmd) {
case LINUX_F_DUPFD:
fcntl_args.cmd = F_DUPFD;
return fcntl(p, &fcntl_args, retval);
case LINUX_F_GETFD:
fcntl_args.cmd = F_GETFD;
return fcntl(p, &fcntl_args, retval);
case LINUX_F_SETFD:
fcntl_args.cmd = F_SETFD;
return fcntl(p, &fcntl_args, retval);
case LINUX_F_GETFL:
fcntl_args.cmd = F_GETFL;
error = fcntl(p, &fcntl_args, &result);
*retval = 0;
if (result & O_RDONLY) *retval |= LINUX_O_RDONLY;
if (result & O_WRONLY) *retval |= LINUX_O_WRONLY;
if (result & O_RDWR) *retval |= LINUX_O_RDWR;
if (result & O_NDELAY) *retval |= LINUX_O_NONBLOCK;
if (result & O_APPEND) *retval |= LINUX_O_APPEND;
if (result & O_FSYNC) *retval |= LINUX_O_SYNC;
return error;
case LINUX_F_SETFL:
if (args->arg & LINUX_O_NDELAY) fcntl_args.arg |= O_NONBLOCK;
if (args->arg & LINUX_O_APPEND) fcntl_args.arg |= O_APPEND;
if (args->arg & LINUX_O_SYNC) fcntl_args.arg |= O_FSYNC;
fcntl_args.cmd = F_SETFL;
return fcntl(p, &fcntl_args, retval);
case LINUX_F_GETLK:
if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock,
sizeof(struct linux_flock))))
return error;
linux_to_bsd_flock(&linux_flock, bsd_flock);
fcntl_args.cmd = F_GETLK;
fcntl_args.arg = (int)bsd_flock;
if (error = fcntl(p, &fcntl_args, retval))
return error;
bsd_to_linux_flock(bsd_flock, &linux_flock);
return copyout((caddr_t)&linux_flock, (caddr_t)args->arg,
sizeof(struct linux_flock));
case LINUX_F_SETLK:
if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock,
sizeof(struct linux_flock))))
return error;
linux_to_bsd_flock(&linux_flock, bsd_flock);
fcntl_args.cmd = F_SETLK;
fcntl_args.arg = (int)bsd_flock;
return fcntl(p, &fcntl_args, retval);
case LINUX_F_SETLKW:
if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock,
sizeof(struct linux_flock))))
return error;
linux_to_bsd_flock(&linux_flock, bsd_flock);
fcntl_args.cmd = F_SETLKW;
fcntl_args.arg = (int)bsd_flock;
return fcntl(p, &fcntl_args, retval);
case LINUX_F_SETOWN:
fcntl_args.cmd = F_SETOWN;
return fcntl(p, &fcntl_args, retval);
case LINUX_F_GETOWN:
fcntl_args.cmd = F_GETOWN;
return fcntl(p, &fcntl_args, retval);
}
return EINVAL;
}
struct linux_lseek_args {
int fdes;
unsigned long off;
int whence;
};
int
linux_lseek(struct proc *p, struct linux_lseek_args *args, int *retval)
{
struct lseek_args {
int fdes;
int pad;
off_t off;
int whence;
} tmp_args;
off_t tmp_retval;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): lseek(%d, %d, %d)\n",
p->p_pid, args->fdes, args->off, args->whence);
#endif
tmp_args.fdes = args->fdes;
tmp_args.off = (off_t)args->off;
tmp_args.whence = args->whence;
error = lseek(p, &tmp_args, &tmp_retval);
*retval = (int)tmp_retval;
return error;
}
struct linux_dirent {
long dino;
linux_off_t doff;
unsigned short dreclen;
char dname[LINUX_NAME_MAX + 1];
};
#define LINUX_RECLEN(de,namlen) \
ALIGN((((char *)&(de)->dname - (char *)de) + (namlen) + 1))
struct linux_readdir_args {
int fd;
struct linux_dirent *dent;
unsigned int count;
};
int
linux_readdir(struct proc *p, struct linux_readdir_args *args, int *retval)
{
register struct dirent *bdp;
struct vnode *vp;
caddr_t inp, buf; /* BSD-format */
int len, reclen; /* BSD-format */
caddr_t outp; /* Linux-format */
int resid, linuxreclen=0; /* Linux-format */
struct file *fp;
struct uio auio;
struct iovec aiov;
struct vattr va;
off_t off;
struct linux_dirent linux_dirent;
int buflen, error, eofflag, nbytes, justone;
#ifdef DEBUG
printf("Linux-emul(%d): readdir(%d, *, %d)\n",
p->p_pid, args->fd, args->count);
#endif
if ((error = getvnode(p->p_fd, args->fd, &fp)) != 0)
return (error);
if ((fp->f_flag & FREAD) == 0)
return (EBADF);
vp = (struct vnode *) fp->f_data;
if (vp->v_type != VDIR)
return (EINVAL);
if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)))
return error;
nbytes = args->count;
if (nbytes == 1) {
nbytes = sizeof (struct linux_dirent);
justone = 1;
}
else
justone = 0;
buflen = max(va.va_blocksize, nbytes);
buf = malloc(buflen, M_TEMP, M_WAITOK);
VOP_LOCK(vp);
off = fp->f_offset;
again:
aiov.iov_base = buf;
aiov.iov_len = buflen;
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_rw = UIO_READ;
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_procp = p;
auio.uio_resid = buflen;
auio.uio_offset = off;
error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, (u_long *) 0, 0);
if (error)
goto out;
inp = buf;
outp = (caddr_t) args->dent;
resid = nbytes;
if ((len = buflen - auio.uio_resid) == 0)
goto eof;
while (len > 0) {
reclen = ((struct dirent *) inp)->d_reclen;
if (reclen & 3)
panic("linux_readdir");
off += reclen;
bdp = (struct dirent *) inp;
if (bdp->d_fileno == 0) {
inp += reclen;
continue;
}
linuxreclen = LINUX_RECLEN(&linux_dirent, bdp->d_namlen);
if (reclen > len || resid < linuxreclen) {
outp++;
break;
}
linux_dirent.dino = (long) bdp->d_fileno;
linux_dirent.doff = (linux_off_t) linuxreclen;
linux_dirent.dreclen = (u_short) bdp->d_namlen;
strcpy(linux_dirent.dname, bdp->d_name);
if ((error = copyout((caddr_t)&linux_dirent, outp, linuxreclen)))
goto out;
inp += reclen;
outp += linuxreclen;
resid -= linuxreclen;
len -= reclen;
if (justone)
break;
}
if (outp == (caddr_t) args->dent)
goto again;
fp->f_offset = off;
if (justone)
nbytes = resid + linuxreclen;
eof:
*retval = nbytes - resid;
out:
VOP_UNLOCK(vp);
free(buf, M_TEMP);
return error;
}

View File

@ -0,0 +1,495 @@
/*-
* Copyright (c) 1994-1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux_ioctl.c,v 1.2 1995/06/07 21:27:57 sos Exp $
*/
#include <i386/linux/linux.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/ioctl.h>
#include <sys/ioctl_compat.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/tty.h>
#include <sys/termios.h>
#include <machine/console.h>
struct linux_termios {
unsigned long c_iflag;
unsigned long c_oflag;
unsigned long c_cflag;
unsigned long c_lflag;
unsigned char c_line;
unsigned char c_cc[LINUX_NCCS];
};
struct linux_winsize {
unsigned short ws_row, ws_col;
unsigned short ws_xpixel, ws_ypixel;
};
static struct speedtab sptab[] = {
{ 0, 0 }, { 50, 1 }, { 75, 2 }, { 110, 3 },
{ 134, 4 }, { 135, 4 }, { 150, 5 }, { 200, 6 },
{ 300, 7 }, { 600, 8 }, { 1200, 9 }, { 1800, 10 },
{ 2400, 11 }, { 4800, 12 }, { 9600, 13 },
{ 19200, 14 }, { 38400, 15 },
{ 57600, 4097 }, { 115200, 4098 }, {-1, -1 }
};
static int
linux_to_bsd_speed(int code, struct speedtab *table)
{
for ( ; table->sp_code != -1; table++)
if (table->sp_code == code)
return (table->sp_speed);
return -1;
}
static int
bsd_to_linux_speed(int speed, struct speedtab *table)
{
for ( ; table->sp_speed != -1; table++)
if (table->sp_speed == speed)
return (table->sp_code);
return -1;
}
static void
bsd_to_linux_termios(struct termios *bsd_termios,
struct linux_termios *linux_termios)
{
int i, speed;
#ifdef DEBUG
printf("LINUX: BSD termios structure (input):\n");
printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
bsd_termios->c_iflag, bsd_termios->c_oflag,
bsd_termios->c_cflag, bsd_termios->c_lflag,
bsd_termios->c_ispeed, bsd_termios->c_ospeed);
printf("c_cc ");
for (i=0; i<NCCS; i++)
printf("%02x ", bsd_termios->c_cc[i]);
printf("\n");
#endif
linux_termios->c_iflag = 0;
if (bsd_termios->c_iflag & IGNBRK)
linux_termios->c_iflag |= LINUX_IGNBRK;
if (bsd_termios->c_iflag & BRKINT)
linux_termios->c_iflag |= LINUX_BRKINT;
if (bsd_termios->c_iflag & IGNPAR)
linux_termios->c_iflag |= LINUX_IGNPAR;
if (bsd_termios->c_iflag & PARMRK)
linux_termios->c_iflag |= LINUX_PARMRK;
if (bsd_termios->c_iflag & INPCK)
linux_termios->c_iflag |= LINUX_INPCK;
if (bsd_termios->c_iflag & ISTRIP)
linux_termios->c_iflag |= LINUX_ISTRIP;
if (bsd_termios->c_iflag & INLCR)
linux_termios->c_iflag |= LINUX_INLCR;
if (bsd_termios->c_iflag & IGNCR)
linux_termios->c_iflag |= LINUX_IGNCR;
if (bsd_termios->c_iflag & ICRNL)
linux_termios->c_iflag |= LINUX_ICRNL;
if (bsd_termios->c_iflag & IXON)
linux_termios->c_iflag |= LINUX_IXANY;
if (bsd_termios->c_iflag & IXON)
linux_termios->c_iflag |= LINUX_IXON;
if (bsd_termios->c_iflag & IXOFF)
linux_termios->c_iflag |= LINUX_IXOFF;
if (bsd_termios->c_iflag & IMAXBEL)
linux_termios->c_iflag |= LINUX_IMAXBEL;
linux_termios->c_oflag = 0;
if (bsd_termios->c_oflag & OPOST)
linux_termios->c_oflag |= LINUX_OPOST;
if (bsd_termios->c_oflag & ONLCR)
linux_termios->c_oflag |= LINUX_ONLCR;
if (bsd_termios->c_oflag & OXTABS)
linux_termios->c_oflag |= LINUX_XTABS;
linux_termios->c_cflag =
bsd_to_linux_speed(bsd_termios->c_ispeed, sptab);
linux_termios->c_cflag |= (bsd_termios->c_cflag & CSIZE) >> 4;
if (bsd_termios->c_cflag & CSTOPB)
linux_termios->c_cflag |= LINUX_CSTOPB;
if (bsd_termios->c_cflag & CREAD)
linux_termios->c_cflag |= LINUX_CREAD;
if (bsd_termios->c_cflag & PARENB)
linux_termios->c_cflag |= LINUX_PARENB;
if (bsd_termios->c_cflag & PARODD)
linux_termios->c_cflag |= LINUX_PARODD;
if (bsd_termios->c_cflag & HUPCL)
linux_termios->c_cflag |= LINUX_HUPCL;
if (bsd_termios->c_cflag & CLOCAL)
linux_termios->c_cflag |= LINUX_CLOCAL;
if (bsd_termios->c_cflag & CRTSCTS)
linux_termios->c_cflag |= LINUX_CRTSCTS;
linux_termios->c_lflag = 0;
if (bsd_termios->c_lflag & ISIG)
linux_termios->c_lflag |= LINUX_ISIG;
if (bsd_termios->c_lflag & ICANON)
linux_termios->c_lflag |= LINUX_ICANON;
if (bsd_termios->c_lflag & ECHO)
linux_termios->c_lflag |= LINUX_ECHO;
if (bsd_termios->c_lflag & ECHOE)
linux_termios->c_lflag |= LINUX_ECHOE;
if (bsd_termios->c_lflag & ECHOK)
linux_termios->c_lflag |= LINUX_ECHOK;
if (bsd_termios->c_lflag & ECHONL)
linux_termios->c_lflag |= LINUX_ECHONL;
if (bsd_termios->c_lflag & NOFLSH)
linux_termios->c_lflag |= LINUX_NOFLSH;
if (bsd_termios->c_lflag & TOSTOP)
linux_termios->c_lflag |= LINUX_TOSTOP;
if (bsd_termios->c_lflag & ECHOCTL)
linux_termios->c_lflag |= LINUX_ECHOCTL;
if (bsd_termios->c_lflag & ECHOPRT)
linux_termios->c_lflag |= LINUX_ECHOPRT;
if (bsd_termios->c_lflag & ECHOKE)
linux_termios->c_lflag |= LINUX_ECHOKE;
if (bsd_termios->c_lflag & FLUSHO)
linux_termios->c_lflag |= LINUX_FLUSHO;
if (bsd_termios->c_lflag & PENDIN)
linux_termios->c_lflag |= LINUX_PENDIN;
if (bsd_termios->c_lflag & IEXTEN)
linux_termios->c_lflag |= LINUX_IEXTEN;
for (i=0; i<LINUX_NCCS; i++)
linux_termios->c_cc[i] = _POSIX_VDISABLE;
linux_termios->c_cc[LINUX_VINTR] = bsd_termios->c_cc[VINTR];
linux_termios->c_cc[LINUX_VQUIT] = bsd_termios->c_cc[VQUIT];
linux_termios->c_cc[LINUX_VERASE] = bsd_termios->c_cc[VERASE];
linux_termios->c_cc[LINUX_VKILL] = bsd_termios->c_cc[VKILL];
linux_termios->c_cc[LINUX_VEOF] = bsd_termios->c_cc[VEOF];
linux_termios->c_cc[LINUX_VEOL] = bsd_termios->c_cc[VEOL];
linux_termios->c_cc[LINUX_VMIN] = bsd_termios->c_cc[VMIN];
linux_termios->c_cc[LINUX_VTIME] = bsd_termios->c_cc[VTIME];
linux_termios->c_cc[LINUX_VEOL2] = bsd_termios->c_cc[VEOL2];
linux_termios->c_cc[LINUX_VSWTC] = _POSIX_VDISABLE;
linux_termios->c_cc[LINUX_VSUSP] = bsd_termios->c_cc[VSUSP];
linux_termios->c_cc[LINUX_VSTART] = bsd_termios->c_cc[VSTART];
linux_termios->c_cc[LINUX_VSTOP] = bsd_termios->c_cc[VSTOP];
linux_termios->c_cc[LINUX_VREPRINT] = bsd_termios->c_cc[VREPRINT];
linux_termios->c_cc[LINUX_VDISCARD] = bsd_termios->c_cc[VDISCARD];
linux_termios->c_cc[LINUX_VWERASE] = bsd_termios->c_cc[VWERASE];
linux_termios->c_cc[LINUX_VLNEXT] = bsd_termios->c_cc[VLNEXT];
linux_termios->c_line = 0;
#ifdef DEBUG
printf("LINUX: LINUX termios structure (output):\n");
printf("i=%08x o=%08x c=%08x l=%08x line=%d\n",
linux_termios->c_iflag, linux_termios->c_oflag,
linux_termios->c_cflag, linux_termios->c_lflag,
linux_termios->c_line);
printf("c_cc ");
for (i=0; i<LINUX_NCCS; i++)
printf("%02x ", linux_termios->c_cc[i]);
printf("\n");
#endif
}
static void
linux_to_bsd_termios(struct linux_termios *linux_termios,
struct termios *bsd_termios)
{
int i, speed;
#ifdef DEBUG
printf("LINUX: LINUX termios structure (input):\n");
printf("i=%08x o=%08x c=%08x l=%08x line=%d\n",
linux_termios->c_iflag, linux_termios->c_oflag,
linux_termios->c_cflag, linux_termios->c_lflag,
linux_termios->c_line);
printf("c_cc ");
for (i=0; i<LINUX_NCCS; i++)
printf("%02x ", linux_termios->c_cc[i]);
printf("\n");
#endif
bsd_termios->c_iflag = 0;
if (linux_termios->c_iflag & LINUX_IGNBRK)
bsd_termios->c_iflag |= IGNBRK;
if (linux_termios->c_iflag & LINUX_BRKINT)
bsd_termios->c_iflag |= BRKINT;
if (linux_termios->c_iflag & LINUX_IGNPAR)
bsd_termios->c_iflag |= IGNPAR;
if (linux_termios->c_iflag & LINUX_PARMRK)
bsd_termios->c_iflag |= PARMRK;
if (linux_termios->c_iflag & LINUX_INPCK)
bsd_termios->c_iflag |= INPCK;
if (linux_termios->c_iflag & LINUX_ISTRIP)
bsd_termios->c_iflag |= ISTRIP;
if (linux_termios->c_iflag & LINUX_INLCR)
bsd_termios->c_iflag |= INLCR;
if (linux_termios->c_iflag & LINUX_IGNCR)
bsd_termios->c_iflag |= IGNCR;
if (linux_termios->c_iflag & LINUX_ICRNL)
bsd_termios->c_iflag |= ICRNL;
if (linux_termios->c_iflag & LINUX_IXON)
bsd_termios->c_iflag |= IXANY;
if (linux_termios->c_iflag & LINUX_IXON)
bsd_termios->c_iflag |= IXON;
if (linux_termios->c_iflag & LINUX_IXOFF)
bsd_termios->c_iflag |= IXOFF;
if (linux_termios->c_iflag & LINUX_IMAXBEL)
bsd_termios->c_iflag |= IMAXBEL;
bsd_termios->c_oflag = 0;
if (linux_termios->c_oflag & LINUX_OPOST)
bsd_termios->c_oflag |= OPOST;
if (linux_termios->c_oflag & LINUX_ONLCR)
bsd_termios->c_oflag |= ONLCR;
if (linux_termios->c_oflag & LINUX_XTABS)
bsd_termios->c_oflag |= OXTABS;
bsd_termios->c_cflag = (linux_termios->c_cflag & LINUX_CSIZE) << 4;
if (linux_termios->c_cflag & LINUX_CSTOPB)
bsd_termios->c_cflag |= CSTOPB;
if (linux_termios->c_cflag & LINUX_PARENB)
bsd_termios->c_cflag |= PARENB;
if (linux_termios->c_cflag & LINUX_PARODD)
bsd_termios->c_cflag |= PARODD;
if (linux_termios->c_cflag & LINUX_HUPCL)
bsd_termios->c_cflag |= HUPCL;
if (linux_termios->c_cflag & LINUX_CLOCAL)
bsd_termios->c_cflag |= CLOCAL;
if (linux_termios->c_cflag & LINUX_CRTSCTS)
bsd_termios->c_cflag |= CRTSCTS;
bsd_termios->c_lflag = 0;
if (linux_termios->c_lflag & LINUX_ISIG)
bsd_termios->c_lflag |= ISIG;
if (linux_termios->c_lflag & LINUX_ICANON)
bsd_termios->c_lflag |= ICANON;
if (linux_termios->c_lflag & LINUX_ECHO)
bsd_termios->c_lflag |= ECHO;
if (linux_termios->c_lflag & LINUX_ECHOE)
bsd_termios->c_lflag |= ECHOE;
if (linux_termios->c_lflag & LINUX_ECHOK)
bsd_termios->c_lflag |= ECHOK;
if (linux_termios->c_lflag & LINUX_ECHONL)
bsd_termios->c_lflag |= ECHONL;
if (linux_termios->c_lflag & LINUX_NOFLSH)
bsd_termios->c_lflag |= NOFLSH;
if (linux_termios->c_lflag & LINUX_TOSTOP)
bsd_termios->c_lflag |= TOSTOP;
if (linux_termios->c_lflag & LINUX_ECHOCTL)
bsd_termios->c_lflag |= ECHOCTL;
if (linux_termios->c_lflag & LINUX_ECHOPRT)
bsd_termios->c_lflag |= ECHOPRT;
if (linux_termios->c_lflag & LINUX_ECHOKE)
bsd_termios->c_lflag |= ECHOKE;
if (linux_termios->c_lflag & LINUX_FLUSHO)
bsd_termios->c_lflag |= FLUSHO;
if (linux_termios->c_lflag & LINUX_PENDIN)
bsd_termios->c_lflag |= PENDIN;
if (linux_termios->c_lflag & IEXTEN)
bsd_termios->c_lflag |= IEXTEN;
for (i=0; i<NCCS; i++)
bsd_termios->c_cc[i] = _POSIX_VDISABLE;
bsd_termios->c_cc[VINTR] = linux_termios->c_cc[LINUX_VINTR];
bsd_termios->c_cc[VQUIT] = linux_termios->c_cc[LINUX_VQUIT];
bsd_termios->c_cc[VERASE] = linux_termios->c_cc[LINUX_VERASE];
bsd_termios->c_cc[VKILL] = linux_termios->c_cc[LINUX_VKILL];
bsd_termios->c_cc[VEOF] = linux_termios->c_cc[LINUX_VEOF];
bsd_termios->c_cc[VEOL] = linux_termios->c_cc[LINUX_VEOL];
bsd_termios->c_cc[VMIN] = linux_termios->c_cc[LINUX_VMIN];
bsd_termios->c_cc[VTIME] = linux_termios->c_cc[LINUX_VTIME];
bsd_termios->c_cc[VEOL2] = linux_termios->c_cc[LINUX_VEOL2];
bsd_termios->c_cc[VSUSP] = linux_termios->c_cc[LINUX_VSUSP];
bsd_termios->c_cc[VSTART] = linux_termios->c_cc[LINUX_VSTART];
bsd_termios->c_cc[VSTOP] = linux_termios->c_cc[LINUX_VSTOP];
bsd_termios->c_cc[VREPRINT] = linux_termios->c_cc[LINUX_VREPRINT];
bsd_termios->c_cc[VDISCARD] = linux_termios->c_cc[LINUX_VDISCARD];
bsd_termios->c_cc[VWERASE] = linux_termios->c_cc[LINUX_VWERASE];
bsd_termios->c_cc[VLNEXT] = linux_termios->c_cc[LINUX_VLNEXT];
bsd_termios->c_ispeed = bsd_termios->c_ospeed =
linux_to_bsd_speed(linux_termios->c_cflag & LINUX_CBAUD, sptab);
#ifdef DEBUG
printf("LINUX: BSD termios structure (output):\n");
printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
bsd_termios->c_iflag, bsd_termios->c_oflag,
bsd_termios->c_cflag, bsd_termios->c_lflag,
bsd_termios->c_ispeed, bsd_termios->c_ospeed);
printf("c_cc ");
for (i=0; i<NCCS; i++)
printf("%02x ", bsd_termios->c_cc[i]);
printf("\n");
#endif
}
struct linux_ioctl_args {
int fd;
int cmd;
int arg;
};
int
linux_ioctl(struct proc *p, struct linux_ioctl_args *args, int *retval)
{
struct termios bsd_termios;
struct winsize bsd_winsize;
struct linux_termios linux_termios;
struct linux_winsize linux_winsize;
struct filedesc *fdp = p->p_fd;
struct file *fp;
int (*func)();
int bsd_line, linux_line;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): ioctl(%d, %04x, *)\n",
p->p_pid, args->fd, args->cmd);
#endif
if ((unsigned)args->fd >= fdp->fd_nfiles
|| (fp = fdp->fd_ofiles[args->fd]) == 0)
return EBADF;
if (!fp || (fp->f_flag & (FREAD | FWRITE)) == 0) {
return EBADF;
}
func = fp->f_ops->fo_ioctl;
switch (args->cmd) {
case LINUX_TCGETS:
if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0)
return error;
bsd_to_linux_termios(&bsd_termios, &linux_termios);
return copyout((caddr_t)&linux_termios, (caddr_t)args->arg,
sizeof(linux_termios));
case LINUX_TCSETS:
linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios);
return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p);
case LINUX_TCSETSW:
linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios);
return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p);
case LINUX_TCSETSF:
linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios);
return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p);
case LINUX_TIOCGPGRP:
args->cmd = TIOCGPGRP;
return ioctl(p, args, retval);
case LINUX_TIOCSPGRP:
args->cmd = TIOCSPGRP;
return ioctl(p, args, retval);
case LINUX_TIOCGWINSZ:
args->cmd = TIOCGWINSZ;
return ioctl(p, args, retval);
case LINUX_TIOCSWINSZ:
args->cmd = TIOCSWINSZ;
return ioctl(p, args, retval);
case LINUX_FIONREAD:
args->cmd = FIONREAD;
return ioctl(p, args, retval);
case LINUX_FIONBIO:
args->cmd = FIONBIO;
return ioctl(p, args, retval);
case LINUX_FIOASYNC:
args->cmd = FIOASYNC;
return ioctl(p, args, retval);
case LINUX_FIONCLEX:
args->cmd = FIONCLEX;
return ioctl(p, args, retval);
case LINUX_FIOCLEX:
args->cmd = FIOCLEX;
return ioctl(p, args, retval);
case LINUX_TIOCEXCL:
args->cmd = TIOCEXCL;
return ioctl(p, args, retval);
case LINUX_TIOCNXCL:
args->cmd = TIOCNXCL;
return ioctl(p, args, retval);
case LINUX_TIOCCONS:
args->cmd = TIOCCONS;
return ioctl(p, args, retval);
case LINUX_TIOCNOTTY:
args->cmd = TIOCNOTTY;
return ioctl(p, args, retval);
case LINUX_TIOCSETD:
switch (args->arg) {
case LINUX_N_TTY:
bsd_line = TTYDISC;
return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
case LINUX_N_SLIP:
bsd_line = SLIPDISC;
return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
case LINUX_N_PPP:
bsd_line = PPPDISC;
return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
default:
return EINVAL;
}
break;
case LINUX_TIOCGETD:
bsd_line = TTYDISC;
if (error =(*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p))
return error;
switch (bsd_line) {
case TTYDISC:
linux_line = LINUX_N_TTY;
break;
case SLIPDISC:
linux_line = LINUX_N_SLIP;
break;
case PPPDISC:
linux_line = LINUX_N_PPP;
break;
default:
return EINVAL;
}
return copyout(&linux_line, (caddr_t)args->arg,
sizeof(int));
}
uprintf("LINUX: 'ioctl' fd=%d, typ=0x%x(%c), num=0x%x not implemented\n",
args->fd, (args->cmd&0xffff00)>>8,
(args->cmd&0xffff00)>>8, args->cmd&0xff);
return EINVAL;
}

View File

@ -0,0 +1,308 @@
/*-
* Copyright (c) 1994-1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux_ipc.c,v 1.2 1995/06/07 21:27:57 sos Exp $
*/
#include <i386/linux/linux.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/exec.h>
#include <sys/proc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <vm/vm.h>
struct linux_ipc_perm {
linux_key_t key;
unsigned short uid;
unsigned short gid;
unsigned short cuid;
unsigned short cgid;
unsigned short mode;
unsigned short seq;
};
static void
linux_to_bsd_ipc_perm(struct linux_ipc_perm *lpp, struct ipc_perm *bpp)
{
bpp->key = lpp->key;
bpp->uid = lpp->uid;
bpp->gid = lpp->gid;
bpp->cuid = lpp->cuid;
bpp->cgid = lpp->cgid;
bpp->mode = lpp->mode;
bpp->seq = lpp->seq;
}
static void
bsd_to_linux_ipc_perm(struct ipc_perm *bpp, struct linux_ipc_perm *lpp)
{
lpp->key = bpp->key;
lpp->uid = bpp->uid;
lpp->gid = bpp->gid;
lpp->cuid = bpp->cuid;
lpp->cgid = bpp->cgid;
lpp->mode = bpp->mode;
lpp->seq = bpp->seq;
}
struct linux_shmid_ds {
struct linux_ipc_perm shm_perm;
int shm_segsz;
linux_time_t shm_atime;
linux_time_t shm_dtime;
linux_time_t shm_ctime;
ushort shm_cpid;
ushort shm_lpid;
short shm_nattch;
ushort private1;
void *private2;
void *private3;
};
static void
linux_to_bsd_shmid_ds(struct linux_shmid_ds *lsp, struct shmid_ds *bsp)
{
linux_to_bsd_ipc_perm(&lsp->shm_perm, &bsp->shm_perm);
bsp->shm_segsz = lsp->shm_segsz;
bsp->shm_lpid = lsp->shm_lpid;
bsp->shm_cpid = lsp->shm_cpid;
bsp->shm_nattch = lsp->shm_nattch;
bsp->shm_atime = lsp->shm_atime;
bsp->shm_dtime = lsp->shm_dtime;
bsp->shm_ctime = lsp->shm_ctime;
bsp->shm_internal = lsp->private3; /* this goes (yet) SOS */
}
static void
bsd_to_linux_shmid_ds(struct shmid_ds *bsp, struct linux_shmid_ds *lsp)
{
bsd_to_linux_ipc_perm(&bsp->shm_perm, &lsp->shm_perm);
lsp->shm_segsz = bsp->shm_segsz;
lsp->shm_lpid = bsp->shm_lpid;
lsp->shm_cpid = bsp->shm_cpid;
lsp->shm_nattch = bsp->shm_nattch;
lsp->shm_atime = bsp->shm_atime;
lsp->shm_dtime = bsp->shm_dtime;
lsp->shm_ctime = bsp->shm_ctime;
lsp->private3 = bsp->shm_internal; /* this goes (yet) SOS */
}
struct linux_ipc_args {
int what;
int arg1;
int arg2;
int arg3;
caddr_t ptr;
};
int
linux_semop(struct proc *p, struct linux_ipc_args *args, int *retval)
{
return ENOSYS;
}
int
linux_semget(struct proc *p, struct linux_ipc_args *args, int *retval)
{
return ENOSYS;
}
int
linux_semctl(struct proc *p, struct linux_ipc_args *args, int *retval)
{
return ENOSYS;
}
int
linux_msgsnd(struct proc *p, struct linux_ipc_args *args, int *retval)
{
return ENOSYS;
}
int
linux_msgrcv(struct proc *p, struct linux_ipc_args *args, int *retval)
{
return ENOSYS;
}
int
linux_msgget(struct proc *p, struct linux_ipc_args *args, int *retval)
{
return ENOSYS;
}
int
linux_msgctl(struct proc *p, struct linux_ipc_args *args, int *retval)
{
return ENOSYS;
}
int
linux_shmat(struct proc *p, struct linux_ipc_args *args, int *retval)
{
struct shmat_args {
int shmid;
void *shmaddr;
int shmflg;
} bsd_args;
int error;
bsd_args.shmid = args->arg1;
bsd_args.shmaddr = args->ptr;
bsd_args.shmflg = args->arg2;
if ((error = shmat(p, &bsd_args, retval)))
return error;
if ((error = copyout(retval, (caddr_t)args->arg3, sizeof(int))))
return error;
retval[0] = 0;
return 0;
}
int
linux_shmdt(struct proc *p, struct linux_ipc_args *args, int *retval)
{
struct shmdt_args {
void *shmaddr;
} bsd_args;
bsd_args.shmaddr = args->ptr;
return shmdt(p, &bsd_args, retval);
}
int
linux_shmget(struct proc *p, struct linux_ipc_args *args, int *retval)
{
struct shmget_args {
key_t key;
int size;
int shmflg;
} bsd_args;
bsd_args.key = args->arg1;
bsd_args.size = args->arg2;
bsd_args.shmflg = args->arg3;
return shmget(p, &bsd_args, retval);
}
int
linux_shmctl(struct proc *p, struct linux_ipc_args *args, int *retval)
{
struct shmid_ds bsd_shmid;
struct linux_shmid_ds linux_shmid;
struct shmctl_args {
int shmid;
int cmd;
struct shmid_ds *buf;
} bsd_args;
int error;
switch (args->arg2) {
case LINUX_IPC_STAT:
bsd_args.shmid = args->arg1;
bsd_args.cmd = IPC_STAT;
bsd_args.buf = (struct shmid_ds*)ua_alloc_init(sizeof(struct shmid_ds));
if ((error = shmctl(p, &bsd_args, retval)))
return error;
if ((error = copyin((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
sizeof(struct shmid_ds))))
return error;
bsd_to_linux_shmid_ds(&bsd_shmid, &linux_shmid);
return copyout((caddr_t)&linux_shmid, args->ptr, sizeof(linux_shmid));
case LINUX_IPC_SET:
if ((error = copyin(args->ptr, (caddr_t)&linux_shmid,
sizeof(linux_shmid))))
return error;
linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid);
bsd_args.buf = (struct shmid_ds*)ua_alloc_init(sizeof(struct shmid_ds));
if ((error = copyout((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
sizeof(struct shmid_ds))))
return error;
bsd_args.shmid = args->arg1;
bsd_args.cmd = IPC_SET;
return shmctl(p, &bsd_args, retval);
case LINUX_IPC_RMID:
bsd_args.shmid = args->arg1;
bsd_args.cmd = IPC_RMID;
if ((error = copyin(args->ptr, (caddr_t)&linux_shmid,
sizeof(linux_shmid))))
return error;
linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid);
bsd_args.buf = (struct shmid_ds*)ua_alloc_init(sizeof(struct shmid_ds));
if ((error = copyout((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
sizeof(struct shmid_ds))))
return error;
return shmctl(p, &bsd_args, retval);
case LINUX_IPC_INFO:
case LINUX_SHM_STAT:
case LINUX_SHM_INFO:
case LINUX_SHM_LOCK:
case LINUX_SHM_UNLOCK:
default:
uprintf("LINUX: 'ipc' typ=%d not implemented\n", args->what);
return EINVAL;
}
}
int
linux_ipc(struct proc *p, struct linux_ipc_args *args, int *retval)
{
switch (args->what) {
case LINUX_SEMOP:
return linux_semop(p, args, retval);
case LINUX_SEMGET:
return linux_semget(p, args, retval);
case LINUX_SEMCTL:
return linux_semctl(p, args, retval);
case LINUX_MSGSND:
return linux_msgsnd(p, args, retval);
case LINUX_MSGRCV:
return linux_msgrcv(p, args, retval);
case LINUX_MSGGET:
return linux_msgget(p, args, retval);
case LINUX_MSGCTL:
return linux_msgctl(p, args, retval);
case LINUX_SHMAT:
return linux_shmat(p, args, retval);
case LINUX_SHMDT:
return linux_shmdt(p, args, retval);
case LINUX_SHMGET:
return linux_shmget(p, args, retval);
case LINUX_SHMCTL:
return linux_shmctl(p, args, retval);
default:
uprintf("LINUX: 'ipc' typ=%d not implemented\n", args->what);
return ENOSYS;
}
}

View File

@ -0,0 +1,660 @@
/*-
* Copyright (c) 1994-1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux_misc.c,v 1.4 1995/06/08 13:50:52 sos Exp $
*/
#include <i386/linux/linux.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/exec.h>
#include <sys/mman.h>
#include <sys/proc.h>
#include <sys/dirent.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/ioctl.h>
#include <sys/imgact_aout.h>
#include <sys/mount.h>
#include <sys/namei.h>
#include <sys/resource.h>
#include <sys/resourcevar.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/utsname.h>
#include <sys/vnode.h>
#include <sys/wait.h>
#include <machine/cpu.h>
#include <machine/psl.h>
#include <machine/reg.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
struct linux_alarm_args {
unsigned int secs;
};
int
linux_alarm(struct proc *p, struct linux_alarm_args *args, int *retval)
{
extern struct timeval time;
struct itimerval it, old_it;
int s;
#ifdef DEBUG
printf("Linux-emul(%d): alarm(%d)\n", p->p_pid, args->secs);
#endif
it.it_value.tv_sec = (long)args->secs;
it.it_value.tv_usec = 0;
it.it_interval.tv_sec = 0;
it.it_interval.tv_usec = 0;
s = splclock();
old_it = p->p_realtimer;
if (timerisset(&old_it.it_value))
if (timercmp(&old_it.it_value, &time, <))
timerclear(&old_it.it_value);
else
timevalsub(&old_it.it_value, &time);
splx(s);
if (itimerfix(&it.it_value) || itimerfix(&it.it_interval))
return EINVAL;
s = splclock();
untimeout(realitexpire, (caddr_t)p);
if (timerisset(&it.it_value)) {
timevaladd(&it.it_value, &time);
timeout(realitexpire, (caddr_t)p, hzto(&it.it_value));
}
p->p_realtimer = it;
splx(s);
if (old_it.it_value.tv_usec)
old_it.it_value.tv_sec++;
*retval = old_it.it_value.tv_sec;
return 0;
}
struct linux_brk_args {
linux_caddr_t dsend;
};
int
linux_brk(struct proc *p, struct linux_brk_args *args, int *retval)
{
#if 0
struct vmspace *vm = p->p_vmspace;
vm_offset_t new, old;
int error;
extern int swap_pager_full;
if ((vm_offset_t)args->dsend < (vm_offset_t)vm->vm_daddr)
return EINVAL;
if (((caddr_t)args->dsend - (caddr_t)vm->vm_daddr)
> p->p_rlimit[RLIMIT_DATA].rlim_cur)
return ENOMEM;
old = round_page((vm_offset_t)vm->vm_daddr) + ctob(vm->vm_dsize);
new = round_page((vm_offset_t)args->dsend);
*retval = old;
if ((new-old) > 0) {
if (swap_pager_full)
return ENOMEM;
error = vm_map_find(&vm->vm_map, NULL, 0, &old, (new-old), FALSE);
if (error)
return error;
vm->vm_dsize += btoc((new-old));
*retval = (int)(vm->vm_daddr + ctob(vm->vm_dsize));
}
return 0;
#else
struct vmspace *vm = p->p_vmspace;
vm_offset_t new, old;
struct obreak_args {
vm_offset_t newsize;
} tmp;
#ifdef DEBUG
printf("Linux-emul(%d): brk(%08x)\n", p->p_pid, args->dsend);
#endif
old = (vm_offset_t)vm->vm_daddr + ctob(vm->vm_dsize);
new = (vm_offset_t)args->dsend;
tmp.newsize = new;
if (((caddr_t)new > vm->vm_daddr) && !obreak(p, &tmp, retval))
retval[0] = (int)new;
else
retval[0] = (int)old;
return 0;
#endif
}
struct linux_uselib_args {
char *library;
};
int
linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval)
{
struct nameidata ni;
struct vnode *vnodep;
struct exec *a_out = 0;
struct vattr attr;
unsigned long vmaddr, virtual_offset, file_offset;
unsigned long buffer, bss_size;
char *ptr;
char path[MAXPATHLEN];
const char *prefix = "/compat/linux";
size_t sz, len;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): uselib(%s)\n", p->p_pid, args->library);
#endif
for (ptr = path; (*ptr = *prefix) != '\0'; ptr++, prefix++) ;
sz = MAXPATHLEN - (ptr - path);
if (error = copyinstr(args->library, ptr, sz, &len))
return error;
if (*ptr != '/')
return EINVAL;
#ifdef DEBUG
printf("Linux-emul(%d): uselib(%s)\n", p->p_pid, path);
#endif
NDINIT(&ni, LOOKUP, FOLLOW, UIO_SYSSPACE, path, p);
if (error = namei(&ni))
return error;
vnodep = ni.ni_vp;
if (vnodep == NULL)
return ENOEXEC;
if (vnodep->v_writecount)
return ETXTBSY;
if (error = VOP_GETATTR(vnodep, &attr, p->p_ucred, p))
return error;
if ((vnodep->v_mount->mnt_flag & MNT_NOEXEC)
|| ((attr.va_mode & 0111) == 0)
|| (attr.va_type != VREG))
return ENOEXEC;
if (attr.va_size == 0)
return ENOEXEC;
if (error = VOP_ACCESS(vnodep, VEXEC, p->p_ucred, p))
return error;
if (error = VOP_OPEN(vnodep, FREAD, p->p_ucred, p))
return error;
error = vm_mmap(kernel_map, (vm_offset_t *)&a_out, 1024,
VM_PROT_READ, VM_PROT_READ, 0, (caddr_t)vnodep, 0);
if (error)
return (error);
/*
* Is it a Linux binary ?
*/
if (((a_out->a_magic >> 16) & 0xff) != 0x64)
return -1;
/*
* Set file/virtual offset based on a.out variant.
*/
switch ((int)(a_out->a_magic & 0xffff)) {
case 0413: /* ZMAGIC */
virtual_offset = 0;
file_offset = 1024;
break;
case 0314: /* QMAGIC */
virtual_offset = 4096;
file_offset = 0;
break;
default:
return (-1);
}
vnodep->v_flag |= VTEXT;
bss_size = round_page(a_out->a_bss);
/*
* Check if file_offset page aligned,.
* Currently we cannot handle misalinged file offsets,
* and so we read in the entire image (what a waste).
*/
if (file_offset & PGOFSET) {
#ifdef DEBUG
printf("uselib: Non page aligned binary %d\n", file_offset);
#endif
/*
* Map text+data read/write/execute
*/
vmaddr = virtual_offset + round_page(a_out->a_entry);
error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr,
round_page(a_out->a_text + a_out->a_data), FALSE);
if (error)
return error;
error = vm_mmap(kernel_map, &buffer,
round_page(a_out->a_text + a_out->a_data + file_offset),
VM_PROT_READ, VM_PROT_READ, MAP_FILE,
(caddr_t)vnodep, trunc_page(file_offset));
if (error)
return error;
error = copyout((caddr_t)(buffer + file_offset), (caddr_t)vmaddr,
a_out->a_text + a_out->a_data);
if (error)
return error;
vm_map_remove(kernel_map, trunc_page(vmaddr),
round_page(a_out->a_text + a_out->a_data + file_offset));
error = vm_map_protect(&p->p_vmspace->vm_map, vmaddr,
round_page(a_out->a_text + a_out->a_data),
VM_PROT_ALL, TRUE);
if (error)
return error;
}
else {
#ifdef DEBUG
printf("uselib: Page aligned binary %d\n", file_offset);
#endif
vmaddr = virtual_offset + round_page(a_out->a_entry);
error = vm_mmap(&p->p_vmspace->vm_map, &vmaddr,
a_out->a_text + a_out->a_data,
VM_PROT_ALL, VM_PROT_ALL, MAP_PRIVATE | MAP_FIXED,
(caddr_t)vnodep, file_offset);
if (error)
return (error);
}
#ifdef DEBUG
printf("mem=%08x = %08x %08x\n", vmaddr, ((int*)vmaddr)[0], ((int*)vmaddr)[1]);
#endif
if (bss_size != 0) {
vmaddr = virtual_offset + round_page(a_out->a_entry) +
round_page(a_out->a_text + a_out->a_data);
error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr,
bss_size, FALSE);
if (error)
return error;
error = vm_map_protect(&p->p_vmspace->vm_map, vmaddr, bss_size,
VM_PROT_ALL, TRUE);
if (error)
return error;
}
return 0;
}
struct linux_select_args {
void *ptr;
};
int
linux_select(struct proc *p, struct linux_select_args *args, int *retval)
{
struct {
int nfds;
fd_set *readfds;
fd_set *writefds;
fd_set *exceptfds;
struct timeval *timeout;
} linux_args;
struct {
unsigned int nd;
fd_set *in;
fd_set *ou;
fd_set *ex;
struct timeval *tv;
} bsd_args;
int error;
if ((error = copyin((caddr_t)args->ptr, (caddr_t)&linux_args,
sizeof(linux_args))))
return error;
#ifdef DEBUG
printf("Linux-emul(%d): select(%d, %d, %d, %d, %d)\n",
p->p_pid, linux_args.nfds, linux_args.readfds,
linux_args.writefds, linux_args.exceptfds,
linux_args.timeout);
#endif
bsd_args.nd = linux_args.nfds;
bsd_args.in = linux_args.readfds;
bsd_args.ou = linux_args.writefds;
bsd_args.ex = linux_args.exceptfds;
bsd_args.tv = linux_args.timeout;
return select(p, &bsd_args, retval);
}
struct linux_getpgid_args {
int pid;
};
int
linux_getpgid(struct proc *p, struct linux_getpgid_args *args, int *retval)
{
struct proc *curproc;
#ifdef DEBUG
printf("Linux-emul(%d): getpgid(%d)\n", p->p_pid, args->pid);
#endif
if (args->pid != p->p_pid) {
if (!(curproc = pfind(args->pid)))
return ESRCH;
}
else
curproc = p;
*retval = curproc->p_pgid;
return 0;
}
int
linux_fork(struct proc *p, void *args, int *retval)
{
int error;
#ifdef DEBUG
printf("Linux-emul(%d): fork()\n", p->p_pid);
#endif
if (error = fork(p, args, retval))
return error;
if (retval[1] == 1)
retval[0] = 0;
return 0;
}
struct linux_mmap_args {
void *ptr;
};
int
linux_mmap(struct proc *p, struct linux_mmap_args *args, int *retval)
{
struct {
linux_caddr_t addr;
int len;
int prot;
int flags;
int fd;
int pos;
} linux_args;
struct {
caddr_t addr;
size_t len;
int prot;
int flags;
int fd;
long pad;
off_t pos;
} bsd_args;
int error;
if ((error = copyin((caddr_t)args->ptr, (caddr_t)&linux_args,
sizeof(linux_args))))
return error;
#ifdef DEBUG
printf("Linux-emul(%d): mmap(%08x, %d, %d, %08x, %d, %d)\n",
p->p_pid, linux_args.addr, linux_args.len, linux_args.prot,
linux_args.flags, linux_args.fd, linux_args.pos);
#endif
bsd_args.flags = 0;
if (linux_args.flags & LINUX_MAP_SHARED)
bsd_args.flags |= MAP_SHARED;
if (linux_args.flags & LINUX_MAP_PRIVATE)
bsd_args.flags |= MAP_PRIVATE;
if (linux_args.flags & LINUX_MAP_FIXED)
bsd_args.flags |= MAP_FIXED;
if (linux_args.flags & LINUX_MAP_ANON)
bsd_args.flags |= MAP_ANON;
bsd_args.addr = linux_args.addr;
bsd_args.len = linux_args.len;
bsd_args.prot = linux_args.prot;
bsd_args.fd = linux_args.fd;
bsd_args.pos = linux_args.pos;
bsd_args.pad = 0;
return mmap(p, &bsd_args, retval);
}
struct linux_pipe_args {
int *pipefds;
};
int
linux_pipe(struct proc *p, struct linux_pipe_args *args, int *retval)
{
int error;
#ifdef DEBUG
printf("Linux-emul(%d): pipe(*)\n", p->p_pid);
#endif
if (error = pipe(p, 0, retval))
return error;
if (error = copyout(retval, args->pipefds, 2*sizeof(int)))
return error;
*retval = 0;
return 0;
}
struct linux_time_args {
linux_time_t *tm;
};
int
linux_time(struct proc *p, struct linux_time_args *args, int *retval)
{
struct timeval tv;
linux_time_t tm;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): time(*)\n", p->p_pid);
#endif
microtime(&tv);
tm = tv.tv_sec;
if (error = copyout(&tm, args->tm, sizeof(linux_time_t)))
return error;
*retval = tv.tv_sec;
return 0;
}
struct linux_tms {
long tms_utime;
long tms_stime;
long tms_cutime;
long tms_cstime;
};
struct linux_tms_args {
char *buf;
};
int
linux_times(struct proc *p, struct linux_tms_args *args, int *retval)
{
extern int hz;
struct timeval tv;
struct linux_tms tms;
#ifdef DEBUG
printf("Linux-emul(%d): times(*)\n", p->p_pid);
#endif
tms.tms_utime = p->p_uticks;
tms.tms_stime = p->p_sticks;
tms.tms_cutime = p->p_stats->p_cru.ru_utime.tv_sec * hz +
((p->p_stats->p_cru.ru_utime.tv_usec * hz)/1000000);
tms.tms_cstime = p->p_stats->p_cru.ru_stime.tv_sec * hz +
((p->p_stats->p_cru.ru_stime.tv_usec * hz)/1000000);
microtime(&tv);
*retval = tv.tv_sec * hz + (tv.tv_usec * hz)/1000000;
return (copyout((caddr_t)&tms, (caddr_t)args->buf,
sizeof(struct linux_tms)));
}
struct linux_newuname_t {
char sysname[65];
char nodename[65];
char release[65];
char version[65];
char machine[65];
char domainname[65];
};
struct linux_newuname_args {
char *buf;
};
int
linux_newuname(struct proc *p, struct linux_newuname_args *args, int *retval)
{
struct linux_newuname_t linux_newuname;
extern char ostype[], osrelease[], machine[];
extern char hostname[], domainname[];
#ifdef DEBUG
printf("Linux-emul(%d): newuname(*)\n", p->p_pid);
#endif
bzero(&linux_newuname, sizeof(struct linux_newuname_args));
strncpy(linux_newuname.sysname, ostype, 64);
strncpy(linux_newuname.nodename, hostname, 64);
strncpy(linux_newuname.release, osrelease, 64);
strncpy(linux_newuname.version, version, 64);
strncpy(linux_newuname.machine, machine, 64);
strncpy(linux_newuname.domainname, domainname, 64);
return (copyout((caddr_t)&linux_newuname, (caddr_t)args->buf,
sizeof(struct linux_newuname_t)));
}
struct linux_utime_args {
char *fname;
linux_time_t *timeptr;
};
int
linux_utime(struct proc *p, struct linux_utime_args *args, int *retval)
{
struct bsd_utimes_args {
char *fname;
struct timeval *tptr;
} bsdutimes;
struct timeval tv;
#ifdef DEBUG
printf("Linux-emul(%d): utime(%s, *)\n", p->p_pid, args->fname);
#endif
tv.tv_sec = (long)args->timeptr;
tv.tv_usec = 0;
bsdutimes.tptr = &tv;
bsdutimes.fname = args->fname;
return utimes(p, &bsdutimes, retval);
}
struct linux_waitpid_args {
int pid;
int *status;
int options;
};
int
linux_waitpid(struct proc *p, struct linux_waitpid_args *args, int *retval)
{
struct wait4_args {
int pid;
int *status;
int options;
struct rusage *rusage;
int compat;
} tmp;
int error, tmpstat;
#ifdef DEBUG
printf("Linux-emul(%d): waitpid(%d, *, %d)\n",
p->p_pid, args->pid, args->options);
#endif
tmp.pid = args->pid;
tmp.status = args->status;
tmp.options = args->options;
tmp.rusage = NULL;
tmp.compat = 0;
if (error = wait4(p, &tmp, retval))
return error;
if (error = copyin(args->status, &tmpstat, sizeof(int)))
return error;
if (WIFSIGNALED(tmpstat))
tmpstat = (tmpstat & 0xffffff80) |
bsd_to_linux_signal[WTERMSIG(tmpstat)];
else if (WIFSTOPPED(tmpstat))
tmpstat = (tmpstat & 0xffff00ff) |
(bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8);
return copyout(&tmpstat, args->status, sizeof(int));
}
struct linux_wait4_args {
int pid;
int *status;
int options;
struct rusage *rusage;
};
int
linux_wait4(struct proc *p, struct linux_wait4_args *args, int *retval)
{
struct wait4_args {
int pid;
int *status;
int options;
struct rusage *rusage;
int compat;
} tmp;
int error, tmpstat;
#ifdef DEBUG
printf("Linux-emul(%d): wait4(%d, *, %d, *)\n",
p->p_pid, args->pid, args->options);
#endif
tmp.pid = args->pid;
tmp.status = args->status;
tmp.options = args->options;
tmp.rusage = args->rusage;
tmp.compat = 0;
if (error = wait4(p, &tmp, retval))
return error;
if (error = copyin(args->status, &tmpstat, sizeof(int)))
return error;
if (WIFSIGNALED(tmpstat))
tmpstat = (tmpstat & 0xffffff80) |
bsd_to_linux_signal[WTERMSIG(tmpstat)];
else if (WIFSTOPPED(tmpstat))
tmpstat = (tmpstat & 0xffff00ff) |
(bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8);
return copyout(&tmpstat, args->status, sizeof(int));
}

View File

@ -0,0 +1,259 @@
/*-
* Copyright (c) 1994-1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux_signal.c,v 1.2 1995/06/07 21:27:57 sos Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/exec.h>
#include <sys/signal.h>
#include <sys/signalvar.h>
#include <vm/vm.h>
#include <i386/linux/linux.h>
#define DONTMASK (sigmask(SIGKILL)|sigmask(SIGSTOP)|sigmask(SIGCHLD))
static sigset_t
linux_to_bsd_sigmask(linux_sigset_t mask) {
int i;
sigset_t new = 0;
for (i = 1; i <= LINUX_NSIG; i++)
if (mask & (1 << i-1))
new |= (1 << (linux_to_bsd_signal[i]-1));
return new;
}
static linux_sigset_t
bsd_to_linux_sigmask(sigset_t mask) {
int i;
sigset_t new = 0;
for (i = 1; i <= NSIG; i++)
if (mask & (1 << i-1))
new |= (1 << (bsd_to_linux_signal[i]-1));
return new;
}
struct linux_sigaction_args {
int sig;
linux_sigaction_t *nsa;
linux_sigaction_t *osa;
};
int
linux_sigaction(struct proc *p, struct linux_sigaction_args *args, int *retval)
{
linux_sigaction_t linux_sa;
struct sigaction *nsa = NULL, *osa = NULL, bsd_sa;
struct sigaction_args {
int sig;
struct sigaction *nsa;
struct sigaction *osa;
} sa;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): sigaction(%d, *, *)\n", p->p_pid, args->sig);
#endif
if (args->osa)
osa = (struct sigaction *)ua_alloc_init(sizeof(struct sigaction));
if (args->nsa) {
nsa = (struct sigaction *)ua_alloc(sizeof(struct sigaction));
if (error = copyin(args->nsa, &linux_sa, sizeof(linux_sigaction_t)))
return error;
bsd_sa.sa_mask = linux_to_bsd_sigmask(linux_sa.sa_mask);
bsd_sa.sa_handler = linux_sa.sa_handler;
bsd_sa.sa_flags = 0;
if (linux_sa.sa_flags & LINUX_SA_NOCLDSTOP)
bsd_sa.sa_flags |= SA_NOCLDSTOP;
if (linux_sa.sa_flags & LINUX_SA_ONSTACK)
bsd_sa.sa_flags |= SA_ONSTACK;
if (linux_sa.sa_flags & LINUX_SA_RESTART)
bsd_sa.sa_flags |= SA_RESTART;
if (error = copyout(&bsd_sa, nsa, sizeof(struct sigaction)))
return error;
}
sa.sig = linux_to_bsd_signal[args->sig];
sa.nsa = nsa;
sa.osa = osa;
if ((error = sigaction(p, &sa, retval)))
return error;
if (args->osa) {
if (error = copyin(osa, &bsd_sa, sizeof(struct sigaction)))
return error;
linux_sa.sa_handler = bsd_sa.sa_handler;
linux_sa.sa_restorer = NULL;
linux_sa.sa_mask = bsd_to_linux_sigmask(bsd_sa.sa_mask);
linux_sa.sa_flags = 0;
if (bsd_sa.sa_flags & SA_NOCLDSTOP)
linux_sa.sa_flags |= LINUX_SA_NOCLDSTOP;
if (bsd_sa.sa_flags & SA_ONSTACK)
linux_sa.sa_flags |= LINUX_SA_ONSTACK;
if (bsd_sa.sa_flags & SA_RESTART)
linux_sa.sa_flags |= LINUX_SA_RESTART;
if (error = copyout(&linux_sa, args->osa, sizeof(linux_sigaction_t)))
return error;
}
return 0;
}
struct linux_sigprocmask_args {
int how;
linux_sigset_t *mask;
linux_sigset_t *omask;
};
int
linux_sigprocmask(struct proc *p, struct linux_sigprocmask_args *args,
int *retval)
{
int error, s;
sigset_t mask;
sigset_t omask;
#ifdef DEBUG
printf("Linux-emul(%d): sigprocmask(%d, *, *)\n", p->p_pid, args->how);
#endif
if (args->omask != NULL) {
omask = bsd_to_linux_sigmask(p->p_sigmask);
if (error = copyout(&omask, args->omask, sizeof(sigset_t)))
return error;
}
if (!(args->mask))
return 0;
if (error = copyin(args->mask, &mask, sizeof(linux_sigset_t)))
return error;
mask = linux_to_bsd_sigmask(mask);
s = splhigh();
switch (args->how) {
case LINUX_SIG_BLOCK:
p->p_sigmask |= (mask & ~DONTMASK);
break;
case LINUX_SIG_UNBLOCK:
p->p_sigmask &= ~mask;
break;
case LINUX_SIG_SETMASK:
p->p_sigmask = (mask & ~DONTMASK);
break;
default:
error = EINVAL;
break;
}
splx(s);
return error;
}
int
linux_siggetmask(struct proc *p, void *args, int *retval)
{
#ifdef DEBUG
printf("Linux-emul(%d): siggetmask()\n", p->p_pid);
#endif
*retval = bsd_to_linux_sigmask(p->p_sigmask);
return 0;
}
struct linux_sigsetmask_args {
linux_sigset_t mask;
};
int
linux_sigsetmask(struct proc *p, struct linux_sigsetmask_args *args,int *retval)
{
int s;
#ifdef DEBUG
printf("Linux-emul(%d): sigsetmask(%08x)\n", p->p_pid, args->mask);
#endif
s = splhigh();
p->p_sigmask = (linux_to_bsd_sigmask(args->mask) & ~DONTMASK);
splx(s);
*retval = bsd_to_linux_sigmask(p->p_sigmask);
return 0;
}
struct linux_sigpending_args {
linux_sigset_t *mask;
};
int
linux_sigpending(struct proc *p, struct linux_sigpending_args *args,int *retval)
{
linux_sigset_t linux_sig;
#ifdef DEBUG
printf("Linux-emul(%d): sigpending(*)\n", p->p_pid);
#endif
linux_sig = bsd_to_linux_sigmask(p->p_siglist & p->p_sigmask);
return copyout(&linux_sig, args->mask, sizeof(linux_sig));
}
struct linux_sigsuspend_args {
linux_sigset_t mask;
};
int
linux_sigsuspend(struct proc *p, struct linux_sigsuspend_args *args,int *retval)
{
sigset_t tmp;
#ifdef DEBUG
printf("Linux-emul(%d): sigsuspend(%08x)\n", p->p_pid, args->mask);
#endif
tmp = linux_to_bsd_sigmask(args->mask);
return sigsuspend(p, &tmp , retval);
}
struct linux_kill_args {
int pid;
int signum;
};
int
linux_kill(struct proc *p, struct linux_kill_args *args, int *retval)
{
struct {
int pid;
int signum;
} tmp;
#ifdef DEBUG
printf("Linux-emul(%d): kill(%d, %d)\n",
p->p_pid, args->pid, args->signum);
#endif
tmp.pid = args->pid;
tmp.signum = linux_to_bsd_signal[args->signum];
return kill(p, &tmp, retval);
}

View File

@ -0,0 +1,595 @@
/*-
* Copyright (c) 1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux_socket.c,v 1.2 1995/06/07 21:27:57 sos Exp $
*/
#include <i386/linux/linux.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <netinet/in.h>
static int
linux_to_bsd_domain(int domain)
{
switch (domain) {
case LINUX_AF_UNSPEC:
return AF_UNSPEC;
case LINUX_AF_UNIX:
return AF_LOCAL;
case LINUX_AF_INET:
return AF_INET;
case LINUX_AF_AX25:
return AF_CCITT;
case LINUX_AF_IPX:
return AF_IPX;
case LINUX_AF_APPLETALK:
return AF_APPLETALK;
default:
return -1;
}
}
static int
linux_to_bsd_sockopt_level(int level)
{
switch (level) {
case LINUX_SOL_SOCKET:
return SOL_SOCKET;
default:
return level;
}
}
static int linux_to_bsd_ip_sockopt(int opt)
{
switch (opt) {
case LINUX_IP_TOS:
return IP_TOS;
case LINUX_IP_TTL:
return IP_TTL;
default:
return -1;
}
}
static int
linux_to_bsd_so_sockopt(int opt)
{
switch (opt) {
case LINUX_SO_DEBUG:
return SO_DEBUG;
case LINUX_SO_REUSEADDR:
return SO_REUSEADDR;
case LINUX_SO_TYPE:
return SO_TYPE;
case LINUX_SO_ERROR:
return SO_ERROR;
case LINUX_SO_DONTROUTE:
return SO_DONTROUTE;
case LINUX_SO_BROADCAST:
return SO_BROADCAST;
case LINUX_SO_SNDBUF:
return SO_SNDBUF;
case LINUX_SO_RCVBUF:
return SO_RCVBUF;
case LINUX_SO_KEEPALIVE:
return SO_KEEPALIVE;
case LINUX_SO_OOBINLINE:
return SO_OOBINLINE;
case LINUX_SO_LINGER:
return SO_LINGER;
case LINUX_SO_PRIORITY:
case LINUX_SO_NO_CHECK:
default:
return -1;
}
}
struct linux_socket_args {
int domain;
int type;
int protocol;
};
static int
linux_socket(struct proc *p, struct linux_socket_args *args, int *retval)
{
struct linux_socket_args linux_args;
struct {
int domain;
int type;
int protocol;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.protocol = linux_args.protocol;
bsd_args.type = linux_args.type;
bsd_args.domain = linux_to_bsd_domain(linux_args.domain);
if (bsd_args.domain == -1)
return EINVAL;
return socket(p, &bsd_args, retval);
}
struct linux_bind_args {
int s;
struct sockaddr *name;
int namelen;
};
static int
linux_bind(struct proc *p, struct linux_bind_args *args, int *retval)
{
struct linux_bind_args linux_args;
struct {
int s;
caddr_t name;
int namelen;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.name = (caddr_t)linux_args.name;
bsd_args.namelen = linux_args.namelen;
return bind(p, &bsd_args, retval);
}
struct linux_connect_args {
int s;
struct sockaddr * name;
int namelen;
};
static int
linux_connect(struct proc *p, struct linux_connect_args *args, int *retval)
{
struct linux_connect_args linux_args;
struct {
int s;
caddr_t name;
int namelen;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.name = (caddr_t)linux_args.name;
bsd_args.namelen = linux_args.namelen;
return connect(p, &bsd_args, retval);
}
struct linux_listen_args {
int s;
int backlog;
};
static int
linux_listen(struct proc *p, struct linux_listen_args *args, int *retval)
{
struct linux_listen_args linux_args;
struct {
int s;
int backlog;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.backlog = linux_args.backlog;
return listen(p, &bsd_args, retval);
}
struct linux_accept_args {
int s;
struct sockaddr *addr;
int *namelen;
};
static int
linux_accept(struct proc *p, struct linux_accept_args *args, int *retval)
{
struct linux_accept_args linux_args;
struct accept_args {
int s;
caddr_t name;
int *anamelen;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.name = (caddr_t)linux_args.addr;
bsd_args.anamelen = linux_args.namelen;
return oaccept(p, &bsd_args, retval);
}
struct linux_getsockname_args {
int s;
struct sockaddr *addr;
int *namelen;
};
static int
linux_getsockname(struct proc *p, struct linux_getsockname_args *args, int *retval)
{
struct linux_getsockname_args linux_args;
struct {
int fdes;
caddr_t asa;
int *alen;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.fdes = linux_args.s;
bsd_args.asa = (caddr_t) linux_args.addr;
bsd_args.alen = linux_args.namelen;
return ogetsockname(p, &bsd_args, retval);
}
struct linux_getpeername_args {
int s;
struct sockaddr *addr;
int *namelen;
};
static int
linux_getpeername(struct proc *p, struct linux_getpeername_args *args, int *retval)
{
struct linux_getpeername_args linux_args;
struct getpeername_args {
int fdes;
caddr_t asa;
int *alen;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.fdes = linux_args.s;
bsd_args.asa = (caddr_t) linux_args.addr;
bsd_args.alen = linux_args.namelen;
return ogetpeername(p, &bsd_args, retval);
}
struct linux_socketpair_args {
int domain;
int type;
int protocol;
int *rsv;
};
static int
linux_socketpair(struct proc *p, struct linux_socketpair_args *args, int *retval)
{
struct linux_socketpair_args linux_args;
struct {
int domain;
int type;
int protocol;
int *rsv;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.domain = linux_to_bsd_domain(linux_args.domain);
if (bsd_args.domain == -1)
return EINVAL;
bsd_args.type = linux_args.type;
bsd_args.protocol = linux_args.protocol;
bsd_args.rsv = linux_args.rsv;
return socketpair(p, &bsd_args, retval);
}
struct linux_send_args {
int s;
void *msg;
int len;
int flags;
};
static int
linux_send(struct proc *p, struct linux_send_args *args, int *retval)
{
struct linux_send_args linux_args;
struct {
int s;
caddr_t buf;
int len;
int flags;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.buf = linux_args.msg;
bsd_args.len = linux_args.len;
bsd_args.flags = linux_args.flags;
return osend(p, &bsd_args, retval);
}
struct linux_recv_args {
int s;
void *msg;
int len;
int flags;
};
static int
linux_recv(struct proc *p, struct linux_recv_args *args, int *retval)
{
struct linux_recv_args linux_args;
struct {
int s;
caddr_t buf;
int len;
int flags;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.buf = linux_args.msg;
bsd_args.len = linux_args.len;
bsd_args.flags = linux_args.flags;
return orecv(p, &bsd_args, retval);
}
struct linux_sendto_args {
int s;
void *msg;
int len;
int flags;
caddr_t to;
int tolen;
};
static int
linux_sendto(struct proc *p, struct linux_sendto_args *args, int *retval)
{
struct linux_sendto_args linux_args;
struct {
int s;
caddr_t buf;
size_t len;
int flags;
caddr_t to;
int tolen;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.buf = linux_args.msg;
bsd_args.len = linux_args.len;
bsd_args.flags = linux_args.flags;
bsd_args.to = linux_args.to;
bsd_args.tolen = linux_args.tolen;
return sendto(p, &bsd_args, retval);
}
struct linux_recvfrom_args {
int s;
void *buf;
int len;
int flags;
caddr_t from;
int *fromlen;
};
static int
linux_recvfrom(struct proc *p, struct linux_recvfrom_args *args, int *retval)
{
struct linux_recvfrom_args linux_args;
struct {
int s;
caddr_t buf;
size_t len;
int flags;
caddr_t from;
int *fromlenaddr;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.buf = linux_args.buf;
bsd_args.len = linux_args.len;
bsd_args.flags = linux_args.flags;
bsd_args.from = linux_args.from;
bsd_args.fromlenaddr = linux_args.fromlen;
return orecvfrom(p, &bsd_args, retval);
}
struct linux_shutdown_args {
int s;
int how;
};
static int
linux_shutdown(struct proc *p, struct linux_shutdown_args *args, int *retval)
{
struct linux_shutdown_args linux_args;
struct {
int s;
int how;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.how = linux_args.how;
return shutdown(p, &bsd_args, retval);
}
struct linux_setsockopt_args {
int s;
int level;
int optname;
void *optval;
int optlen;
};
static int
linux_setsockopt(struct proc *p, struct linux_setsockopt_args *args, int *retval)
{
struct linux_setsockopt_args linux_args;
struct {
int s;
int level;
int name;
caddr_t val;
int valsize;
} bsd_args;
int error, name;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.level = linux_to_bsd_sockopt_level(linux_args.level);
switch (bsd_args.level) {
case SOL_SOCKET:
name = linux_to_bsd_so_sockopt(linux_args.optname);
break;
case IPPROTO_IP:
name = linux_to_bsd_ip_sockopt(linux_args.optname);
break;
default:
return EINVAL;
}
if (name == -1)
return EINVAL;
bsd_args.name = name;
bsd_args.val = linux_args.optval;
bsd_args.valsize = linux_args.optlen;
return setsockopt(p, &bsd_args, retval);
}
struct linux_getsockopt_args {
int s;
int level;
int optname;
void *optval;
int *optlen;
};
static int
linux_getsockopt(struct proc *p, struct linux_getsockopt_args *args, int *retval)
{
struct linux_getsockopt_args linux_args;
struct {
int s;
int level;
int name;
caddr_t val;
int *avalsize;
} bsd_args;
int error, name;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.level = linux_to_bsd_sockopt_level(linux_args.level);
switch (bsd_args.level) {
case SOL_SOCKET:
name = linux_to_bsd_so_sockopt(linux_args.optname);
break;
case IPPROTO_IP:
name = linux_to_bsd_ip_sockopt(linux_args.optname);
break;
default:
return EINVAL;
}
if (name == -1)
return EINVAL;
bsd_args.val = linux_args.optval;
bsd_args.avalsize = linux_args.optlen;
return getsockopt(p, &bsd_args, retval);
}
struct linux_socketcall_args {
int what;
void *args;
};
int
linux_socketcall(struct proc *p, struct linux_socketcall_args *args,int *retval)
{
switch (args->what) {
case LINUX_SOCKET:
return linux_socket(p, args->args, retval);
case LINUX_BIND:
return linux_bind(p, args->args, retval);
case LINUX_CONNECT:
return linux_connect(p, args->args, retval);
case LINUX_LISTEN:
return linux_listen(p, args->args, retval);
case LINUX_ACCEPT:
return linux_accept(p, args->args, retval);
case LINUX_GETSOCKNAME:
return linux_getsockname(p, args->args, retval);
case LINUX_GETPEERNAME:
return linux_getpeername(p, args->args, retval);
case LINUX_SOCKETPAIR:
return linux_socketpair(p, args->args, retval);
case LINUX_SEND:
return linux_send(p, args->args, retval);
case LINUX_RECV:
return linux_recv(p, args->args, retval);
case LINUX_SENDTO:
return linux_sendto(p, args->args, retval);
case LINUX_RECVFROM:
return linux_recvfrom(p, args->args, retval);
case LINUX_SHUTDOWN:
return linux_shutdown(p, args->args, retval);
case LINUX_SETSOCKOPT:
return linux_setsockopt(p, args->args, retval);
case LINUX_GETSOCKOPT:
return linux_getsockopt(p, args->args, retval);
default:
uprintf("LINUX: 'socket' typ=%d not implemented\n", args->what);
return ENOSYS;
}
}

View File

@ -0,0 +1,273 @@
/*-
* Copyright (c) 1994-1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux_stats.c,v 1.3 1995/06/08 13:50:52 sos Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/dirent.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/proc.h>
#include <sys/mount.h>
#include <sys/namei.h>
#include <sys/stat.h>
#include <sys/vnode.h>
#include <machine/cpu.h>
#include <machine/psl.h>
#include <machine/reg.h>
#include <i386/linux/linux.h>
struct linux_newstat {
unsigned short stat_dev;
unsigned short __pad1;
unsigned long stat_ino;
unsigned short stat_mode;
unsigned short stat_nlink;
unsigned short stat_uid;
unsigned short stat_gid;
unsigned short stat_rdev;
unsigned short __pad2;
unsigned long stat_size;
unsigned long stat_blksize;
unsigned long stat_blocks;
unsigned long stat_atime;
unsigned long __unused1;
unsigned long stat_mtime;
unsigned long __unused2;
unsigned long stat_ctime;
unsigned long __unused3;
unsigned long __unused4;
unsigned long __unused5;
};
struct linux_newstat_args {
char *path;
struct linux_newstat *buf;
};
static int
newstat_copyout(struct stat *buf, void *ubuf)
{
struct linux_newstat tbuf;
tbuf.stat_dev = (buf->st_dev & 0xff) | ((buf->st_dev & 0xff00)<<10);
tbuf.stat_ino = buf->st_ino;
tbuf.stat_mode = buf->st_mode;
tbuf.stat_nlink = buf->st_nlink;
tbuf.stat_uid = buf->st_uid;
tbuf.stat_gid = buf->st_gid;
tbuf.stat_rdev = buf->st_rdev;
tbuf.stat_size = buf->st_size;
tbuf.stat_atime = buf->st_atime;
tbuf.stat_mtime = buf->st_mtime;
tbuf.stat_ctime = buf->st_ctime;
tbuf.stat_blksize = buf->st_blksize;
tbuf.stat_blocks = buf->st_blocks;
return copyout(&tbuf, ubuf, sizeof(tbuf));
}
int
linux_newstat(struct proc *p, struct linux_newstat_args *args, int *retval)
{
struct stat buf;
struct linux_newstat tbuf;
struct nameidata nd;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): newstat(%s, *)\n", p->p_pid, args->path);
#endif
NDINIT(&nd, LOOKUP, LOCKLEAF|FOLLOW, UIO_USERSPACE, args->path, p);
error = namei(&nd);
if (!error) {
error = vn_stat(nd.ni_vp, &buf, p);
vput(nd.ni_vp);
}
if (!error)
error = newstat_copyout(&buf, args->buf);
return error;
}
int
linux_newlstat(struct proc *p, struct linux_newstat_args *args, int *retval)
{
struct stat buf;
struct linux_newstat tbuf;
struct nameidata nd;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): newlstat(%s, *)\n", p->p_pid, args->path);
#endif
NDINIT(&nd, LOOKUP, LOCKLEAF|FOLLOW, UIO_USERSPACE, args->path, p);
error = namei(&nd);
if (!error) {
error = vn_stat(nd.ni_vp, &buf, p);
vput(nd.ni_vp);
}
if (!error)
error = newstat_copyout(&buf, args->buf);
return error;
}
struct linux_newfstat_args {
int fd;
struct linux_newstat *buf;
};
int
linux_newfstat(struct proc *p, struct linux_newfstat_args *args, int *retval)
{
struct linux_newstat tbuf;
struct filedesc *fdp = p->p_fd;
struct file *fp;
struct stat buf;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): newlstat(%d, *)\n", p->p_pid, args->fd);
#endif
if ((unsigned)args->fd >= fdp->fd_nfiles
|| (fp = fdp->fd_ofiles[args->fd]) == NULL)
return EBADF;
switch (fp->f_type) {
case DTYPE_VNODE:
error = vn_stat((struct vnode *)fp->f_data, &buf, p);
break;
case DTYPE_SOCKET:
error = soo_stat((struct socket *)fp->f_data, &buf);
break;
default:
panic("LINUX newfstat");
}
if (!error)
error = newstat_copyout(&buf, args->buf);
return error;
}
struct linux_statfs {
long ftype;
long fbsize;
long fblocks;
long fbfree;
long fbavail;
long ffiles;
long fffree;
linux_fsid_t ffsid;
long fnamelen;
long fspare[6];
};
struct linux_statfs_args {
char *path;
struct statfs *buf;
};
int
linux_statfs(struct proc *p, struct linux_statfs_args *args, int *retval)
{
struct mount *mp;
struct nameidata *ndp;
struct statfs *bsd_statfs;
struct nameidata nd;
struct linux_statfs linux_statfs;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): statfs(%s, *)\n", p->p_pid, args->path);
#endif
ndp = &nd;
ndp->ni_cnd.cn_nameiop = LOOKUP;
ndp->ni_cnd.cn_flags = FOLLOW;
ndp->ni_cnd.cn_proc = curproc;
ndp->ni_cnd.cn_cred = curproc->p_cred->pc_ucred;
ndp->ni_segflg = UIO_USERSPACE;
ndp->ni_dirp = args->path;
if (error = namei(ndp))
return error;
mp = ndp->ni_vp->v_mount;
bsd_statfs = &mp->mnt_stat;
vrele(ndp->ni_vp);
if (error = VFS_STATFS(mp, bsd_statfs, p))
return error;
bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
linux_statfs.ftype = bsd_statfs->f_type;
linux_statfs.fbsize = bsd_statfs->f_bsize;
linux_statfs.fblocks = bsd_statfs->f_blocks;
linux_statfs.fbfree = bsd_statfs->f_bfree;
linux_statfs.fbavail = bsd_statfs->f_bavail;
linux_statfs.fffree = bsd_statfs->f_ffree;
linux_statfs.ffiles = bsd_statfs->f_files;
linux_statfs.ffsid.val[0] = bsd_statfs->f_fsid.val[0];
linux_statfs.ffsid.val[1] = bsd_statfs->f_fsid.val[1];
linux_statfs.fnamelen = MAXNAMLEN;
return copyout((caddr_t)&linux_statfs, (caddr_t)args->buf,
sizeof(struct linux_statfs));
}
struct linux_fstatfs_args {
int fd;
struct statfs *buf;
};
int
linux_fstatfs(struct proc *p, struct linux_fstatfs_args *args, int *retval)
{
struct file *fp;
struct mount *mp;
struct statfs *bsd_statfs;
struct linux_statfs linux_statfs;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): fstatfs(%d, *)\n", p->p_pid, args->fd);
#endif
if (error = getvnode(p->p_fd, args->fd, &fp))
return error;
mp = ((struct vnode *)fp->f_data)->v_mount;
bsd_statfs = &mp->mnt_stat;
if (error = VFS_STATFS(mp, bsd_statfs, p))
return error;
bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
linux_statfs.ftype = bsd_statfs->f_type;
linux_statfs.fbsize = bsd_statfs->f_bsize;
linux_statfs.fblocks = bsd_statfs->f_blocks;
linux_statfs.fbfree = bsd_statfs->f_bfree;
linux_statfs.fbavail = bsd_statfs->f_bavail;
linux_statfs.fffree = bsd_statfs->f_ffree;
linux_statfs.ffiles = bsd_statfs->f_files;
linux_statfs.ffsid.val[0] = bsd_statfs->f_fsid.val[0];
linux_statfs.ffsid.val[1] = bsd_statfs->f_fsid.val[1];
linux_statfs.fnamelen = MAXNAMLEN;
return copyout((caddr_t)&linux_statfs, (caddr_t)args->buf,
sizeof(struct linux_statfs));
}

View File

@ -0,0 +1,235 @@
/*-
* Copyright (c) 1994-1995 Søren Schmidt
* All rights reserved.
*
* Based heavily on /sys/kern/imgact_aout.c which is:
* Copyright (c) 1993, David Greenman
*
* 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 withough 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.
*
* $Id: imgact_linux.c,v 1.2 1995/06/07 21:27:57 sos Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/resourcevar.h>
#include <sys/exec.h>
#include <sys/mman.h>
#include <sys/imgact.h>
#include <sys/imgact_aout.h>
#include <sys/kernel.h>
#include <sys/sysent.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
int
exec_linux_imgact(iparams)
struct image_params *iparams;
{
struct exec *a_out = (struct exec *) iparams->image_header;
struct vmspace *vmspace = iparams->proc->p_vmspace;
unsigned long vmaddr, virtual_offset, file_offset;
unsigned long buffer, bss_size;
int error;
extern struct sysentvec linux_sysvec;
if (((a_out->a_magic >> 16) & 0xff) != 0x64)
return -1;
/*
* Set file/virtual offset based on a.out variant.
*/
switch ((int)(a_out->a_magic & 0xffff)) {
case 0413:
virtual_offset = 0;
file_offset = 1024;
break;
case 0314:
virtual_offset = 4096;
file_offset = 0;
break;
default:
return (-1);
}
bss_size = round_page(a_out->a_bss);
/*
* Check various fields in header for validity/bounds.
*/
if (a_out->a_entry < virtual_offset ||
a_out->a_entry >= virtual_offset + a_out->a_text ||
a_out->a_text % NBPG || a_out->a_data % NBPG)
return (-1);
/* text + data can't exceed file size */
if (a_out->a_data + a_out->a_text > iparams->attr->va_size)
return (EFAULT);
/*
* text/data/bss must not exceed limits
*/
if (a_out->a_text > MAXTSIZ || a_out->a_data + bss_size > MAXDSIZ ||
a_out->a_data+bss_size > iparams->proc->p_rlimit[RLIMIT_DATA].rlim_cur)
return (ENOMEM);
/* copy in arguments and/or environment from old process */
error = exec_extract_strings(iparams);
if (error)
return (error);
/*
* Destroy old process VM and create a new one (with a new stack)
*/
exec_new_vmspace(iparams);
/*
* Check if file_offset page aligned,.
* Currently we cannot handle misalinged file offsets,
* and so we read in the entire image (what a waste).
*/
if (file_offset & PGOFSET) {
#ifdef DEBUG
printf("imgact: Non page aligned binary %d\n", file_offset);
#endif
/*
* Map text read/execute
*/
vmaddr = virtual_offset;
error = vm_map_find(&vmspace->vm_map, NULL, 0, &vmaddr,
round_page(a_out->a_text), FALSE);
if (error)
return error;
error = vm_mmap(kernel_map, &buffer,
round_page(a_out->a_text + file_offset),
VM_PROT_READ, VM_PROT_READ, MAP_FILE,
(caddr_t) iparams->vnodep, trunc_page(file_offset));
if (error)
return error;
error = copyout((caddr_t)(buffer + file_offset), (caddr_t)vmaddr,
a_out->a_text);
if (error)
return error;
vm_map_remove(kernel_map, trunc_page(vmaddr),
round_page(a_out->a_text + file_offset));
error = vm_map_protect(&vmspace->vm_map, vmaddr,
round_page(a_out->a_text),
VM_PROT_EXECUTE|VM_PROT_READ, TRUE);
if (error)
return error;
/*
* Map data read/write
*/
vmaddr = virtual_offset + a_out->a_text;
error = vm_map_find(&vmspace->vm_map, NULL, 0, &vmaddr,
round_page(a_out->a_data + bss_size), FALSE);
if (error)
return error;
error = vm_mmap(kernel_map, &buffer,
round_page(a_out->a_data + file_offset),
VM_PROT_READ, VM_PROT_READ, MAP_FILE,
(caddr_t) iparams->vnodep,
trunc_page(a_out->a_text + file_offset));
if (error)
return error;
error = copyout((caddr_t)(buffer + file_offset),
(caddr_t)vmaddr,
a_out->a_data);
if (error)
return error;
vm_map_remove(kernel_map, trunc_page(vmaddr),
round_page(a_out->a_data + file_offset));
error = vm_map_protect(&vmspace->vm_map, vmaddr,
round_page(a_out->a_data + bss_size),
VM_PROT_WRITE|VM_PROT_READ, TRUE);
if (error)
return error;
}
else {
#ifdef DEBUG
printf("imgact: Page aligned binary %d\n", file_offset);
#endif
/*
* Map text read/execute
*/
vmaddr = virtual_offset;
error = vm_mmap(&vmspace->vm_map, &vmaddr, a_out->a_text,
VM_PROT_READ | VM_PROT_EXECUTE,
VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_WRITE,
MAP_PRIVATE | MAP_FIXED,
(caddr_t)iparams->vnodep, file_offset);
if (error)
return (error);
/*
* Map data read/write
*/
vmaddr = virtual_offset + a_out->a_text;
error = vm_mmap(&vmspace->vm_map, &vmaddr, a_out->a_data,
VM_PROT_READ | VM_PROT_WRITE,
VM_PROT_ALL, MAP_PRIVATE | MAP_FIXED,
(caddr_t)iparams->vnodep, file_offset + a_out->a_text);
if (error)
return (error);
/*
* Allocate demand-zeroed area for uninitialized data
*/
if (bss_size != 0) {
vmaddr = virtual_offset + a_out->a_text + a_out->a_data;
error = vm_map_find(&vmspace->vm_map, NULL, 0, &vmaddr,
bss_size, FALSE);
if (error)
return (error);
}
}
/* Fill in process VM information */
vmspace->vm_tsize = round_page(a_out->a_text) >> PAGE_SHIFT;
vmspace->vm_dsize = round_page(a_out->a_data + bss_size) >> PAGE_SHIFT;
vmspace->vm_taddr = (caddr_t)virtual_offset;
vmspace->vm_daddr = (caddr_t)virtual_offset + a_out->a_text;
/* Fill in image_params */
iparams->interpreted = 0;
iparams->entry_addr = a_out->a_entry;
iparams->proc->p_sysent = &linux_sysvec;
return (0);
}
/*
* Tell kern_execve.c about it, with a little help from the linker.
* Since `const' objects end up in the text segment, TEXT_SET is the
* correct directive to use.
*/
const struct execsw linux_execsw = { exec_linux_imgact, "linux" };
TEXT_SET(execsw_set, linux_execsw);

406
sys/i386/linux/linux.h Normal file
View File

@ -0,0 +1,406 @@
/*-
* Copyright (c) 1994-1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux.h,v 1.3 1995/06/08 13:50:52 sos Exp $
*/
#ifndef LINUX_H
#define LINUX_H
typedef unsigned short linux_uid_t;
typedef unsigned short linux_gid_t;
typedef unsigned short linux_dev_t;
typedef unsigned long linux_ino_t;
typedef unsigned short linux_mode_t;
typedef unsigned short linux_nlink_t;
typedef long linux_time_t;
typedef long linux_clock_t;
typedef char * linux_caddr_t;
typedef long linux_off_t;
typedef struct {
long val[2];
} linux_fsid_t;
typedef int linux_pid_t;
typedef unsigned long linux_sigset_t;
typedef void (*linux_handler_t)(int);
typedef struct {
void (*sa_handler)(int);
linux_sigset_t sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void);
} linux_sigaction_t;
typedef int linux_key_t;
extern int bsd_to_linux_signal[];
extern int linux_to_bsd_signal[];
/* misc defines */
#define LINUX_NAME_MAX 255
/* signal numbers */
#define LINUX_SIGHUP 1
#define LINUX_SIGINT 2
#define LINUX_SIGQUIT 3
#define LINUX_SIGILL 4
#define LINUX_SIGTRAP 5
#define LINUX_SIGABRT 6
#define LINUX_SIGIOT 6
#define LINUX_SIGUNUSED 7
#define LINUX_SIGFPE 8
#define LINUX_SIGKILL 9
#define LINUX_SIGUSR1 10
#define LINUX_SIGSEGV 11
#define LINUX_SIGUSR2 12
#define LINUX_SIGPIPE 13
#define LINUX_SIGALRM 14
#define LINUX_SIGTERM 15
#define LINUX_SIGSTKFLT 16
#define LINUX_SIGCHLD 17
#define LINUX_SIGCONT 18
#define LINUX_SIGSTOP 19
#define LINUX_SIGTSTP 20
#define LINUX_SIGTTIN 21
#define LINUX_SIGTTOU 22
#define LINUX_SIGIO 23
#define LINUX_SIGPOLL LINUX_SIGIO
#define LINUX_SIGURG LINUX_SIGIO
#define LINUX_SIGXCPU 24
#define LINUX_SIGXFSZ 25
#define LINUX_SIGVTALRM 26
#define LINUX_SIGPROF 27
#define LINUX_SIGWINCH 28
#define LINUX_SIGLOST 29
#define LINUX_SIGPWR 30
#define LINUX_SIGBUS LINUX_SIGUNUSED
#define LINUX_NSIG 32
/* sigaction flags */
#define LINUX_SA_NOCLDSTOP 0x00000001
#define LINUX_SA_ONSTACK 0x08000000
#define LINUX_SA_RESTART 0x10000000
#define LINUX_SA_INTERRUPT 0x20000000
#define LINUX_SA_NOMASK 0x40000000
#define LINUX_SA_ONESHOT 0x80000000
/* sigprocmask actions */
#define LINUX_SIG_BLOCK 0
#define LINUX_SIG_UNBLOCK 1
#define LINUX_SIG_SETMASK 2
/* termio commands */
#define LINUX_TCGETS 0x5401
#define LINUX_TCSETS 0x5402
#define LINUX_TCSETSW 0x5403
#define LINUX_TCSETSF 0x5404
#define LINUX_TCGETA 0x5405
#define LINUX_TCSETA 0x5406
#define LINUX_TCSETAW 0x5407
#define LINUX_TCSETAF 0x5408
#define LINUX_TCSBRK 0x5409
#define LINUX_TCXONC 0x540A
#define LINUX_TCFLSH 0x540B
#define LINUX_TIOCEXCL 0x540C
#define LINUX_TIOCNXCL 0x540D
#define LINUX_TIOCSCTTY 0x540E
#define LINUX_TIOCGPGRP 0x540F
#define LINUX_TIOCSPGRP 0x5410
#define LINUX_TIOCOUTQ 0x5411
#define LINUX_TIOCSTI 0x5412
#define LINUX_TIOCGWINSZ 0x5413
#define LINUX_TIOCSWINSZ 0x5414
#define LINUX_TIOCMGET 0x5415
#define LINUX_TIOCMBIS 0x5416
#define LINUX_TIOCMBIC 0x5417
#define LINUX_TIOCMSET 0x5418
#define LINUX_TIOCGSOFTCAR 0x5419
#define LINUX_TIOCSSOFTCAR 0x541A
#define LINUX_FIONREAD 0x541B
#define LINUX_TIOCINQ FIONREAD
#define LINUX_TIOCLINUX 0x541C
#define LINUX_TIOCCONS 0x541D
#define LINUX_TIOCGSERIAL 0x541E
#define LINUX_TIOCSSERIAL 0x541F
#define LINUX_TIOCPKT 0x5420
#define LINUX_FIONBIO 0x5421
#define LINUX_TIOCNOTTY 0x5422
#define LINUX_TIOCSETD 0x5423
#define LINUX_TIOCGETD 0x5424
#define LINUX_TCSBRKP 0x5425
#define LINUX_TIOCTTYGSTRUCT 0x5426
#define LINUX_FIONCLEX 0x5450
#define LINUX_FIOCLEX 0x5451
#define LINUX_FIOASYNC 0x5452
#define LINUX_TIOCSERCONFIG 0x5453
#define LINUX_TIOCSERGWILD 0x5454
#define LINUX_TIOCSERSWILD 0x5455
#define LINUX_TIOCGLCKTRMIOS 0x5456
#define LINUX_TIOCSLCKTRMIOS 0x5457
/* line disciplines */
#define LINUX_N_TTY 0
#define LINUX_N_SLIP 1
#define LINUX_N_MOUSE 2
#define LINUX_N_PPP 3
/* Linux termio c_cc values */
#define LINUX_VINTR 0
#define LINUX_VQUIT 1
#define LINUX_VERASE 2
#define LINUX_VKILL 3
#define LINUX_VEOF 4
#define LINUX_VTIME 5
#define LINUX_VMIN 6
#define LINUX_VSWTC 7
#define LINUX_NCC 8
/* Linux termios c_cc values */
#define LINUX_VSTART 8
#define LINUX_VSTOP 9
#define LINUX_VSUSP 10
#define LINUX_VEOL 11
#define LINUX_VREPRINT 12
#define LINUX_VDISCARD 13
#define LINUX_VWERASE 14
#define LINUX_VLNEXT 15
#define LINUX_VEOL2 16
#define LINUX_NCCS 17
/* Linux c_iflag masks */
#define LINUX_IGNBRK 0x0000001
#define LINUX_BRKINT 0x0000002
#define LINUX_IGNPAR 0x0000004
#define LINUX_PARMRK 0x0000008
#define LINUX_INPCK 0x0000010
#define LINUX_ISTRIP 0x0000020
#define LINUX_INLCR 0x0000040
#define LINUX_IGNCR 0x0000080
#define LINUX_ICRNL 0x0000100
#define LINUX_IUCLC 0x0000200
#define LINUX_IXON 0x0000400
#define LINUX_IXANY 0x0000800
#define LINUX_IXOFF 0x0001000
#define LINUX_IMAXBEL 0x0002000
/* Linux c_oflag masks */
#define LINUX_OPOST 0x0000001
#define LINUX_OLCUC 0x0000002
#define LINUX_ONLCR 0x0000004
#define LINUX_OCRNL 0x0000008
#define LINUX_ONOCR 0x0000010
#define LINUX_ONLRET 0x0000020
#define LINUX_OFILL 0x0000040
#define LINUX_OFDEL 0x0000080
#define LINUX_NLDLY 0x0000100
#define LINUX_NL0 0x0000000
#define LINUX_NL1 0x0000100
#define LINUX_CRDLY 0x0000600
#define LINUX_CR0 0x0000000
#define LINUX_CR1 0x0000200
#define LINUX_CR2 0x0000400
#define LINUX_CR3 0x0000600
#define LINUX_TABDLY 0x0001800
#define LINUX_TAB0 0x0000000
#define LINUX_TAB1 0x0000800
#define LINUX_TAB2 0x0001000
#define LINUX_TAB3 0x0001800
#define LINUX_XTABS 0x0001800
#define LINUX_BSDLY 0x0002000
#define LINUX_BS0 0x0000000
#define LINUX_BS1 0x0002000
#define LINUX_VTDLY 0x0004000
#define LINUX_VT0 0x0000000
#define LINUX_VT1 0x0004000
#define LINUX_FFDLY 0x0008000
#define LINUX_FF0 0x0000000
#define LINUX_FF1 0x0008000
#define LINUX_CBAUD 0x0000100f
#define LINUX_B0 0x00000000
#define LINUX_B50 0x00000001
#define LINUX_B75 0x00000002
#define LINUX_B110 0x00000003
#define LINUX_B134 0x00000004
#define LINUX_B150 0x00000005
#define LINUX_B200 0x00000006
#define LINUX_B300 0x00000007
#define LINUX_B600 0x00000008
#define LINUX_B1200 0x00000009
#define LINUX_B1800 0x0000000a
#define LINUX_B2400 0x0000000b
#define LINUX_B4800 0x0000000c
#define LINUX_B9600 0x0000000d
#define LINUX_B19200 0x0000000e
#define LINUX_B38400 0x0000000f
#define LINUX_EXTA LINUX_B19200
#define LINUX_EXTB LINUX_B38400
#define LINUX_CBAUDEX 0x00001000
#define LINUX_B57600 0x00001001
#define LINUX_B115200 0x00001002
#define LINUX_CSIZE 0x00000030
#define LINUX_CS5 0x00000000
#define LINUX_CS6 0x00000010
#define LINUX_CS7 0x00000020
#define LINUX_CS8 0x00000030
#define LINUX_CSTOPB 0x00000040
#define LINUX_CREAD 0x00000080
#define LINUX_PARENB 0x00000100
#define LINUX_PARODD 0x00000200
#define LINUX_HUPCL 0x00000400
#define LINUX_CLOCAL 0x00000800
#define LINUX_CRTSCTS 0x80000000
/* Linux c_lflag masks */
#define LINUX_ISIG 0x00000001
#define LINUX_ICANON 0x00000002
#define LINUX_XCASE 0x00000004
#define LINUX_ECHO 0x00000008
#define LINUX_ECHOE 0x00000010
#define LINUX_ECHOK 0x00000020
#define LINUX_ECHONL 0x00000040
#define LINUX_NOFLSH 0x00000080
#define LINUX_TOSTOP 0x00000100
#define LINUX_ECHOCTL 0x00000200
#define LINUX_ECHOPRT 0x00000400
#define LINUX_ECHOKE 0x00000800
#define LINUX_FLUSHO 0x00001000
#define LINUX_PENDIN 0x00002000
#define LINUX_IEXTEN 0x00008000
/* open/fcntl flags */
#define LINUX_O_RDONLY 00
#define LINUX_O_WRONLY 01
#define LINUX_O_RDWR 02
#define LINUX_O_CREAT 0100
#define LINUX_O_EXCL 0200
#define LINUX_O_NOCTTY 0400
#define LINUX_O_TRUNC 01000
#define LINUX_O_APPEND 02000
#define LINUX_O_NONBLOCK 04000
#define LINUX_O_NDELAY LINUX_O_NONBLOCK
#define LINUX_O_SYNC 010000
#define LINUX_FASYNC 020000
/* fcntl flags */
#define LINUX_F_DUPFD 0
#define LINUX_F_GETFD 1
#define LINUX_F_SETFD 2
#define LINUX_F_GETFL 3
#define LINUX_F_SETFL 4
#define LINUX_F_GETLK 5
#define LINUX_F_SETLK 6
#define LINUX_F_SETLKW 7
#define LINUX_F_SETOWN 8
#define LINUX_F_GETOWN 9
#define LINUX_F_RDLCK 0
#define LINUX_F_WRLCK 1
#define LINUX_F_UNLCK 2
/* mmap options */
#define LINUX_MAP_SHARED 0x0001
#define LINUX_MAP_PRIVATE 0x0002
#define LINUX_MAP_FIXED 0x0010
#define LINUX_MAP_ANON 0x0020
/* SystemV ipc defines */
#define LINUX_SEMOP 1
#define LINUX_SEMGET 2
#define LINUX_SEMCTL 3
#define LINUX_MSGSND 11
#define LINUX_MSGRCV 12
#define LINUX_MSGGET 13
#define LINUX_MSGCTL 14
#define LINUX_SHMAT 21
#define LINUX_SHMDT 22
#define LINUX_SHMGET 23
#define LINUX_SHMCTL 24
#define LINUX_IPC_RMID 0
#define LINUX_IPC_SET 1
#define LINUX_IPC_STAT 2
#define LINUX_IPC_INFO 3
#define LINUX_SHM_LOCK 11
#define LINUX_SHM_UNLOCK 12
#define LINUX_SHM_STAT 13
#define LINUX_SHM_INFO 14
#define LINUX_SHM_RDONLY 0x1000
#define LINUX_SHM_RND 0x2000
#define LINUX_SHM_REMAP 0x4000
/* Socket defines */
#define LINUX_SOCKET 1
#define LINUX_BIND 2
#define LINUX_CONNECT 3
#define LINUX_LISTEN 4
#define LINUX_ACCEPT 5
#define LINUX_GETSOCKNAME 6
#define LINUX_GETPEERNAME 7
#define LINUX_SOCKETPAIR 8
#define LINUX_SEND 9
#define LINUX_RECV 10
#define LINUX_SENDTO 11
#define LINUX_RECVFROM 12
#define LINUX_SHUTDOWN 13
#define LINUX_SETSOCKOPT 14
#define LINUX_GETSOCKOPT 15
#define LINUX_AF_UNSPEC 0
#define LINUX_AF_UNIX 1
#define LINUX_AF_INET 2
#define LINUX_AF_AX25 3
#define LINUX_AF_IPX 4
#define LINUX_AF_APPLETALK 5
#define LINUX_SOL_SOCKET 1
#define LINUX_SOL_IP 0
#define LINUX_SOL_IPX 256
#define LINUX_SOL_AX25 257
#define LINUX_SOL_TCP 6
#define LINUX_SOL_UDP 17
#define LINUX_SO_DEBUG 1
#define LINUX_SO_REUSEADDR 2
#define LINUX_SO_TYPE 3
#define LINUX_SO_ERROR 4
#define LINUX_SO_DONTROUTE 5
#define LINUX_SO_BROADCAST 6
#define LINUX_SO_SNDBUF 7
#define LINUX_SO_RCVBUF 8
#define LINUX_SO_KEEPALIVE 9
#define LINUX_SO_OOBINLINE 10
#define LINUX_SO_NO_CHECK 11
#define LINUX_SO_PRIORITY 12
#define LINUX_SO_LINGER 13
#define LINUX_IP_TOS 1
#define LINUX_IP_TTL 2
#endif /* LINUX_H */

View File

@ -0,0 +1,316 @@
/*-
* Copyright (c) 1994-1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux_dummy.c,v 1.3 1995/06/08 13:50:52 sos Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/resourcevar.h>
#include <sys/errno.h>
#include <vm/vm.h>
int
linux_setup(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): setup() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_break(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): break() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_stat(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): stat() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_fstat(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): fstat() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_mount(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): mount() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_umount(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): umount() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_stime(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): stime() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_ptrace(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): ptrace() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_pause(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): pause() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_stty(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): stty() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_gtty(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): gtty() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_nice(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): nice() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_ftime(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): ftime() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_prof(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): prof() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_signal(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): signal() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_phys(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): phys() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_lock(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): lock() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_mpx(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): mpx() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_ulimit(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): ulimit() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_olduname(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): olduname() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_ustat(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): ustat() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_ioperm(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): ioperm() not supported\n", p->p_pid);
return 0; /* EINVAL SOS XXX */
}
int
linux_syslog(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): syslog() not supported (BSD sigreturn)\n",p->p_pid);
return sigreturn(p, args, retval);
}
int
linux_iopl(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): iopl() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_vhangup(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): vhangup() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_idle(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): idle() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_vm86(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): vm86() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_swapoff(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): swapoff() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_sysinfo(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): sysinfo() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_sigreturn(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): sigreturn() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_clone(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): clone() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_uname(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): uname() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_modify_ldt(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): modify_ldt() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_adjtimex(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): adjtimex() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_create_module(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): create_module() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_init_module(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): init_module() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_delete_module(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): delete_module() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_get_kernel_syms(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): get_kernel_syms() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_quotactl(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): quotactl() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_bdflush(struct proc *p, void *args, int *retval)
{
printf("Linux-emul(%d): bdflush() not supported\n", p->p_pid);
return ENOSYS;
}

436
sys/i386/linux/linux_file.c Normal file
View File

@ -0,0 +1,436 @@
/*-
* Copyright (c) 1994-1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux_file.c,v 1.2 1995/06/07 21:27:57 sos Exp $
*/
#include <i386/linux/linux.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/proc.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/vnode.h>
#include <sys/malloc.h>
#include <sys/exec.h>
#include <sys/dirent.h>
#include <vm/vm.h>
#include <ufs/ufs/dir.h>
struct linux_creat_args {
char *path;
int mode;
};
int
linux_creat(struct proc *p, struct linux_creat_args *args, int *retval)
{
struct {
char *path;
int flags;
int mode;
} bsd_open_args;
#ifdef DEBUG
printf("Linux-emul(%d): creat(%s, %d)\n",
p->p_pid, args->path, args->mode);
#endif
bsd_open_args.path = args->path;
bsd_open_args.mode = args->mode;
bsd_open_args.flags = O_WRONLY | O_CREAT | O_TRUNC;
return open(p, &bsd_open_args, retval);
}
struct linux_open_args {
char *path;
int flags;
int mode;
};
int
linux_open(struct proc *p, struct linux_open_args *args, int *retval)
{
struct {
char *path;
int flags;
int mode;
} bsd_open_args;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): open(%s, 0x%x, 0x%x)\n",
p->p_pid, args->path, args->flags, args->mode);
#endif
bsd_open_args.flags = 0;
if (args->flags & LINUX_O_RDONLY)
bsd_open_args.flags |= O_RDONLY;
if (args->flags & LINUX_O_WRONLY)
bsd_open_args.flags |= O_WRONLY;
if (args->flags & LINUX_O_RDWR)
bsd_open_args.flags |= O_RDWR;
if (args->flags & LINUX_O_NDELAY)
bsd_open_args.flags |= O_NONBLOCK;
if (args->flags & LINUX_O_APPEND)
bsd_open_args.flags |= O_APPEND;
if (args->flags & LINUX_O_SYNC)
bsd_open_args.flags |= O_FSYNC;
if (args->flags & LINUX_O_NONBLOCK)
bsd_open_args.flags |= O_NONBLOCK;
if (args->flags & LINUX_FASYNC)
bsd_open_args.flags |= O_ASYNC;
if (args->flags & LINUX_O_CREAT)
bsd_open_args.flags |= O_CREAT;
if (args->flags & LINUX_O_TRUNC)
bsd_open_args.flags |= O_TRUNC;
if (args->flags & LINUX_O_EXCL)
bsd_open_args.flags |= O_EXCL;
if (args->flags & LINUX_O_NOCTTY)
bsd_open_args.flags |= O_NOCTTY;
bsd_open_args.path = args->path;
bsd_open_args.mode = args->mode;
error = open(p, &bsd_open_args, retval);
if (!error && !(bsd_open_args.flags & O_NOCTTY) &&
SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
struct filedesc *fdp = p->p_fd;
struct file *fp = fdp->fd_ofiles[*retval];
if (fp->f_type == DTYPE_VNODE)
(fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, (caddr_t) 0, p);
}
return error;
}
struct linux_flock {
short l_type;
short l_whence;
linux_off_t l_start;
linux_off_t l_len;
linux_pid_t l_pid;
};
static void
linux_to_bsd_flock(struct linux_flock *linux_flock, struct flock *bsd_flock)
{
switch (linux_flock->l_type) {
case LINUX_F_RDLCK:
bsd_flock->l_type = F_RDLCK;
break;
case LINUX_F_WRLCK:
bsd_flock->l_type = F_WRLCK;
break;
case LINUX_F_UNLCK:
bsd_flock->l_type = F_UNLCK;
break;
}
bsd_flock->l_whence = linux_flock->l_whence;
bsd_flock->l_start = (off_t)linux_flock->l_start;
bsd_flock->l_len = (off_t)linux_flock->l_len;
bsd_flock->l_pid = (pid_t)linux_flock->l_pid;
}
static void
bsd_to_linux_flock(struct flock *bsd_flock, struct linux_flock *linux_flock)
{
switch (bsd_flock->l_type) {
case F_RDLCK:
linux_flock->l_type = LINUX_F_RDLCK;
break;
case F_WRLCK:
linux_flock->l_type = LINUX_F_WRLCK;
break;
case F_UNLCK:
linux_flock->l_type = LINUX_F_UNLCK;
break;
}
linux_flock->l_whence = bsd_flock->l_whence;
linux_flock->l_start = (linux_off_t)bsd_flock->l_start;
linux_flock->l_len = (linux_off_t)bsd_flock->l_len;
linux_flock->l_pid = (linux_pid_t)bsd_flock->l_pid;
}
struct linux_fcntl_args {
int fd;
int cmd;
int arg;
};
int
linux_fcntl(struct proc *p, struct linux_fcntl_args *args, int *retval)
{
int error, result;
struct fcntl_args {
int fd;
int cmd;
int arg;
} fcntl_args;
struct linux_flock linux_flock;
struct flock *bsd_flock =
(struct flock *)ua_alloc_init(sizeof(struct flock));
#ifdef DEBUG
printf("Linux-emul(%d): fcntl(%d, %08x, *)\n",
p->p_pid, args->fd, args->cmd);
#endif
fcntl_args.fd = args->fd;
fcntl_args.arg = 0;
switch (args->cmd) {
case LINUX_F_DUPFD:
fcntl_args.cmd = F_DUPFD;
return fcntl(p, &fcntl_args, retval);
case LINUX_F_GETFD:
fcntl_args.cmd = F_GETFD;
return fcntl(p, &fcntl_args, retval);
case LINUX_F_SETFD:
fcntl_args.cmd = F_SETFD;
return fcntl(p, &fcntl_args, retval);
case LINUX_F_GETFL:
fcntl_args.cmd = F_GETFL;
error = fcntl(p, &fcntl_args, &result);
*retval = 0;
if (result & O_RDONLY) *retval |= LINUX_O_RDONLY;
if (result & O_WRONLY) *retval |= LINUX_O_WRONLY;
if (result & O_RDWR) *retval |= LINUX_O_RDWR;
if (result & O_NDELAY) *retval |= LINUX_O_NONBLOCK;
if (result & O_APPEND) *retval |= LINUX_O_APPEND;
if (result & O_FSYNC) *retval |= LINUX_O_SYNC;
return error;
case LINUX_F_SETFL:
if (args->arg & LINUX_O_NDELAY) fcntl_args.arg |= O_NONBLOCK;
if (args->arg & LINUX_O_APPEND) fcntl_args.arg |= O_APPEND;
if (args->arg & LINUX_O_SYNC) fcntl_args.arg |= O_FSYNC;
fcntl_args.cmd = F_SETFL;
return fcntl(p, &fcntl_args, retval);
case LINUX_F_GETLK:
if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock,
sizeof(struct linux_flock))))
return error;
linux_to_bsd_flock(&linux_flock, bsd_flock);
fcntl_args.cmd = F_GETLK;
fcntl_args.arg = (int)bsd_flock;
if (error = fcntl(p, &fcntl_args, retval))
return error;
bsd_to_linux_flock(bsd_flock, &linux_flock);
return copyout((caddr_t)&linux_flock, (caddr_t)args->arg,
sizeof(struct linux_flock));
case LINUX_F_SETLK:
if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock,
sizeof(struct linux_flock))))
return error;
linux_to_bsd_flock(&linux_flock, bsd_flock);
fcntl_args.cmd = F_SETLK;
fcntl_args.arg = (int)bsd_flock;
return fcntl(p, &fcntl_args, retval);
case LINUX_F_SETLKW:
if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock,
sizeof(struct linux_flock))))
return error;
linux_to_bsd_flock(&linux_flock, bsd_flock);
fcntl_args.cmd = F_SETLKW;
fcntl_args.arg = (int)bsd_flock;
return fcntl(p, &fcntl_args, retval);
case LINUX_F_SETOWN:
fcntl_args.cmd = F_SETOWN;
return fcntl(p, &fcntl_args, retval);
case LINUX_F_GETOWN:
fcntl_args.cmd = F_GETOWN;
return fcntl(p, &fcntl_args, retval);
}
return EINVAL;
}
struct linux_lseek_args {
int fdes;
unsigned long off;
int whence;
};
int
linux_lseek(struct proc *p, struct linux_lseek_args *args, int *retval)
{
struct lseek_args {
int fdes;
int pad;
off_t off;
int whence;
} tmp_args;
off_t tmp_retval;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): lseek(%d, %d, %d)\n",
p->p_pid, args->fdes, args->off, args->whence);
#endif
tmp_args.fdes = args->fdes;
tmp_args.off = (off_t)args->off;
tmp_args.whence = args->whence;
error = lseek(p, &tmp_args, &tmp_retval);
*retval = (int)tmp_retval;
return error;
}
struct linux_dirent {
long dino;
linux_off_t doff;
unsigned short dreclen;
char dname[LINUX_NAME_MAX + 1];
};
#define LINUX_RECLEN(de,namlen) \
ALIGN((((char *)&(de)->dname - (char *)de) + (namlen) + 1))
struct linux_readdir_args {
int fd;
struct linux_dirent *dent;
unsigned int count;
};
int
linux_readdir(struct proc *p, struct linux_readdir_args *args, int *retval)
{
register struct dirent *bdp;
struct vnode *vp;
caddr_t inp, buf; /* BSD-format */
int len, reclen; /* BSD-format */
caddr_t outp; /* Linux-format */
int resid, linuxreclen=0; /* Linux-format */
struct file *fp;
struct uio auio;
struct iovec aiov;
struct vattr va;
off_t off;
struct linux_dirent linux_dirent;
int buflen, error, eofflag, nbytes, justone;
#ifdef DEBUG
printf("Linux-emul(%d): readdir(%d, *, %d)\n",
p->p_pid, args->fd, args->count);
#endif
if ((error = getvnode(p->p_fd, args->fd, &fp)) != 0)
return (error);
if ((fp->f_flag & FREAD) == 0)
return (EBADF);
vp = (struct vnode *) fp->f_data;
if (vp->v_type != VDIR)
return (EINVAL);
if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)))
return error;
nbytes = args->count;
if (nbytes == 1) {
nbytes = sizeof (struct linux_dirent);
justone = 1;
}
else
justone = 0;
buflen = max(va.va_blocksize, nbytes);
buf = malloc(buflen, M_TEMP, M_WAITOK);
VOP_LOCK(vp);
off = fp->f_offset;
again:
aiov.iov_base = buf;
aiov.iov_len = buflen;
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_rw = UIO_READ;
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_procp = p;
auio.uio_resid = buflen;
auio.uio_offset = off;
error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, (u_long *) 0, 0);
if (error)
goto out;
inp = buf;
outp = (caddr_t) args->dent;
resid = nbytes;
if ((len = buflen - auio.uio_resid) == 0)
goto eof;
while (len > 0) {
reclen = ((struct dirent *) inp)->d_reclen;
if (reclen & 3)
panic("linux_readdir");
off += reclen;
bdp = (struct dirent *) inp;
if (bdp->d_fileno == 0) {
inp += reclen;
continue;
}
linuxreclen = LINUX_RECLEN(&linux_dirent, bdp->d_namlen);
if (reclen > len || resid < linuxreclen) {
outp++;
break;
}
linux_dirent.dino = (long) bdp->d_fileno;
linux_dirent.doff = (linux_off_t) linuxreclen;
linux_dirent.dreclen = (u_short) bdp->d_namlen;
strcpy(linux_dirent.dname, bdp->d_name);
if ((error = copyout((caddr_t)&linux_dirent, outp, linuxreclen)))
goto out;
inp += reclen;
outp += linuxreclen;
resid -= linuxreclen;
len -= reclen;
if (justone)
break;
}
if (outp == (caddr_t) args->dent)
goto again;
fp->f_offset = off;
if (justone)
nbytes = resid + linuxreclen;
eof:
*retval = nbytes - resid;
out:
VOP_UNLOCK(vp);
free(buf, M_TEMP);
return error;
}

View File

@ -0,0 +1,63 @@
/*-
* Copyright (c) 1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux_generic.c,v 1.3 1995/06/25 17:30:46 sos Exp $
*/
#include <i386/linux/linux.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/exec.h>
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/malloc.h>
#include <sys/vnode.h>
#include <vm/vm.h>
static caddr_t ua_ptr = NULL;
caddr_t ua_alloc_init(int len)
{
caddr_t ptr;
ptr = (caddr_t)ALIGN((PS_STRINGS));
ptr += sizeof(struct ps_strings);
ua_ptr = (caddr_t)(ptr + ALIGN(len));
return ptr;
}
caddr_t ua_alloc(int len)
{
caddr_t ptr;
ptr = ua_ptr;
ua_ptr += ALIGN(len);
return ptr;
}

View File

@ -0,0 +1,495 @@
/*-
* Copyright (c) 1994-1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux_ioctl.c,v 1.2 1995/06/07 21:27:57 sos Exp $
*/
#include <i386/linux/linux.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/ioctl.h>
#include <sys/ioctl_compat.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/tty.h>
#include <sys/termios.h>
#include <machine/console.h>
struct linux_termios {
unsigned long c_iflag;
unsigned long c_oflag;
unsigned long c_cflag;
unsigned long c_lflag;
unsigned char c_line;
unsigned char c_cc[LINUX_NCCS];
};
struct linux_winsize {
unsigned short ws_row, ws_col;
unsigned short ws_xpixel, ws_ypixel;
};
static struct speedtab sptab[] = {
{ 0, 0 }, { 50, 1 }, { 75, 2 }, { 110, 3 },
{ 134, 4 }, { 135, 4 }, { 150, 5 }, { 200, 6 },
{ 300, 7 }, { 600, 8 }, { 1200, 9 }, { 1800, 10 },
{ 2400, 11 }, { 4800, 12 }, { 9600, 13 },
{ 19200, 14 }, { 38400, 15 },
{ 57600, 4097 }, { 115200, 4098 }, {-1, -1 }
};
static int
linux_to_bsd_speed(int code, struct speedtab *table)
{
for ( ; table->sp_code != -1; table++)
if (table->sp_code == code)
return (table->sp_speed);
return -1;
}
static int
bsd_to_linux_speed(int speed, struct speedtab *table)
{
for ( ; table->sp_speed != -1; table++)
if (table->sp_speed == speed)
return (table->sp_code);
return -1;
}
static void
bsd_to_linux_termios(struct termios *bsd_termios,
struct linux_termios *linux_termios)
{
int i, speed;
#ifdef DEBUG
printf("LINUX: BSD termios structure (input):\n");
printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
bsd_termios->c_iflag, bsd_termios->c_oflag,
bsd_termios->c_cflag, bsd_termios->c_lflag,
bsd_termios->c_ispeed, bsd_termios->c_ospeed);
printf("c_cc ");
for (i=0; i<NCCS; i++)
printf("%02x ", bsd_termios->c_cc[i]);
printf("\n");
#endif
linux_termios->c_iflag = 0;
if (bsd_termios->c_iflag & IGNBRK)
linux_termios->c_iflag |= LINUX_IGNBRK;
if (bsd_termios->c_iflag & BRKINT)
linux_termios->c_iflag |= LINUX_BRKINT;
if (bsd_termios->c_iflag & IGNPAR)
linux_termios->c_iflag |= LINUX_IGNPAR;
if (bsd_termios->c_iflag & PARMRK)
linux_termios->c_iflag |= LINUX_PARMRK;
if (bsd_termios->c_iflag & INPCK)
linux_termios->c_iflag |= LINUX_INPCK;
if (bsd_termios->c_iflag & ISTRIP)
linux_termios->c_iflag |= LINUX_ISTRIP;
if (bsd_termios->c_iflag & INLCR)
linux_termios->c_iflag |= LINUX_INLCR;
if (bsd_termios->c_iflag & IGNCR)
linux_termios->c_iflag |= LINUX_IGNCR;
if (bsd_termios->c_iflag & ICRNL)
linux_termios->c_iflag |= LINUX_ICRNL;
if (bsd_termios->c_iflag & IXON)
linux_termios->c_iflag |= LINUX_IXANY;
if (bsd_termios->c_iflag & IXON)
linux_termios->c_iflag |= LINUX_IXON;
if (bsd_termios->c_iflag & IXOFF)
linux_termios->c_iflag |= LINUX_IXOFF;
if (bsd_termios->c_iflag & IMAXBEL)
linux_termios->c_iflag |= LINUX_IMAXBEL;
linux_termios->c_oflag = 0;
if (bsd_termios->c_oflag & OPOST)
linux_termios->c_oflag |= LINUX_OPOST;
if (bsd_termios->c_oflag & ONLCR)
linux_termios->c_oflag |= LINUX_ONLCR;
if (bsd_termios->c_oflag & OXTABS)
linux_termios->c_oflag |= LINUX_XTABS;
linux_termios->c_cflag =
bsd_to_linux_speed(bsd_termios->c_ispeed, sptab);
linux_termios->c_cflag |= (bsd_termios->c_cflag & CSIZE) >> 4;
if (bsd_termios->c_cflag & CSTOPB)
linux_termios->c_cflag |= LINUX_CSTOPB;
if (bsd_termios->c_cflag & CREAD)
linux_termios->c_cflag |= LINUX_CREAD;
if (bsd_termios->c_cflag & PARENB)
linux_termios->c_cflag |= LINUX_PARENB;
if (bsd_termios->c_cflag & PARODD)
linux_termios->c_cflag |= LINUX_PARODD;
if (bsd_termios->c_cflag & HUPCL)
linux_termios->c_cflag |= LINUX_HUPCL;
if (bsd_termios->c_cflag & CLOCAL)
linux_termios->c_cflag |= LINUX_CLOCAL;
if (bsd_termios->c_cflag & CRTSCTS)
linux_termios->c_cflag |= LINUX_CRTSCTS;
linux_termios->c_lflag = 0;
if (bsd_termios->c_lflag & ISIG)
linux_termios->c_lflag |= LINUX_ISIG;
if (bsd_termios->c_lflag & ICANON)
linux_termios->c_lflag |= LINUX_ICANON;
if (bsd_termios->c_lflag & ECHO)
linux_termios->c_lflag |= LINUX_ECHO;
if (bsd_termios->c_lflag & ECHOE)
linux_termios->c_lflag |= LINUX_ECHOE;
if (bsd_termios->c_lflag & ECHOK)
linux_termios->c_lflag |= LINUX_ECHOK;
if (bsd_termios->c_lflag & ECHONL)
linux_termios->c_lflag |= LINUX_ECHONL;
if (bsd_termios->c_lflag & NOFLSH)
linux_termios->c_lflag |= LINUX_NOFLSH;
if (bsd_termios->c_lflag & TOSTOP)
linux_termios->c_lflag |= LINUX_TOSTOP;
if (bsd_termios->c_lflag & ECHOCTL)
linux_termios->c_lflag |= LINUX_ECHOCTL;
if (bsd_termios->c_lflag & ECHOPRT)
linux_termios->c_lflag |= LINUX_ECHOPRT;
if (bsd_termios->c_lflag & ECHOKE)
linux_termios->c_lflag |= LINUX_ECHOKE;
if (bsd_termios->c_lflag & FLUSHO)
linux_termios->c_lflag |= LINUX_FLUSHO;
if (bsd_termios->c_lflag & PENDIN)
linux_termios->c_lflag |= LINUX_PENDIN;
if (bsd_termios->c_lflag & IEXTEN)
linux_termios->c_lflag |= LINUX_IEXTEN;
for (i=0; i<LINUX_NCCS; i++)
linux_termios->c_cc[i] = _POSIX_VDISABLE;
linux_termios->c_cc[LINUX_VINTR] = bsd_termios->c_cc[VINTR];
linux_termios->c_cc[LINUX_VQUIT] = bsd_termios->c_cc[VQUIT];
linux_termios->c_cc[LINUX_VERASE] = bsd_termios->c_cc[VERASE];
linux_termios->c_cc[LINUX_VKILL] = bsd_termios->c_cc[VKILL];
linux_termios->c_cc[LINUX_VEOF] = bsd_termios->c_cc[VEOF];
linux_termios->c_cc[LINUX_VEOL] = bsd_termios->c_cc[VEOL];
linux_termios->c_cc[LINUX_VMIN] = bsd_termios->c_cc[VMIN];
linux_termios->c_cc[LINUX_VTIME] = bsd_termios->c_cc[VTIME];
linux_termios->c_cc[LINUX_VEOL2] = bsd_termios->c_cc[VEOL2];
linux_termios->c_cc[LINUX_VSWTC] = _POSIX_VDISABLE;
linux_termios->c_cc[LINUX_VSUSP] = bsd_termios->c_cc[VSUSP];
linux_termios->c_cc[LINUX_VSTART] = bsd_termios->c_cc[VSTART];
linux_termios->c_cc[LINUX_VSTOP] = bsd_termios->c_cc[VSTOP];
linux_termios->c_cc[LINUX_VREPRINT] = bsd_termios->c_cc[VREPRINT];
linux_termios->c_cc[LINUX_VDISCARD] = bsd_termios->c_cc[VDISCARD];
linux_termios->c_cc[LINUX_VWERASE] = bsd_termios->c_cc[VWERASE];
linux_termios->c_cc[LINUX_VLNEXT] = bsd_termios->c_cc[VLNEXT];
linux_termios->c_line = 0;
#ifdef DEBUG
printf("LINUX: LINUX termios structure (output):\n");
printf("i=%08x o=%08x c=%08x l=%08x line=%d\n",
linux_termios->c_iflag, linux_termios->c_oflag,
linux_termios->c_cflag, linux_termios->c_lflag,
linux_termios->c_line);
printf("c_cc ");
for (i=0; i<LINUX_NCCS; i++)
printf("%02x ", linux_termios->c_cc[i]);
printf("\n");
#endif
}
static void
linux_to_bsd_termios(struct linux_termios *linux_termios,
struct termios *bsd_termios)
{
int i, speed;
#ifdef DEBUG
printf("LINUX: LINUX termios structure (input):\n");
printf("i=%08x o=%08x c=%08x l=%08x line=%d\n",
linux_termios->c_iflag, linux_termios->c_oflag,
linux_termios->c_cflag, linux_termios->c_lflag,
linux_termios->c_line);
printf("c_cc ");
for (i=0; i<LINUX_NCCS; i++)
printf("%02x ", linux_termios->c_cc[i]);
printf("\n");
#endif
bsd_termios->c_iflag = 0;
if (linux_termios->c_iflag & LINUX_IGNBRK)
bsd_termios->c_iflag |= IGNBRK;
if (linux_termios->c_iflag & LINUX_BRKINT)
bsd_termios->c_iflag |= BRKINT;
if (linux_termios->c_iflag & LINUX_IGNPAR)
bsd_termios->c_iflag |= IGNPAR;
if (linux_termios->c_iflag & LINUX_PARMRK)
bsd_termios->c_iflag |= PARMRK;
if (linux_termios->c_iflag & LINUX_INPCK)
bsd_termios->c_iflag |= INPCK;
if (linux_termios->c_iflag & LINUX_ISTRIP)
bsd_termios->c_iflag |= ISTRIP;
if (linux_termios->c_iflag & LINUX_INLCR)
bsd_termios->c_iflag |= INLCR;
if (linux_termios->c_iflag & LINUX_IGNCR)
bsd_termios->c_iflag |= IGNCR;
if (linux_termios->c_iflag & LINUX_ICRNL)
bsd_termios->c_iflag |= ICRNL;
if (linux_termios->c_iflag & LINUX_IXON)
bsd_termios->c_iflag |= IXANY;
if (linux_termios->c_iflag & LINUX_IXON)
bsd_termios->c_iflag |= IXON;
if (linux_termios->c_iflag & LINUX_IXOFF)
bsd_termios->c_iflag |= IXOFF;
if (linux_termios->c_iflag & LINUX_IMAXBEL)
bsd_termios->c_iflag |= IMAXBEL;
bsd_termios->c_oflag = 0;
if (linux_termios->c_oflag & LINUX_OPOST)
bsd_termios->c_oflag |= OPOST;
if (linux_termios->c_oflag & LINUX_ONLCR)
bsd_termios->c_oflag |= ONLCR;
if (linux_termios->c_oflag & LINUX_XTABS)
bsd_termios->c_oflag |= OXTABS;
bsd_termios->c_cflag = (linux_termios->c_cflag & LINUX_CSIZE) << 4;
if (linux_termios->c_cflag & LINUX_CSTOPB)
bsd_termios->c_cflag |= CSTOPB;
if (linux_termios->c_cflag & LINUX_PARENB)
bsd_termios->c_cflag |= PARENB;
if (linux_termios->c_cflag & LINUX_PARODD)
bsd_termios->c_cflag |= PARODD;
if (linux_termios->c_cflag & LINUX_HUPCL)
bsd_termios->c_cflag |= HUPCL;
if (linux_termios->c_cflag & LINUX_CLOCAL)
bsd_termios->c_cflag |= CLOCAL;
if (linux_termios->c_cflag & LINUX_CRTSCTS)
bsd_termios->c_cflag |= CRTSCTS;
bsd_termios->c_lflag = 0;
if (linux_termios->c_lflag & LINUX_ISIG)
bsd_termios->c_lflag |= ISIG;
if (linux_termios->c_lflag & LINUX_ICANON)
bsd_termios->c_lflag |= ICANON;
if (linux_termios->c_lflag & LINUX_ECHO)
bsd_termios->c_lflag |= ECHO;
if (linux_termios->c_lflag & LINUX_ECHOE)
bsd_termios->c_lflag |= ECHOE;
if (linux_termios->c_lflag & LINUX_ECHOK)
bsd_termios->c_lflag |= ECHOK;
if (linux_termios->c_lflag & LINUX_ECHONL)
bsd_termios->c_lflag |= ECHONL;
if (linux_termios->c_lflag & LINUX_NOFLSH)
bsd_termios->c_lflag |= NOFLSH;
if (linux_termios->c_lflag & LINUX_TOSTOP)
bsd_termios->c_lflag |= TOSTOP;
if (linux_termios->c_lflag & LINUX_ECHOCTL)
bsd_termios->c_lflag |= ECHOCTL;
if (linux_termios->c_lflag & LINUX_ECHOPRT)
bsd_termios->c_lflag |= ECHOPRT;
if (linux_termios->c_lflag & LINUX_ECHOKE)
bsd_termios->c_lflag |= ECHOKE;
if (linux_termios->c_lflag & LINUX_FLUSHO)
bsd_termios->c_lflag |= FLUSHO;
if (linux_termios->c_lflag & LINUX_PENDIN)
bsd_termios->c_lflag |= PENDIN;
if (linux_termios->c_lflag & IEXTEN)
bsd_termios->c_lflag |= IEXTEN;
for (i=0; i<NCCS; i++)
bsd_termios->c_cc[i] = _POSIX_VDISABLE;
bsd_termios->c_cc[VINTR] = linux_termios->c_cc[LINUX_VINTR];
bsd_termios->c_cc[VQUIT] = linux_termios->c_cc[LINUX_VQUIT];
bsd_termios->c_cc[VERASE] = linux_termios->c_cc[LINUX_VERASE];
bsd_termios->c_cc[VKILL] = linux_termios->c_cc[LINUX_VKILL];
bsd_termios->c_cc[VEOF] = linux_termios->c_cc[LINUX_VEOF];
bsd_termios->c_cc[VEOL] = linux_termios->c_cc[LINUX_VEOL];
bsd_termios->c_cc[VMIN] = linux_termios->c_cc[LINUX_VMIN];
bsd_termios->c_cc[VTIME] = linux_termios->c_cc[LINUX_VTIME];
bsd_termios->c_cc[VEOL2] = linux_termios->c_cc[LINUX_VEOL2];
bsd_termios->c_cc[VSUSP] = linux_termios->c_cc[LINUX_VSUSP];
bsd_termios->c_cc[VSTART] = linux_termios->c_cc[LINUX_VSTART];
bsd_termios->c_cc[VSTOP] = linux_termios->c_cc[LINUX_VSTOP];
bsd_termios->c_cc[VREPRINT] = linux_termios->c_cc[LINUX_VREPRINT];
bsd_termios->c_cc[VDISCARD] = linux_termios->c_cc[LINUX_VDISCARD];
bsd_termios->c_cc[VWERASE] = linux_termios->c_cc[LINUX_VWERASE];
bsd_termios->c_cc[VLNEXT] = linux_termios->c_cc[LINUX_VLNEXT];
bsd_termios->c_ispeed = bsd_termios->c_ospeed =
linux_to_bsd_speed(linux_termios->c_cflag & LINUX_CBAUD, sptab);
#ifdef DEBUG
printf("LINUX: BSD termios structure (output):\n");
printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
bsd_termios->c_iflag, bsd_termios->c_oflag,
bsd_termios->c_cflag, bsd_termios->c_lflag,
bsd_termios->c_ispeed, bsd_termios->c_ospeed);
printf("c_cc ");
for (i=0; i<NCCS; i++)
printf("%02x ", bsd_termios->c_cc[i]);
printf("\n");
#endif
}
struct linux_ioctl_args {
int fd;
int cmd;
int arg;
};
int
linux_ioctl(struct proc *p, struct linux_ioctl_args *args, int *retval)
{
struct termios bsd_termios;
struct winsize bsd_winsize;
struct linux_termios linux_termios;
struct linux_winsize linux_winsize;
struct filedesc *fdp = p->p_fd;
struct file *fp;
int (*func)();
int bsd_line, linux_line;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): ioctl(%d, %04x, *)\n",
p->p_pid, args->fd, args->cmd);
#endif
if ((unsigned)args->fd >= fdp->fd_nfiles
|| (fp = fdp->fd_ofiles[args->fd]) == 0)
return EBADF;
if (!fp || (fp->f_flag & (FREAD | FWRITE)) == 0) {
return EBADF;
}
func = fp->f_ops->fo_ioctl;
switch (args->cmd) {
case LINUX_TCGETS:
if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0)
return error;
bsd_to_linux_termios(&bsd_termios, &linux_termios);
return copyout((caddr_t)&linux_termios, (caddr_t)args->arg,
sizeof(linux_termios));
case LINUX_TCSETS:
linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios);
return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p);
case LINUX_TCSETSW:
linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios);
return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p);
case LINUX_TCSETSF:
linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios);
return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p);
case LINUX_TIOCGPGRP:
args->cmd = TIOCGPGRP;
return ioctl(p, args, retval);
case LINUX_TIOCSPGRP:
args->cmd = TIOCSPGRP;
return ioctl(p, args, retval);
case LINUX_TIOCGWINSZ:
args->cmd = TIOCGWINSZ;
return ioctl(p, args, retval);
case LINUX_TIOCSWINSZ:
args->cmd = TIOCSWINSZ;
return ioctl(p, args, retval);
case LINUX_FIONREAD:
args->cmd = FIONREAD;
return ioctl(p, args, retval);
case LINUX_FIONBIO:
args->cmd = FIONBIO;
return ioctl(p, args, retval);
case LINUX_FIOASYNC:
args->cmd = FIOASYNC;
return ioctl(p, args, retval);
case LINUX_FIONCLEX:
args->cmd = FIONCLEX;
return ioctl(p, args, retval);
case LINUX_FIOCLEX:
args->cmd = FIOCLEX;
return ioctl(p, args, retval);
case LINUX_TIOCEXCL:
args->cmd = TIOCEXCL;
return ioctl(p, args, retval);
case LINUX_TIOCNXCL:
args->cmd = TIOCNXCL;
return ioctl(p, args, retval);
case LINUX_TIOCCONS:
args->cmd = TIOCCONS;
return ioctl(p, args, retval);
case LINUX_TIOCNOTTY:
args->cmd = TIOCNOTTY;
return ioctl(p, args, retval);
case LINUX_TIOCSETD:
switch (args->arg) {
case LINUX_N_TTY:
bsd_line = TTYDISC;
return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
case LINUX_N_SLIP:
bsd_line = SLIPDISC;
return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
case LINUX_N_PPP:
bsd_line = PPPDISC;
return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
default:
return EINVAL;
}
break;
case LINUX_TIOCGETD:
bsd_line = TTYDISC;
if (error =(*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p))
return error;
switch (bsd_line) {
case TTYDISC:
linux_line = LINUX_N_TTY;
break;
case SLIPDISC:
linux_line = LINUX_N_SLIP;
break;
case PPPDISC:
linux_line = LINUX_N_PPP;
break;
default:
return EINVAL;
}
return copyout(&linux_line, (caddr_t)args->arg,
sizeof(int));
}
uprintf("LINUX: 'ioctl' fd=%d, typ=0x%x(%c), num=0x%x not implemented\n",
args->fd, (args->cmd&0xffff00)>>8,
(args->cmd&0xffff00)>>8, args->cmd&0xff);
return EINVAL;
}

308
sys/i386/linux/linux_ipc.c Normal file
View File

@ -0,0 +1,308 @@
/*-
* Copyright (c) 1994-1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux_ipc.c,v 1.2 1995/06/07 21:27:57 sos Exp $
*/
#include <i386/linux/linux.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/exec.h>
#include <sys/proc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <vm/vm.h>
struct linux_ipc_perm {
linux_key_t key;
unsigned short uid;
unsigned short gid;
unsigned short cuid;
unsigned short cgid;
unsigned short mode;
unsigned short seq;
};
static void
linux_to_bsd_ipc_perm(struct linux_ipc_perm *lpp, struct ipc_perm *bpp)
{
bpp->key = lpp->key;
bpp->uid = lpp->uid;
bpp->gid = lpp->gid;
bpp->cuid = lpp->cuid;
bpp->cgid = lpp->cgid;
bpp->mode = lpp->mode;
bpp->seq = lpp->seq;
}
static void
bsd_to_linux_ipc_perm(struct ipc_perm *bpp, struct linux_ipc_perm *lpp)
{
lpp->key = bpp->key;
lpp->uid = bpp->uid;
lpp->gid = bpp->gid;
lpp->cuid = bpp->cuid;
lpp->cgid = bpp->cgid;
lpp->mode = bpp->mode;
lpp->seq = bpp->seq;
}
struct linux_shmid_ds {
struct linux_ipc_perm shm_perm;
int shm_segsz;
linux_time_t shm_atime;
linux_time_t shm_dtime;
linux_time_t shm_ctime;
ushort shm_cpid;
ushort shm_lpid;
short shm_nattch;
ushort private1;
void *private2;
void *private3;
};
static void
linux_to_bsd_shmid_ds(struct linux_shmid_ds *lsp, struct shmid_ds *bsp)
{
linux_to_bsd_ipc_perm(&lsp->shm_perm, &bsp->shm_perm);
bsp->shm_segsz = lsp->shm_segsz;
bsp->shm_lpid = lsp->shm_lpid;
bsp->shm_cpid = lsp->shm_cpid;
bsp->shm_nattch = lsp->shm_nattch;
bsp->shm_atime = lsp->shm_atime;
bsp->shm_dtime = lsp->shm_dtime;
bsp->shm_ctime = lsp->shm_ctime;
bsp->shm_internal = lsp->private3; /* this goes (yet) SOS */
}
static void
bsd_to_linux_shmid_ds(struct shmid_ds *bsp, struct linux_shmid_ds *lsp)
{
bsd_to_linux_ipc_perm(&bsp->shm_perm, &lsp->shm_perm);
lsp->shm_segsz = bsp->shm_segsz;
lsp->shm_lpid = bsp->shm_lpid;
lsp->shm_cpid = bsp->shm_cpid;
lsp->shm_nattch = bsp->shm_nattch;
lsp->shm_atime = bsp->shm_atime;
lsp->shm_dtime = bsp->shm_dtime;
lsp->shm_ctime = bsp->shm_ctime;
lsp->private3 = bsp->shm_internal; /* this goes (yet) SOS */
}
struct linux_ipc_args {
int what;
int arg1;
int arg2;
int arg3;
caddr_t ptr;
};
int
linux_semop(struct proc *p, struct linux_ipc_args *args, int *retval)
{
return ENOSYS;
}
int
linux_semget(struct proc *p, struct linux_ipc_args *args, int *retval)
{
return ENOSYS;
}
int
linux_semctl(struct proc *p, struct linux_ipc_args *args, int *retval)
{
return ENOSYS;
}
int
linux_msgsnd(struct proc *p, struct linux_ipc_args *args, int *retval)
{
return ENOSYS;
}
int
linux_msgrcv(struct proc *p, struct linux_ipc_args *args, int *retval)
{
return ENOSYS;
}
int
linux_msgget(struct proc *p, struct linux_ipc_args *args, int *retval)
{
return ENOSYS;
}
int
linux_msgctl(struct proc *p, struct linux_ipc_args *args, int *retval)
{
return ENOSYS;
}
int
linux_shmat(struct proc *p, struct linux_ipc_args *args, int *retval)
{
struct shmat_args {
int shmid;
void *shmaddr;
int shmflg;
} bsd_args;
int error;
bsd_args.shmid = args->arg1;
bsd_args.shmaddr = args->ptr;
bsd_args.shmflg = args->arg2;
if ((error = shmat(p, &bsd_args, retval)))
return error;
if ((error = copyout(retval, (caddr_t)args->arg3, sizeof(int))))
return error;
retval[0] = 0;
return 0;
}
int
linux_shmdt(struct proc *p, struct linux_ipc_args *args, int *retval)
{
struct shmdt_args {
void *shmaddr;
} bsd_args;
bsd_args.shmaddr = args->ptr;
return shmdt(p, &bsd_args, retval);
}
int
linux_shmget(struct proc *p, struct linux_ipc_args *args, int *retval)
{
struct shmget_args {
key_t key;
int size;
int shmflg;
} bsd_args;
bsd_args.key = args->arg1;
bsd_args.size = args->arg2;
bsd_args.shmflg = args->arg3;
return shmget(p, &bsd_args, retval);
}
int
linux_shmctl(struct proc *p, struct linux_ipc_args *args, int *retval)
{
struct shmid_ds bsd_shmid;
struct linux_shmid_ds linux_shmid;
struct shmctl_args {
int shmid;
int cmd;
struct shmid_ds *buf;
} bsd_args;
int error;
switch (args->arg2) {
case LINUX_IPC_STAT:
bsd_args.shmid = args->arg1;
bsd_args.cmd = IPC_STAT;
bsd_args.buf = (struct shmid_ds*)ua_alloc_init(sizeof(struct shmid_ds));
if ((error = shmctl(p, &bsd_args, retval)))
return error;
if ((error = copyin((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
sizeof(struct shmid_ds))))
return error;
bsd_to_linux_shmid_ds(&bsd_shmid, &linux_shmid);
return copyout((caddr_t)&linux_shmid, args->ptr, sizeof(linux_shmid));
case LINUX_IPC_SET:
if ((error = copyin(args->ptr, (caddr_t)&linux_shmid,
sizeof(linux_shmid))))
return error;
linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid);
bsd_args.buf = (struct shmid_ds*)ua_alloc_init(sizeof(struct shmid_ds));
if ((error = copyout((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
sizeof(struct shmid_ds))))
return error;
bsd_args.shmid = args->arg1;
bsd_args.cmd = IPC_SET;
return shmctl(p, &bsd_args, retval);
case LINUX_IPC_RMID:
bsd_args.shmid = args->arg1;
bsd_args.cmd = IPC_RMID;
if ((error = copyin(args->ptr, (caddr_t)&linux_shmid,
sizeof(linux_shmid))))
return error;
linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid);
bsd_args.buf = (struct shmid_ds*)ua_alloc_init(sizeof(struct shmid_ds));
if ((error = copyout((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
sizeof(struct shmid_ds))))
return error;
return shmctl(p, &bsd_args, retval);
case LINUX_IPC_INFO:
case LINUX_SHM_STAT:
case LINUX_SHM_INFO:
case LINUX_SHM_LOCK:
case LINUX_SHM_UNLOCK:
default:
uprintf("LINUX: 'ipc' typ=%d not implemented\n", args->what);
return EINVAL;
}
}
int
linux_ipc(struct proc *p, struct linux_ipc_args *args, int *retval)
{
switch (args->what) {
case LINUX_SEMOP:
return linux_semop(p, args, retval);
case LINUX_SEMGET:
return linux_semget(p, args, retval);
case LINUX_SEMCTL:
return linux_semctl(p, args, retval);
case LINUX_MSGSND:
return linux_msgsnd(p, args, retval);
case LINUX_MSGRCV:
return linux_msgrcv(p, args, retval);
case LINUX_MSGGET:
return linux_msgget(p, args, retval);
case LINUX_MSGCTL:
return linux_msgctl(p, args, retval);
case LINUX_SHMAT:
return linux_shmat(p, args, retval);
case LINUX_SHMDT:
return linux_shmdt(p, args, retval);
case LINUX_SHMGET:
return linux_shmget(p, args, retval);
case LINUX_SHMCTL:
return linux_shmctl(p, args, retval);
default:
uprintf("LINUX: 'ipc' typ=%d not implemented\n", args->what);
return ENOSYS;
}
}

660
sys/i386/linux/linux_misc.c Normal file
View File

@ -0,0 +1,660 @@
/*-
* Copyright (c) 1994-1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux_misc.c,v 1.4 1995/06/08 13:50:52 sos Exp $
*/
#include <i386/linux/linux.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/exec.h>
#include <sys/mman.h>
#include <sys/proc.h>
#include <sys/dirent.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/ioctl.h>
#include <sys/imgact_aout.h>
#include <sys/mount.h>
#include <sys/namei.h>
#include <sys/resource.h>
#include <sys/resourcevar.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/utsname.h>
#include <sys/vnode.h>
#include <sys/wait.h>
#include <machine/cpu.h>
#include <machine/psl.h>
#include <machine/reg.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
struct linux_alarm_args {
unsigned int secs;
};
int
linux_alarm(struct proc *p, struct linux_alarm_args *args, int *retval)
{
extern struct timeval time;
struct itimerval it, old_it;
int s;
#ifdef DEBUG
printf("Linux-emul(%d): alarm(%d)\n", p->p_pid, args->secs);
#endif
it.it_value.tv_sec = (long)args->secs;
it.it_value.tv_usec = 0;
it.it_interval.tv_sec = 0;
it.it_interval.tv_usec = 0;
s = splclock();
old_it = p->p_realtimer;
if (timerisset(&old_it.it_value))
if (timercmp(&old_it.it_value, &time, <))
timerclear(&old_it.it_value);
else
timevalsub(&old_it.it_value, &time);
splx(s);
if (itimerfix(&it.it_value) || itimerfix(&it.it_interval))
return EINVAL;
s = splclock();
untimeout(realitexpire, (caddr_t)p);
if (timerisset(&it.it_value)) {
timevaladd(&it.it_value, &time);
timeout(realitexpire, (caddr_t)p, hzto(&it.it_value));
}
p->p_realtimer = it;
splx(s);
if (old_it.it_value.tv_usec)
old_it.it_value.tv_sec++;
*retval = old_it.it_value.tv_sec;
return 0;
}
struct linux_brk_args {
linux_caddr_t dsend;
};
int
linux_brk(struct proc *p, struct linux_brk_args *args, int *retval)
{
#if 0
struct vmspace *vm = p->p_vmspace;
vm_offset_t new, old;
int error;
extern int swap_pager_full;
if ((vm_offset_t)args->dsend < (vm_offset_t)vm->vm_daddr)
return EINVAL;
if (((caddr_t)args->dsend - (caddr_t)vm->vm_daddr)
> p->p_rlimit[RLIMIT_DATA].rlim_cur)
return ENOMEM;
old = round_page((vm_offset_t)vm->vm_daddr) + ctob(vm->vm_dsize);
new = round_page((vm_offset_t)args->dsend);
*retval = old;
if ((new-old) > 0) {
if (swap_pager_full)
return ENOMEM;
error = vm_map_find(&vm->vm_map, NULL, 0, &old, (new-old), FALSE);
if (error)
return error;
vm->vm_dsize += btoc((new-old));
*retval = (int)(vm->vm_daddr + ctob(vm->vm_dsize));
}
return 0;
#else
struct vmspace *vm = p->p_vmspace;
vm_offset_t new, old;
struct obreak_args {
vm_offset_t newsize;
} tmp;
#ifdef DEBUG
printf("Linux-emul(%d): brk(%08x)\n", p->p_pid, args->dsend);
#endif
old = (vm_offset_t)vm->vm_daddr + ctob(vm->vm_dsize);
new = (vm_offset_t)args->dsend;
tmp.newsize = new;
if (((caddr_t)new > vm->vm_daddr) && !obreak(p, &tmp, retval))
retval[0] = (int)new;
else
retval[0] = (int)old;
return 0;
#endif
}
struct linux_uselib_args {
char *library;
};
int
linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval)
{
struct nameidata ni;
struct vnode *vnodep;
struct exec *a_out = 0;
struct vattr attr;
unsigned long vmaddr, virtual_offset, file_offset;
unsigned long buffer, bss_size;
char *ptr;
char path[MAXPATHLEN];
const char *prefix = "/compat/linux";
size_t sz, len;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): uselib(%s)\n", p->p_pid, args->library);
#endif
for (ptr = path; (*ptr = *prefix) != '\0'; ptr++, prefix++) ;
sz = MAXPATHLEN - (ptr - path);
if (error = copyinstr(args->library, ptr, sz, &len))
return error;
if (*ptr != '/')
return EINVAL;
#ifdef DEBUG
printf("Linux-emul(%d): uselib(%s)\n", p->p_pid, path);
#endif
NDINIT(&ni, LOOKUP, FOLLOW, UIO_SYSSPACE, path, p);
if (error = namei(&ni))
return error;
vnodep = ni.ni_vp;
if (vnodep == NULL)
return ENOEXEC;
if (vnodep->v_writecount)
return ETXTBSY;
if (error = VOP_GETATTR(vnodep, &attr, p->p_ucred, p))
return error;
if ((vnodep->v_mount->mnt_flag & MNT_NOEXEC)
|| ((attr.va_mode & 0111) == 0)
|| (attr.va_type != VREG))
return ENOEXEC;
if (attr.va_size == 0)
return ENOEXEC;
if (error = VOP_ACCESS(vnodep, VEXEC, p->p_ucred, p))
return error;
if (error = VOP_OPEN(vnodep, FREAD, p->p_ucred, p))
return error;
error = vm_mmap(kernel_map, (vm_offset_t *)&a_out, 1024,
VM_PROT_READ, VM_PROT_READ, 0, (caddr_t)vnodep, 0);
if (error)
return (error);
/*
* Is it a Linux binary ?
*/
if (((a_out->a_magic >> 16) & 0xff) != 0x64)
return -1;
/*
* Set file/virtual offset based on a.out variant.
*/
switch ((int)(a_out->a_magic & 0xffff)) {
case 0413: /* ZMAGIC */
virtual_offset = 0;
file_offset = 1024;
break;
case 0314: /* QMAGIC */
virtual_offset = 4096;
file_offset = 0;
break;
default:
return (-1);
}
vnodep->v_flag |= VTEXT;
bss_size = round_page(a_out->a_bss);
/*
* Check if file_offset page aligned,.
* Currently we cannot handle misalinged file offsets,
* and so we read in the entire image (what a waste).
*/
if (file_offset & PGOFSET) {
#ifdef DEBUG
printf("uselib: Non page aligned binary %d\n", file_offset);
#endif
/*
* Map text+data read/write/execute
*/
vmaddr = virtual_offset + round_page(a_out->a_entry);
error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr,
round_page(a_out->a_text + a_out->a_data), FALSE);
if (error)
return error;
error = vm_mmap(kernel_map, &buffer,
round_page(a_out->a_text + a_out->a_data + file_offset),
VM_PROT_READ, VM_PROT_READ, MAP_FILE,
(caddr_t)vnodep, trunc_page(file_offset));
if (error)
return error;
error = copyout((caddr_t)(buffer + file_offset), (caddr_t)vmaddr,
a_out->a_text + a_out->a_data);
if (error)
return error;
vm_map_remove(kernel_map, trunc_page(vmaddr),
round_page(a_out->a_text + a_out->a_data + file_offset));
error = vm_map_protect(&p->p_vmspace->vm_map, vmaddr,
round_page(a_out->a_text + a_out->a_data),
VM_PROT_ALL, TRUE);
if (error)
return error;
}
else {
#ifdef DEBUG
printf("uselib: Page aligned binary %d\n", file_offset);
#endif
vmaddr = virtual_offset + round_page(a_out->a_entry);
error = vm_mmap(&p->p_vmspace->vm_map, &vmaddr,
a_out->a_text + a_out->a_data,
VM_PROT_ALL, VM_PROT_ALL, MAP_PRIVATE | MAP_FIXED,
(caddr_t)vnodep, file_offset);
if (error)
return (error);
}
#ifdef DEBUG
printf("mem=%08x = %08x %08x\n", vmaddr, ((int*)vmaddr)[0], ((int*)vmaddr)[1]);
#endif
if (bss_size != 0) {
vmaddr = virtual_offset + round_page(a_out->a_entry) +
round_page(a_out->a_text + a_out->a_data);
error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr,
bss_size, FALSE);
if (error)
return error;
error = vm_map_protect(&p->p_vmspace->vm_map, vmaddr, bss_size,
VM_PROT_ALL, TRUE);
if (error)
return error;
}
return 0;
}
struct linux_select_args {
void *ptr;
};
int
linux_select(struct proc *p, struct linux_select_args *args, int *retval)
{
struct {
int nfds;
fd_set *readfds;
fd_set *writefds;
fd_set *exceptfds;
struct timeval *timeout;
} linux_args;
struct {
unsigned int nd;
fd_set *in;
fd_set *ou;
fd_set *ex;
struct timeval *tv;
} bsd_args;
int error;
if ((error = copyin((caddr_t)args->ptr, (caddr_t)&linux_args,
sizeof(linux_args))))
return error;
#ifdef DEBUG
printf("Linux-emul(%d): select(%d, %d, %d, %d, %d)\n",
p->p_pid, linux_args.nfds, linux_args.readfds,
linux_args.writefds, linux_args.exceptfds,
linux_args.timeout);
#endif
bsd_args.nd = linux_args.nfds;
bsd_args.in = linux_args.readfds;
bsd_args.ou = linux_args.writefds;
bsd_args.ex = linux_args.exceptfds;
bsd_args.tv = linux_args.timeout;
return select(p, &bsd_args, retval);
}
struct linux_getpgid_args {
int pid;
};
int
linux_getpgid(struct proc *p, struct linux_getpgid_args *args, int *retval)
{
struct proc *curproc;
#ifdef DEBUG
printf("Linux-emul(%d): getpgid(%d)\n", p->p_pid, args->pid);
#endif
if (args->pid != p->p_pid) {
if (!(curproc = pfind(args->pid)))
return ESRCH;
}
else
curproc = p;
*retval = curproc->p_pgid;
return 0;
}
int
linux_fork(struct proc *p, void *args, int *retval)
{
int error;
#ifdef DEBUG
printf("Linux-emul(%d): fork()\n", p->p_pid);
#endif
if (error = fork(p, args, retval))
return error;
if (retval[1] == 1)
retval[0] = 0;
return 0;
}
struct linux_mmap_args {
void *ptr;
};
int
linux_mmap(struct proc *p, struct linux_mmap_args *args, int *retval)
{
struct {
linux_caddr_t addr;
int len;
int prot;
int flags;
int fd;
int pos;
} linux_args;
struct {
caddr_t addr;
size_t len;
int prot;
int flags;
int fd;
long pad;
off_t pos;
} bsd_args;
int error;
if ((error = copyin((caddr_t)args->ptr, (caddr_t)&linux_args,
sizeof(linux_args))))
return error;
#ifdef DEBUG
printf("Linux-emul(%d): mmap(%08x, %d, %d, %08x, %d, %d)\n",
p->p_pid, linux_args.addr, linux_args.len, linux_args.prot,
linux_args.flags, linux_args.fd, linux_args.pos);
#endif
bsd_args.flags = 0;
if (linux_args.flags & LINUX_MAP_SHARED)
bsd_args.flags |= MAP_SHARED;
if (linux_args.flags & LINUX_MAP_PRIVATE)
bsd_args.flags |= MAP_PRIVATE;
if (linux_args.flags & LINUX_MAP_FIXED)
bsd_args.flags |= MAP_FIXED;
if (linux_args.flags & LINUX_MAP_ANON)
bsd_args.flags |= MAP_ANON;
bsd_args.addr = linux_args.addr;
bsd_args.len = linux_args.len;
bsd_args.prot = linux_args.prot;
bsd_args.fd = linux_args.fd;
bsd_args.pos = linux_args.pos;
bsd_args.pad = 0;
return mmap(p, &bsd_args, retval);
}
struct linux_pipe_args {
int *pipefds;
};
int
linux_pipe(struct proc *p, struct linux_pipe_args *args, int *retval)
{
int error;
#ifdef DEBUG
printf("Linux-emul(%d): pipe(*)\n", p->p_pid);
#endif
if (error = pipe(p, 0, retval))
return error;
if (error = copyout(retval, args->pipefds, 2*sizeof(int)))
return error;
*retval = 0;
return 0;
}
struct linux_time_args {
linux_time_t *tm;
};
int
linux_time(struct proc *p, struct linux_time_args *args, int *retval)
{
struct timeval tv;
linux_time_t tm;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): time(*)\n", p->p_pid);
#endif
microtime(&tv);
tm = tv.tv_sec;
if (error = copyout(&tm, args->tm, sizeof(linux_time_t)))
return error;
*retval = tv.tv_sec;
return 0;
}
struct linux_tms {
long tms_utime;
long tms_stime;
long tms_cutime;
long tms_cstime;
};
struct linux_tms_args {
char *buf;
};
int
linux_times(struct proc *p, struct linux_tms_args *args, int *retval)
{
extern int hz;
struct timeval tv;
struct linux_tms tms;
#ifdef DEBUG
printf("Linux-emul(%d): times(*)\n", p->p_pid);
#endif
tms.tms_utime = p->p_uticks;
tms.tms_stime = p->p_sticks;
tms.tms_cutime = p->p_stats->p_cru.ru_utime.tv_sec * hz +
((p->p_stats->p_cru.ru_utime.tv_usec * hz)/1000000);
tms.tms_cstime = p->p_stats->p_cru.ru_stime.tv_sec * hz +
((p->p_stats->p_cru.ru_stime.tv_usec * hz)/1000000);
microtime(&tv);
*retval = tv.tv_sec * hz + (tv.tv_usec * hz)/1000000;
return (copyout((caddr_t)&tms, (caddr_t)args->buf,
sizeof(struct linux_tms)));
}
struct linux_newuname_t {
char sysname[65];
char nodename[65];
char release[65];
char version[65];
char machine[65];
char domainname[65];
};
struct linux_newuname_args {
char *buf;
};
int
linux_newuname(struct proc *p, struct linux_newuname_args *args, int *retval)
{
struct linux_newuname_t linux_newuname;
extern char ostype[], osrelease[], machine[];
extern char hostname[], domainname[];
#ifdef DEBUG
printf("Linux-emul(%d): newuname(*)\n", p->p_pid);
#endif
bzero(&linux_newuname, sizeof(struct linux_newuname_args));
strncpy(linux_newuname.sysname, ostype, 64);
strncpy(linux_newuname.nodename, hostname, 64);
strncpy(linux_newuname.release, osrelease, 64);
strncpy(linux_newuname.version, version, 64);
strncpy(linux_newuname.machine, machine, 64);
strncpy(linux_newuname.domainname, domainname, 64);
return (copyout((caddr_t)&linux_newuname, (caddr_t)args->buf,
sizeof(struct linux_newuname_t)));
}
struct linux_utime_args {
char *fname;
linux_time_t *timeptr;
};
int
linux_utime(struct proc *p, struct linux_utime_args *args, int *retval)
{
struct bsd_utimes_args {
char *fname;
struct timeval *tptr;
} bsdutimes;
struct timeval tv;
#ifdef DEBUG
printf("Linux-emul(%d): utime(%s, *)\n", p->p_pid, args->fname);
#endif
tv.tv_sec = (long)args->timeptr;
tv.tv_usec = 0;
bsdutimes.tptr = &tv;
bsdutimes.fname = args->fname;
return utimes(p, &bsdutimes, retval);
}
struct linux_waitpid_args {
int pid;
int *status;
int options;
};
int
linux_waitpid(struct proc *p, struct linux_waitpid_args *args, int *retval)
{
struct wait4_args {
int pid;
int *status;
int options;
struct rusage *rusage;
int compat;
} tmp;
int error, tmpstat;
#ifdef DEBUG
printf("Linux-emul(%d): waitpid(%d, *, %d)\n",
p->p_pid, args->pid, args->options);
#endif
tmp.pid = args->pid;
tmp.status = args->status;
tmp.options = args->options;
tmp.rusage = NULL;
tmp.compat = 0;
if (error = wait4(p, &tmp, retval))
return error;
if (error = copyin(args->status, &tmpstat, sizeof(int)))
return error;
if (WIFSIGNALED(tmpstat))
tmpstat = (tmpstat & 0xffffff80) |
bsd_to_linux_signal[WTERMSIG(tmpstat)];
else if (WIFSTOPPED(tmpstat))
tmpstat = (tmpstat & 0xffff00ff) |
(bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8);
return copyout(&tmpstat, args->status, sizeof(int));
}
struct linux_wait4_args {
int pid;
int *status;
int options;
struct rusage *rusage;
};
int
linux_wait4(struct proc *p, struct linux_wait4_args *args, int *retval)
{
struct wait4_args {
int pid;
int *status;
int options;
struct rusage *rusage;
int compat;
} tmp;
int error, tmpstat;
#ifdef DEBUG
printf("Linux-emul(%d): wait4(%d, *, %d, *)\n",
p->p_pid, args->pid, args->options);
#endif
tmp.pid = args->pid;
tmp.status = args->status;
tmp.options = args->options;
tmp.rusage = args->rusage;
tmp.compat = 0;
if (error = wait4(p, &tmp, retval))
return error;
if (error = copyin(args->status, &tmpstat, sizeof(int)))
return error;
if (WIFSIGNALED(tmpstat))
tmpstat = (tmpstat & 0xffffff80) |
bsd_to_linux_signal[WTERMSIG(tmpstat)];
else if (WIFSTOPPED(tmpstat))
tmpstat = (tmpstat & 0xffff00ff) |
(bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8);
return copyout(&tmpstat, args->status, sizeof(int));
}

View File

@ -0,0 +1,259 @@
/*-
* Copyright (c) 1994-1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux_signal.c,v 1.2 1995/06/07 21:27:57 sos Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/exec.h>
#include <sys/signal.h>
#include <sys/signalvar.h>
#include <vm/vm.h>
#include <i386/linux/linux.h>
#define DONTMASK (sigmask(SIGKILL)|sigmask(SIGSTOP)|sigmask(SIGCHLD))
static sigset_t
linux_to_bsd_sigmask(linux_sigset_t mask) {
int i;
sigset_t new = 0;
for (i = 1; i <= LINUX_NSIG; i++)
if (mask & (1 << i-1))
new |= (1 << (linux_to_bsd_signal[i]-1));
return new;
}
static linux_sigset_t
bsd_to_linux_sigmask(sigset_t mask) {
int i;
sigset_t new = 0;
for (i = 1; i <= NSIG; i++)
if (mask & (1 << i-1))
new |= (1 << (bsd_to_linux_signal[i]-1));
return new;
}
struct linux_sigaction_args {
int sig;
linux_sigaction_t *nsa;
linux_sigaction_t *osa;
};
int
linux_sigaction(struct proc *p, struct linux_sigaction_args *args, int *retval)
{
linux_sigaction_t linux_sa;
struct sigaction *nsa = NULL, *osa = NULL, bsd_sa;
struct sigaction_args {
int sig;
struct sigaction *nsa;
struct sigaction *osa;
} sa;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): sigaction(%d, *, *)\n", p->p_pid, args->sig);
#endif
if (args->osa)
osa = (struct sigaction *)ua_alloc_init(sizeof(struct sigaction));
if (args->nsa) {
nsa = (struct sigaction *)ua_alloc(sizeof(struct sigaction));
if (error = copyin(args->nsa, &linux_sa, sizeof(linux_sigaction_t)))
return error;
bsd_sa.sa_mask = linux_to_bsd_sigmask(linux_sa.sa_mask);
bsd_sa.sa_handler = linux_sa.sa_handler;
bsd_sa.sa_flags = 0;
if (linux_sa.sa_flags & LINUX_SA_NOCLDSTOP)
bsd_sa.sa_flags |= SA_NOCLDSTOP;
if (linux_sa.sa_flags & LINUX_SA_ONSTACK)
bsd_sa.sa_flags |= SA_ONSTACK;
if (linux_sa.sa_flags & LINUX_SA_RESTART)
bsd_sa.sa_flags |= SA_RESTART;
if (error = copyout(&bsd_sa, nsa, sizeof(struct sigaction)))
return error;
}
sa.sig = linux_to_bsd_signal[args->sig];
sa.nsa = nsa;
sa.osa = osa;
if ((error = sigaction(p, &sa, retval)))
return error;
if (args->osa) {
if (error = copyin(osa, &bsd_sa, sizeof(struct sigaction)))
return error;
linux_sa.sa_handler = bsd_sa.sa_handler;
linux_sa.sa_restorer = NULL;
linux_sa.sa_mask = bsd_to_linux_sigmask(bsd_sa.sa_mask);
linux_sa.sa_flags = 0;
if (bsd_sa.sa_flags & SA_NOCLDSTOP)
linux_sa.sa_flags |= LINUX_SA_NOCLDSTOP;
if (bsd_sa.sa_flags & SA_ONSTACK)
linux_sa.sa_flags |= LINUX_SA_ONSTACK;
if (bsd_sa.sa_flags & SA_RESTART)
linux_sa.sa_flags |= LINUX_SA_RESTART;
if (error = copyout(&linux_sa, args->osa, sizeof(linux_sigaction_t)))
return error;
}
return 0;
}
struct linux_sigprocmask_args {
int how;
linux_sigset_t *mask;
linux_sigset_t *omask;
};
int
linux_sigprocmask(struct proc *p, struct linux_sigprocmask_args *args,
int *retval)
{
int error, s;
sigset_t mask;
sigset_t omask;
#ifdef DEBUG
printf("Linux-emul(%d): sigprocmask(%d, *, *)\n", p->p_pid, args->how);
#endif
if (args->omask != NULL) {
omask = bsd_to_linux_sigmask(p->p_sigmask);
if (error = copyout(&omask, args->omask, sizeof(sigset_t)))
return error;
}
if (!(args->mask))
return 0;
if (error = copyin(args->mask, &mask, sizeof(linux_sigset_t)))
return error;
mask = linux_to_bsd_sigmask(mask);
s = splhigh();
switch (args->how) {
case LINUX_SIG_BLOCK:
p->p_sigmask |= (mask & ~DONTMASK);
break;
case LINUX_SIG_UNBLOCK:
p->p_sigmask &= ~mask;
break;
case LINUX_SIG_SETMASK:
p->p_sigmask = (mask & ~DONTMASK);
break;
default:
error = EINVAL;
break;
}
splx(s);
return error;
}
int
linux_siggetmask(struct proc *p, void *args, int *retval)
{
#ifdef DEBUG
printf("Linux-emul(%d): siggetmask()\n", p->p_pid);
#endif
*retval = bsd_to_linux_sigmask(p->p_sigmask);
return 0;
}
struct linux_sigsetmask_args {
linux_sigset_t mask;
};
int
linux_sigsetmask(struct proc *p, struct linux_sigsetmask_args *args,int *retval)
{
int s;
#ifdef DEBUG
printf("Linux-emul(%d): sigsetmask(%08x)\n", p->p_pid, args->mask);
#endif
s = splhigh();
p->p_sigmask = (linux_to_bsd_sigmask(args->mask) & ~DONTMASK);
splx(s);
*retval = bsd_to_linux_sigmask(p->p_sigmask);
return 0;
}
struct linux_sigpending_args {
linux_sigset_t *mask;
};
int
linux_sigpending(struct proc *p, struct linux_sigpending_args *args,int *retval)
{
linux_sigset_t linux_sig;
#ifdef DEBUG
printf("Linux-emul(%d): sigpending(*)\n", p->p_pid);
#endif
linux_sig = bsd_to_linux_sigmask(p->p_siglist & p->p_sigmask);
return copyout(&linux_sig, args->mask, sizeof(linux_sig));
}
struct linux_sigsuspend_args {
linux_sigset_t mask;
};
int
linux_sigsuspend(struct proc *p, struct linux_sigsuspend_args *args,int *retval)
{
sigset_t tmp;
#ifdef DEBUG
printf("Linux-emul(%d): sigsuspend(%08x)\n", p->p_pid, args->mask);
#endif
tmp = linux_to_bsd_sigmask(args->mask);
return sigsuspend(p, &tmp , retval);
}
struct linux_kill_args {
int pid;
int signum;
};
int
linux_kill(struct proc *p, struct linux_kill_args *args, int *retval)
{
struct {
int pid;
int signum;
} tmp;
#ifdef DEBUG
printf("Linux-emul(%d): kill(%d, %d)\n",
p->p_pid, args->pid, args->signum);
#endif
tmp.pid = args->pid;
tmp.signum = linux_to_bsd_signal[args->signum];
return kill(p, &tmp, retval);
}

View File

@ -0,0 +1,595 @@
/*-
* Copyright (c) 1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux_socket.c,v 1.2 1995/06/07 21:27:57 sos Exp $
*/
#include <i386/linux/linux.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <netinet/in.h>
static int
linux_to_bsd_domain(int domain)
{
switch (domain) {
case LINUX_AF_UNSPEC:
return AF_UNSPEC;
case LINUX_AF_UNIX:
return AF_LOCAL;
case LINUX_AF_INET:
return AF_INET;
case LINUX_AF_AX25:
return AF_CCITT;
case LINUX_AF_IPX:
return AF_IPX;
case LINUX_AF_APPLETALK:
return AF_APPLETALK;
default:
return -1;
}
}
static int
linux_to_bsd_sockopt_level(int level)
{
switch (level) {
case LINUX_SOL_SOCKET:
return SOL_SOCKET;
default:
return level;
}
}
static int linux_to_bsd_ip_sockopt(int opt)
{
switch (opt) {
case LINUX_IP_TOS:
return IP_TOS;
case LINUX_IP_TTL:
return IP_TTL;
default:
return -1;
}
}
static int
linux_to_bsd_so_sockopt(int opt)
{
switch (opt) {
case LINUX_SO_DEBUG:
return SO_DEBUG;
case LINUX_SO_REUSEADDR:
return SO_REUSEADDR;
case LINUX_SO_TYPE:
return SO_TYPE;
case LINUX_SO_ERROR:
return SO_ERROR;
case LINUX_SO_DONTROUTE:
return SO_DONTROUTE;
case LINUX_SO_BROADCAST:
return SO_BROADCAST;
case LINUX_SO_SNDBUF:
return SO_SNDBUF;
case LINUX_SO_RCVBUF:
return SO_RCVBUF;
case LINUX_SO_KEEPALIVE:
return SO_KEEPALIVE;
case LINUX_SO_OOBINLINE:
return SO_OOBINLINE;
case LINUX_SO_LINGER:
return SO_LINGER;
case LINUX_SO_PRIORITY:
case LINUX_SO_NO_CHECK:
default:
return -1;
}
}
struct linux_socket_args {
int domain;
int type;
int protocol;
};
static int
linux_socket(struct proc *p, struct linux_socket_args *args, int *retval)
{
struct linux_socket_args linux_args;
struct {
int domain;
int type;
int protocol;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.protocol = linux_args.protocol;
bsd_args.type = linux_args.type;
bsd_args.domain = linux_to_bsd_domain(linux_args.domain);
if (bsd_args.domain == -1)
return EINVAL;
return socket(p, &bsd_args, retval);
}
struct linux_bind_args {
int s;
struct sockaddr *name;
int namelen;
};
static int
linux_bind(struct proc *p, struct linux_bind_args *args, int *retval)
{
struct linux_bind_args linux_args;
struct {
int s;
caddr_t name;
int namelen;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.name = (caddr_t)linux_args.name;
bsd_args.namelen = linux_args.namelen;
return bind(p, &bsd_args, retval);
}
struct linux_connect_args {
int s;
struct sockaddr * name;
int namelen;
};
static int
linux_connect(struct proc *p, struct linux_connect_args *args, int *retval)
{
struct linux_connect_args linux_args;
struct {
int s;
caddr_t name;
int namelen;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.name = (caddr_t)linux_args.name;
bsd_args.namelen = linux_args.namelen;
return connect(p, &bsd_args, retval);
}
struct linux_listen_args {
int s;
int backlog;
};
static int
linux_listen(struct proc *p, struct linux_listen_args *args, int *retval)
{
struct linux_listen_args linux_args;
struct {
int s;
int backlog;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.backlog = linux_args.backlog;
return listen(p, &bsd_args, retval);
}
struct linux_accept_args {
int s;
struct sockaddr *addr;
int *namelen;
};
static int
linux_accept(struct proc *p, struct linux_accept_args *args, int *retval)
{
struct linux_accept_args linux_args;
struct accept_args {
int s;
caddr_t name;
int *anamelen;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.name = (caddr_t)linux_args.addr;
bsd_args.anamelen = linux_args.namelen;
return oaccept(p, &bsd_args, retval);
}
struct linux_getsockname_args {
int s;
struct sockaddr *addr;
int *namelen;
};
static int
linux_getsockname(struct proc *p, struct linux_getsockname_args *args, int *retval)
{
struct linux_getsockname_args linux_args;
struct {
int fdes;
caddr_t asa;
int *alen;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.fdes = linux_args.s;
bsd_args.asa = (caddr_t) linux_args.addr;
bsd_args.alen = linux_args.namelen;
return ogetsockname(p, &bsd_args, retval);
}
struct linux_getpeername_args {
int s;
struct sockaddr *addr;
int *namelen;
};
static int
linux_getpeername(struct proc *p, struct linux_getpeername_args *args, int *retval)
{
struct linux_getpeername_args linux_args;
struct getpeername_args {
int fdes;
caddr_t asa;
int *alen;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.fdes = linux_args.s;
bsd_args.asa = (caddr_t) linux_args.addr;
bsd_args.alen = linux_args.namelen;
return ogetpeername(p, &bsd_args, retval);
}
struct linux_socketpair_args {
int domain;
int type;
int protocol;
int *rsv;
};
static int
linux_socketpair(struct proc *p, struct linux_socketpair_args *args, int *retval)
{
struct linux_socketpair_args linux_args;
struct {
int domain;
int type;
int protocol;
int *rsv;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.domain = linux_to_bsd_domain(linux_args.domain);
if (bsd_args.domain == -1)
return EINVAL;
bsd_args.type = linux_args.type;
bsd_args.protocol = linux_args.protocol;
bsd_args.rsv = linux_args.rsv;
return socketpair(p, &bsd_args, retval);
}
struct linux_send_args {
int s;
void *msg;
int len;
int flags;
};
static int
linux_send(struct proc *p, struct linux_send_args *args, int *retval)
{
struct linux_send_args linux_args;
struct {
int s;
caddr_t buf;
int len;
int flags;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.buf = linux_args.msg;
bsd_args.len = linux_args.len;
bsd_args.flags = linux_args.flags;
return osend(p, &bsd_args, retval);
}
struct linux_recv_args {
int s;
void *msg;
int len;
int flags;
};
static int
linux_recv(struct proc *p, struct linux_recv_args *args, int *retval)
{
struct linux_recv_args linux_args;
struct {
int s;
caddr_t buf;
int len;
int flags;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.buf = linux_args.msg;
bsd_args.len = linux_args.len;
bsd_args.flags = linux_args.flags;
return orecv(p, &bsd_args, retval);
}
struct linux_sendto_args {
int s;
void *msg;
int len;
int flags;
caddr_t to;
int tolen;
};
static int
linux_sendto(struct proc *p, struct linux_sendto_args *args, int *retval)
{
struct linux_sendto_args linux_args;
struct {
int s;
caddr_t buf;
size_t len;
int flags;
caddr_t to;
int tolen;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.buf = linux_args.msg;
bsd_args.len = linux_args.len;
bsd_args.flags = linux_args.flags;
bsd_args.to = linux_args.to;
bsd_args.tolen = linux_args.tolen;
return sendto(p, &bsd_args, retval);
}
struct linux_recvfrom_args {
int s;
void *buf;
int len;
int flags;
caddr_t from;
int *fromlen;
};
static int
linux_recvfrom(struct proc *p, struct linux_recvfrom_args *args, int *retval)
{
struct linux_recvfrom_args linux_args;
struct {
int s;
caddr_t buf;
size_t len;
int flags;
caddr_t from;
int *fromlenaddr;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.buf = linux_args.buf;
bsd_args.len = linux_args.len;
bsd_args.flags = linux_args.flags;
bsd_args.from = linux_args.from;
bsd_args.fromlenaddr = linux_args.fromlen;
return orecvfrom(p, &bsd_args, retval);
}
struct linux_shutdown_args {
int s;
int how;
};
static int
linux_shutdown(struct proc *p, struct linux_shutdown_args *args, int *retval)
{
struct linux_shutdown_args linux_args;
struct {
int s;
int how;
} bsd_args;
int error;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.how = linux_args.how;
return shutdown(p, &bsd_args, retval);
}
struct linux_setsockopt_args {
int s;
int level;
int optname;
void *optval;
int optlen;
};
static int
linux_setsockopt(struct proc *p, struct linux_setsockopt_args *args, int *retval)
{
struct linux_setsockopt_args linux_args;
struct {
int s;
int level;
int name;
caddr_t val;
int valsize;
} bsd_args;
int error, name;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.level = linux_to_bsd_sockopt_level(linux_args.level);
switch (bsd_args.level) {
case SOL_SOCKET:
name = linux_to_bsd_so_sockopt(linux_args.optname);
break;
case IPPROTO_IP:
name = linux_to_bsd_ip_sockopt(linux_args.optname);
break;
default:
return EINVAL;
}
if (name == -1)
return EINVAL;
bsd_args.name = name;
bsd_args.val = linux_args.optval;
bsd_args.valsize = linux_args.optlen;
return setsockopt(p, &bsd_args, retval);
}
struct linux_getsockopt_args {
int s;
int level;
int optname;
void *optval;
int *optlen;
};
static int
linux_getsockopt(struct proc *p, struct linux_getsockopt_args *args, int *retval)
{
struct linux_getsockopt_args linux_args;
struct {
int s;
int level;
int name;
caddr_t val;
int *avalsize;
} bsd_args;
int error, name;
if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
return error;
bsd_args.s = linux_args.s;
bsd_args.level = linux_to_bsd_sockopt_level(linux_args.level);
switch (bsd_args.level) {
case SOL_SOCKET:
name = linux_to_bsd_so_sockopt(linux_args.optname);
break;
case IPPROTO_IP:
name = linux_to_bsd_ip_sockopt(linux_args.optname);
break;
default:
return EINVAL;
}
if (name == -1)
return EINVAL;
bsd_args.val = linux_args.optval;
bsd_args.avalsize = linux_args.optlen;
return getsockopt(p, &bsd_args, retval);
}
struct linux_socketcall_args {
int what;
void *args;
};
int
linux_socketcall(struct proc *p, struct linux_socketcall_args *args,int *retval)
{
switch (args->what) {
case LINUX_SOCKET:
return linux_socket(p, args->args, retval);
case LINUX_BIND:
return linux_bind(p, args->args, retval);
case LINUX_CONNECT:
return linux_connect(p, args->args, retval);
case LINUX_LISTEN:
return linux_listen(p, args->args, retval);
case LINUX_ACCEPT:
return linux_accept(p, args->args, retval);
case LINUX_GETSOCKNAME:
return linux_getsockname(p, args->args, retval);
case LINUX_GETPEERNAME:
return linux_getpeername(p, args->args, retval);
case LINUX_SOCKETPAIR:
return linux_socketpair(p, args->args, retval);
case LINUX_SEND:
return linux_send(p, args->args, retval);
case LINUX_RECV:
return linux_recv(p, args->args, retval);
case LINUX_SENDTO:
return linux_sendto(p, args->args, retval);
case LINUX_RECVFROM:
return linux_recvfrom(p, args->args, retval);
case LINUX_SHUTDOWN:
return linux_shutdown(p, args->args, retval);
case LINUX_SETSOCKOPT:
return linux_setsockopt(p, args->args, retval);
case LINUX_GETSOCKOPT:
return linux_getsockopt(p, args->args, retval);
default:
uprintf("LINUX: 'socket' typ=%d not implemented\n", args->what);
return ENOSYS;
}
}

View File

@ -0,0 +1,273 @@
/*-
* Copyright (c) 1994-1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux_stats.c,v 1.3 1995/06/08 13:50:52 sos Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/dirent.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/proc.h>
#include <sys/mount.h>
#include <sys/namei.h>
#include <sys/stat.h>
#include <sys/vnode.h>
#include <machine/cpu.h>
#include <machine/psl.h>
#include <machine/reg.h>
#include <i386/linux/linux.h>
struct linux_newstat {
unsigned short stat_dev;
unsigned short __pad1;
unsigned long stat_ino;
unsigned short stat_mode;
unsigned short stat_nlink;
unsigned short stat_uid;
unsigned short stat_gid;
unsigned short stat_rdev;
unsigned short __pad2;
unsigned long stat_size;
unsigned long stat_blksize;
unsigned long stat_blocks;
unsigned long stat_atime;
unsigned long __unused1;
unsigned long stat_mtime;
unsigned long __unused2;
unsigned long stat_ctime;
unsigned long __unused3;
unsigned long __unused4;
unsigned long __unused5;
};
struct linux_newstat_args {
char *path;
struct linux_newstat *buf;
};
static int
newstat_copyout(struct stat *buf, void *ubuf)
{
struct linux_newstat tbuf;
tbuf.stat_dev = (buf->st_dev & 0xff) | ((buf->st_dev & 0xff00)<<10);
tbuf.stat_ino = buf->st_ino;
tbuf.stat_mode = buf->st_mode;
tbuf.stat_nlink = buf->st_nlink;
tbuf.stat_uid = buf->st_uid;
tbuf.stat_gid = buf->st_gid;
tbuf.stat_rdev = buf->st_rdev;
tbuf.stat_size = buf->st_size;
tbuf.stat_atime = buf->st_atime;
tbuf.stat_mtime = buf->st_mtime;
tbuf.stat_ctime = buf->st_ctime;
tbuf.stat_blksize = buf->st_blksize;
tbuf.stat_blocks = buf->st_blocks;
return copyout(&tbuf, ubuf, sizeof(tbuf));
}
int
linux_newstat(struct proc *p, struct linux_newstat_args *args, int *retval)
{
struct stat buf;
struct linux_newstat tbuf;
struct nameidata nd;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): newstat(%s, *)\n", p->p_pid, args->path);
#endif
NDINIT(&nd, LOOKUP, LOCKLEAF|FOLLOW, UIO_USERSPACE, args->path, p);
error = namei(&nd);
if (!error) {
error = vn_stat(nd.ni_vp, &buf, p);
vput(nd.ni_vp);
}
if (!error)
error = newstat_copyout(&buf, args->buf);
return error;
}
int
linux_newlstat(struct proc *p, struct linux_newstat_args *args, int *retval)
{
struct stat buf;
struct linux_newstat tbuf;
struct nameidata nd;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): newlstat(%s, *)\n", p->p_pid, args->path);
#endif
NDINIT(&nd, LOOKUP, LOCKLEAF|FOLLOW, UIO_USERSPACE, args->path, p);
error = namei(&nd);
if (!error) {
error = vn_stat(nd.ni_vp, &buf, p);
vput(nd.ni_vp);
}
if (!error)
error = newstat_copyout(&buf, args->buf);
return error;
}
struct linux_newfstat_args {
int fd;
struct linux_newstat *buf;
};
int
linux_newfstat(struct proc *p, struct linux_newfstat_args *args, int *retval)
{
struct linux_newstat tbuf;
struct filedesc *fdp = p->p_fd;
struct file *fp;
struct stat buf;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): newlstat(%d, *)\n", p->p_pid, args->fd);
#endif
if ((unsigned)args->fd >= fdp->fd_nfiles
|| (fp = fdp->fd_ofiles[args->fd]) == NULL)
return EBADF;
switch (fp->f_type) {
case DTYPE_VNODE:
error = vn_stat((struct vnode *)fp->f_data, &buf, p);
break;
case DTYPE_SOCKET:
error = soo_stat((struct socket *)fp->f_data, &buf);
break;
default:
panic("LINUX newfstat");
}
if (!error)
error = newstat_copyout(&buf, args->buf);
return error;
}
struct linux_statfs {
long ftype;
long fbsize;
long fblocks;
long fbfree;
long fbavail;
long ffiles;
long fffree;
linux_fsid_t ffsid;
long fnamelen;
long fspare[6];
};
struct linux_statfs_args {
char *path;
struct statfs *buf;
};
int
linux_statfs(struct proc *p, struct linux_statfs_args *args, int *retval)
{
struct mount *mp;
struct nameidata *ndp;
struct statfs *bsd_statfs;
struct nameidata nd;
struct linux_statfs linux_statfs;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): statfs(%s, *)\n", p->p_pid, args->path);
#endif
ndp = &nd;
ndp->ni_cnd.cn_nameiop = LOOKUP;
ndp->ni_cnd.cn_flags = FOLLOW;
ndp->ni_cnd.cn_proc = curproc;
ndp->ni_cnd.cn_cred = curproc->p_cred->pc_ucred;
ndp->ni_segflg = UIO_USERSPACE;
ndp->ni_dirp = args->path;
if (error = namei(ndp))
return error;
mp = ndp->ni_vp->v_mount;
bsd_statfs = &mp->mnt_stat;
vrele(ndp->ni_vp);
if (error = VFS_STATFS(mp, bsd_statfs, p))
return error;
bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
linux_statfs.ftype = bsd_statfs->f_type;
linux_statfs.fbsize = bsd_statfs->f_bsize;
linux_statfs.fblocks = bsd_statfs->f_blocks;
linux_statfs.fbfree = bsd_statfs->f_bfree;
linux_statfs.fbavail = bsd_statfs->f_bavail;
linux_statfs.fffree = bsd_statfs->f_ffree;
linux_statfs.ffiles = bsd_statfs->f_files;
linux_statfs.ffsid.val[0] = bsd_statfs->f_fsid.val[0];
linux_statfs.ffsid.val[1] = bsd_statfs->f_fsid.val[1];
linux_statfs.fnamelen = MAXNAMLEN;
return copyout((caddr_t)&linux_statfs, (caddr_t)args->buf,
sizeof(struct linux_statfs));
}
struct linux_fstatfs_args {
int fd;
struct statfs *buf;
};
int
linux_fstatfs(struct proc *p, struct linux_fstatfs_args *args, int *retval)
{
struct file *fp;
struct mount *mp;
struct statfs *bsd_statfs;
struct linux_statfs linux_statfs;
int error;
#ifdef DEBUG
printf("Linux-emul(%d): fstatfs(%d, *)\n", p->p_pid, args->fd);
#endif
if (error = getvnode(p->p_fd, args->fd, &fp))
return error;
mp = ((struct vnode *)fp->f_data)->v_mount;
bsd_statfs = &mp->mnt_stat;
if (error = VFS_STATFS(mp, bsd_statfs, p))
return error;
bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
linux_statfs.ftype = bsd_statfs->f_type;
linux_statfs.fbsize = bsd_statfs->f_bsize;
linux_statfs.fblocks = bsd_statfs->f_blocks;
linux_statfs.fbfree = bsd_statfs->f_bfree;
linux_statfs.fbavail = bsd_statfs->f_bavail;
linux_statfs.fffree = bsd_statfs->f_ffree;
linux_statfs.ffiles = bsd_statfs->f_files;
linux_statfs.ffsid.val[0] = bsd_statfs->f_fsid.val[0];
linux_statfs.ffsid.val[1] = bsd_statfs->f_fsid.val[1];
linux_statfs.fnamelen = MAXNAMLEN;
return copyout((caddr_t)&linux_statfs, (caddr_t)args->buf,
sizeof(struct linux_statfs));
}

View File

@ -0,0 +1,367 @@
/*-
* Copyright (c) 1994-1995 Søren Schmidt
* 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 withough 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.
*
* $Id: linux_sysent.c,v 1.3 1995/06/08 13:50:52 sos Exp $
*/
#include <i386/linux/linux.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysent.h>
#include <sys/imgact.h>
#include <sys/errno.h>
#include <sys/signal.h>
extern int access();
extern int acct();
extern int linux_adjtimex();
extern int linux_alarm();
extern int linux_bdflush();
extern int linux_break();
extern int linux_brk();
extern int chdir();
extern int chmod();
extern int chown();
extern int chroot();
extern int linux_clone();
extern int close();
extern int linux_creat();
extern int linux_create_module();
extern int linux_delete_module();
extern int dup();
extern int dup2();
extern int execve();
extern int exit();
extern int fchdir();
extern int fchmod();
extern int fchown();
extern int linux_fcntl();
extern int linux_fork();
extern int linux_fstat();
extern int linux_fstatfs();
extern int fsync();
extern int linux_ftime();
extern int oftruncate();
extern int linux_get_kernel_syms();
extern int getegid();
extern int geteuid();
extern int getgid();
extern int getgroups();
extern int getitimer();
extern int linux_getpgid();
extern int getpgrp();
extern int getpid();
extern int getppid();
extern int getpriority();
extern int ogetrlimit();
extern int getrusage();
extern int gettimeofday();
extern int getuid();
extern int linux_gtty();
extern int linux_idle();
extern int linux_init_module();
extern int linux_ioctl();
extern int linux_ioperm();
extern int linux_iopl();
extern int linux_ipc();
extern int linux_kill();
extern int link();
extern int linux_lock();
extern int linux_lseek();
extern int ostat();
extern int mkdir();
extern int mknod();
extern int linux_mmap();
extern int linux_modify_ldt();
extern int linux_mount();
extern int mprotect();
extern int linux_mpx();
extern int munmap();
extern int linux_newfstat();
extern int linux_newlstat();
extern int linux_newstat();
extern int linux_newuname();
extern int linux_nice();
extern int linux_olduname();
extern int linux_open();
extern int linux_pause();
extern int linux_phys();
extern int linux_pipe();
extern int linux_prof();
extern int profil();
extern int linux_ptrace();
extern int linux_quotactl();
extern int read();
extern int linux_readdir();
extern int readlink();
extern int reboot();
extern int rename();
extern int rmdir();
extern int linux_select();
extern int setdomainname();
extern int setgid();
extern int setgroups();
extern int osethostname();
extern int setitimer();
extern int setpgid();
extern int setpriority();
extern int setregid();
extern int setreuid();
extern int osetrlimit();
extern int setsid();
extern int settimeofday();
extern int setuid();
extern int sigreturn();
extern int linux_setup();
extern int linux_sigaction();
extern int linux_siggetmask();
extern int linux_signal();
extern int linux_sigpending();
extern int linux_sigprocmask();
extern int linux_sigreturn();
extern int linux_sigsetmask();
extern int linux_sigsuspend();
extern int linux_socketcall();
extern int linux_stat();
extern int linux_statfs();
extern int linux_stime();
extern int linux_stty();
extern int linux_swapoff();
extern int swapon();
extern int symlink();
extern int sync();
extern int linux_sysinfo();
extern int linux_syslog();
extern int linux_time();
extern int linux_times();
extern int otruncate();
extern int linux_ulimit();
extern int umask();
extern int linux_umount();
extern int linux_uname();
extern int unlink();
extern int linux_uselib();
extern int linux_ustat();
extern int linux_utime();
extern int linux_vhangup();
extern int linux_vm86();
extern int linux_wait4();
extern int linux_waitpid();
extern int write();
static struct sysent linux_sysent[] = {
0, linux_setup, /* 0 */
1, exit, /* 1 */
0, linux_fork, /* 2 */
3, read, /* 3 */
3, write, /* 4 */
3, linux_open, /* 5 */
1, close, /* 6 */
3, linux_waitpid, /* 7 */
2, linux_creat, /* 8 */
2, link, /* 9 */
1, unlink, /* 10 */
3, execve, /* 11 */
1, chdir, /* 12 */
1, linux_time, /* 13 */
3, mknod, /* 14 */
2, chmod, /* 15 */
3, chown, /* 16 */
1, linux_break, /* 17 */
2, linux_stat, /* 18 */
3, linux_lseek, /* 19 */
0, getpid, /* 20 */
5, linux_mount, /* 21 */
1, linux_umount, /* 22 */
1, setuid, /* 23 */
0, getuid, /* 24 */
1, linux_stime, /* 25 */
4, linux_ptrace, /* 26 */
1, linux_alarm, /* 27 */
2, linux_fstat, /* 28 */
0, linux_pause, /* 29 */
2, linux_utime, /* 30 */
0, linux_stty, /* 31 */
0, linux_gtty, /* 32 */
2, access, /* 33 */
1, linux_nice, /* 34 */
0, linux_ftime, /* 35 */
0, sync, /* 36 */
2, linux_kill, /* 37 */
2, rename, /* 38 */
2, mkdir, /* 39 */
1, rmdir, /* 40 */
1, dup, /* 41 */
1, linux_pipe, /* 42 */
1, linux_times, /* 43 */
0, linux_prof, /* 44 */
1, linux_brk, /* 45 */
1, setgid, /* 46 */
0, getgid, /* 47 */
2, linux_signal, /* 48 */
0, geteuid, /* 49 */
0, getegid, /* 50 */
0, acct, /* 51 */
0, linux_phys, /* 52 */
0, linux_lock, /* 53 */
3, linux_ioctl, /* 54 */
3, linux_fcntl, /* 55 */
0, linux_mpx, /* 56 */
2, setpgid, /* 57 */
0, linux_ulimit, /* 58 */
1, linux_olduname, /* 59 */
1, umask, /* 60 */
1, chroot, /* 61 */
2, linux_ustat, /* 62 */
2, dup2, /* 63 */
0, getppid, /* 64 */
0, getpgrp, /* 65 */
0, setsid, /* 66 */
3, linux_sigaction, /* 67 */
0, linux_siggetmask, /* 68 */
1, linux_sigsetmask, /* 69 */
2, setreuid, /* 70 */
2, setregid, /* 71 */
1, linux_sigsuspend, /* 72 */
1, linux_sigpending, /* 73 */
2, osethostname, /* 74 */
2, osetrlimit, /* 75 */
2, ogetrlimit, /* 76 */
2, getrusage, /* 77 */
2, gettimeofday, /* 78 */
2, settimeofday, /* 79 */
2, getgroups, /* 80 */
2, setgroups, /* 81 */
1, linux_select, /* 82 */
2, symlink, /* 83 */
2, ostat, /* 84 */
3, readlink, /* 85 */
1, linux_uselib, /* 86 */
1, swapon, /* 87 */
3, reboot, /* 88 */
3, linux_readdir, /* 89 */
1, linux_mmap, /* 90 */
2, munmap, /* 91 */
2, otruncate, /* 92 */
2, oftruncate, /* 93 */
2, fchmod, /* 94 */
3, fchown, /* 95 */
2, getpriority, /* 96 */
3, setpriority, /* 97 */
0, profil, /* 98 */
2, linux_statfs, /* 99 */
2, linux_fstatfs, /* 100 */
3, linux_ioperm, /* 101 */
2, linux_socketcall, /* 102 */
3, linux_syslog, /* 103 */
3, setitimer, /* 104 */
2, getitimer, /* 105 */
2, linux_newstat, /* 106 */
2, linux_newlstat, /* 107 */
2, linux_newfstat, /* 108 */
2, linux_uname, /* 109 */
1, linux_iopl, /* 110 */
0, linux_vhangup, /* 111 */
0, linux_idle, /* 112 */
1, linux_vm86, /* 113 */
4, linux_wait4, /* 114 */
1, linux_swapoff, /* 115 */
1, linux_sysinfo, /* 116 */
4, linux_ipc, /* 117 */
1, fsync, /* 118 */
1, linux_sigreturn, /* 119 */
0, linux_clone, /* 120 */
2, setdomainname, /* 121 */
1, linux_newuname, /* 122 */
3, linux_modify_ldt, /* 123 */
1, linux_adjtimex, /* 124 */
3, mprotect, /* 125 */
3, linux_sigprocmask, /* 126 */
2, linux_create_module, /* 127 */
4, linux_init_module, /* 128 */
1, linux_delete_module, /* 129 */
1, linux_get_kernel_syms, /* 130 */
0, linux_quotactl, /* 131 */
1, linux_getpgid, /* 132 */
1, fchdir, /* 133 */
0, linux_bdflush, /* 134 */
};
int bsd_to_linux_errno[ELAST] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 35, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 11,115,114, 88, 89,
90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
100,101,102,103,104,105,106,107,108,109,
110,111, 40, 36,112,113, 39, 11, 87,122,
116, 66, 6, 6, 6, 6, 6, 37, 38, 9,
6,
};
int bsd_to_linux_signal[NSIG] = {
0, LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT,
LINUX_SIGILL, LINUX_SIGTRAP, LINUX_SIGABRT, 0,
LINUX_SIGFPE, LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV,
0, LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM,
LINUX_SIGURG, LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT,
LINUX_SIGCHLD, LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO,
LINUX_SIGXCPU, LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF,
LINUX_SIGWINCH, 0, LINUX_SIGUSR1, LINUX_SIGUSR2
};
int linux_to_bsd_signal[LINUX_NSIG] = {
0, SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGEMT,
SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM,
SIGBUS, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGIO,
SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, SIGURG, SIGURG, 0
};
int linux_fixup(int **stack_base, struct image_params *iparams)
{
int *argv, *envp;
argv = *stack_base;
envp = *stack_base + (iparams->argc + 1);
(*stack_base)--;
**stack_base = (int)envp;
(*stack_base)--;
**stack_base = (int)argv;
(*stack_base)--;
**stack_base = (int)iparams->argc;
}
struct sysentvec linux_sysvec = {
sizeof (linux_sysent) / sizeof(linux_sysent[0]),
linux_sysent,
0xff,
NSIG,
bsd_to_linux_signal,
ELAST,
bsd_to_linux_errno,
linux_fixup
};

View File

@ -1,7 +1,7 @@
# $Id: Makefile,v 1.9 1995/03/20 19:25:38 wollman Exp $
# $Id: Makefile,v 1.10 1995/06/13 20:51:13 wollman Exp $
SUBDIR= cd9660 coff fdesc ibcs2 if_disc if_ppp if_sl if_tun \
ipfw kernfs msdos nfs nullfs \
ipfw kernfs linux msdos nfs nullfs \
portal procfs socksys syscons umapfs union
#
# Doesn't work:

View File

@ -0,0 +1,16 @@
# $Id$
.PATH: ${.CURDIR}/../../sys/i386/linux
KMOD= linux_mod
SRCS= linux.c linux_file.c linux_ioctl.c linux_misc.c linux_signal.c \
linux_generic.c linux_ipc.c linux_socket.c linux_stats.c \
linux_dummy.c linux_sysent.c imgact_linux.c vnode_if.h
NOMAN=
CFLAGS+= -DLKM -I. -DCOMPAT_LINUX -DSYSVSHM #-DSYSVMSG -DSYSVSEM #-DDEBUG
CLEANFILES+= vnode_if.h vnode_if.c
afterinstall:
${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
${.CURDIR}/linux /usr/bin
.include <bsd.kmod.mk>

3
sys/modules/linux/linux Normal file
View File

@ -0,0 +1,3 @@
#!/bin/sh
# $Id$
modload -e linux_init /lkm/linux_mod.o

58
sys/modules/linux/linux.c Normal file
View File

@ -0,0 +1,58 @@
/*-
* Copyright (c) 1994 Søren Schmidt
* 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 withough 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.
*
* $Id: linux.c,v 1.1 1994/10/14 08:46:12 sos Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/exec.h>
#include <sys/conf.h>
#include <sys/sysent.h>
#include <sys/lkm.h>
#include <sys/errno.h>
extern const struct execsw linux_execsw;
MOD_EXEC("linux_emulator", -1, (struct execsw*)&linux_execsw)
linux_load(struct lkm_table *lkmtp, int cmd)
{
uprintf("Linux emulator installed\n");
return 0;
}
linux_unload(struct lkm_table *lkmtp, int cmd)
{
uprintf("Linux emulator removed\n");
return 0;
}
linux_init(struct lkm_table *lkmtp, int cmd, int ver)
{
DISPATCH(lkmtp, cmd, ver, linux_load, linux_unload, nosys);
}

View File

@ -0,0 +1,3 @@
#!/bin/sh
# $Id$
modload -e linux_init /lkm/linux_mod.o