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:
parent
0f72d204e6
commit
c21dee177f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=9313
@ -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
16
lkm/linux/Makefile
Normal 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
3
lkm/linux/linux
Normal file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
# $Id$
|
||||
modload -e linux_init /lkm/linux_mod.o
|
58
lkm/linux/linux.c
Normal file
58
lkm/linux/linux.c
Normal 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
406
sys/alpha/linux/linux.h
Normal 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 */
|
316
sys/alpha/linux/linux_dummy.c
Normal file
316
sys/alpha/linux/linux_dummy.c
Normal 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/compat/linux/linux_file.c
Normal file
436
sys/compat/linux/linux_file.c
Normal 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;
|
||||
}
|
495
sys/compat/linux/linux_ioctl.c
Normal file
495
sys/compat/linux/linux_ioctl.c
Normal 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/compat/linux/linux_ipc.c
Normal file
308
sys/compat/linux/linux_ipc.c
Normal 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/compat/linux/linux_misc.c
Normal file
660
sys/compat/linux/linux_misc.c
Normal 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));
|
||||
}
|
259
sys/compat/linux/linux_signal.c
Normal file
259
sys/compat/linux/linux_signal.c
Normal 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);
|
||||
}
|
595
sys/compat/linux/linux_socket.c
Normal file
595
sys/compat/linux/linux_socket.c
Normal 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;
|
||||
}
|
||||
}
|
273
sys/compat/linux/linux_stats.c
Normal file
273
sys/compat/linux/linux_stats.c
Normal 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));
|
||||
}
|
235
sys/i386/linux/imgact_linux.c
Normal file
235
sys/i386/linux/imgact_linux.c
Normal 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
406
sys/i386/linux/linux.h
Normal 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 */
|
316
sys/i386/linux/linux_dummy.c
Normal file
316
sys/i386/linux/linux_dummy.c
Normal 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
436
sys/i386/linux/linux_file.c
Normal 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;
|
||||
}
|
63
sys/i386/linux/linux_generic.c
Normal file
63
sys/i386/linux/linux_generic.c
Normal 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;
|
||||
}
|
495
sys/i386/linux/linux_ioctl.c
Normal file
495
sys/i386/linux/linux_ioctl.c
Normal 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
308
sys/i386/linux/linux_ipc.c
Normal 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
660
sys/i386/linux/linux_misc.c
Normal 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));
|
||||
}
|
259
sys/i386/linux/linux_signal.c
Normal file
259
sys/i386/linux/linux_signal.c
Normal 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);
|
||||
}
|
595
sys/i386/linux/linux_socket.c
Normal file
595
sys/i386/linux/linux_socket.c
Normal 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;
|
||||
}
|
||||
}
|
273
sys/i386/linux/linux_stats.c
Normal file
273
sys/i386/linux/linux_stats.c
Normal 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));
|
||||
}
|
367
sys/i386/linux/linux_sysent.c
Normal file
367
sys/i386/linux/linux_sysent.c
Normal 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
|
||||
};
|
@ -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
sys/modules/linux/Makefile
Normal file
16
sys/modules/linux/Makefile
Normal 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
3
sys/modules/linux/linux
Normal file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
# $Id$
|
||||
modload -e linux_init /lkm/linux_mod.o
|
58
sys/modules/linux/linux.c
Normal file
58
sys/modules/linux/linux.c
Normal 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);
|
||||
}
|
3
sys/modules/linux/linux.sh
Normal file
3
sys/modules/linux/linux.sh
Normal file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
# $Id$
|
||||
modload -e linux_init /lkm/linux_mod.o
|
Loading…
Reference in New Issue
Block a user