diff options
author | marcel <marcel@FreeBSD.org> | 2000-08-22 07:08:33 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2000-08-22 07:08:33 +0000 |
commit | af4eb9aac2a75741dae47076b24d02939bd6adc3 (patch) | |
tree | 12475e8050c1b54600e1ef53318663524b202453 | |
parent | 4b9a3820dd5819191229e63c4815676dda015796 (diff) | |
download | FreeBSD-src-af4eb9aac2a75741dae47076b24d02939bd6adc3.zip FreeBSD-src-af4eb9aac2a75741dae47076b24d02939bd6adc3.tar.gz |
Finish the Linuxulator MD/MI split.
In summary:
o This file has been moved to sys/compat/linux,
o Any MD syscalls in this file are moved to
linux_machdep.c in sys/i386/linux,
o Include directives, makefiles and config files
have been updated.
-rw-r--r-- | sys/alpha/linux/linux_ioctl.h | 437 | ||||
-rw-r--r-- | sys/i386/linux/linux_file.c | 879 | ||||
-rw-r--r-- | sys/i386/linux/linux_ioctl.c | 1529 | ||||
-rw-r--r-- | sys/i386/linux/linux_ioctl.h | 437 | ||||
-rw-r--r-- | sys/i386/linux/linux_ipc.c | 490 | ||||
-rw-r--r-- | sys/i386/linux/linux_mib.c | 231 | ||||
-rw-r--r-- | sys/i386/linux/linux_mib.h | 43 | ||||
-rw-r--r-- | sys/i386/linux/linux_misc.c | 1470 | ||||
-rw-r--r-- | sys/i386/linux/linux_signal.c | 555 | ||||
-rw-r--r-- | sys/i386/linux/linux_socket.c | 874 | ||||
-rw-r--r-- | sys/i386/linux/linux_stats.c | 378 | ||||
-rw-r--r-- | sys/i386/linux/linux_util.c | 187 | ||||
-rw-r--r-- | sys/i386/linux/linux_util.h | 95 |
13 files changed, 0 insertions, 7605 deletions
diff --git a/sys/alpha/linux/linux_ioctl.h b/sys/alpha/linux/linux_ioctl.h deleted file mode 100644 index e20a34f..0000000 --- a/sys/alpha/linux/linux_ioctl.h +++ /dev/null @@ -1,437 +0,0 @@ -/*- - * Copyright (c) 1999 Marcel Moolenaar - * 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. - * - * $FreeBSD$ - */ - -#ifndef _LINUX_IOCTL_H_ -#define _LINUX_IOCTL_H_ - -/* - * disk - */ -#define LINUX_BLKROSET 0x125d -#define LINUX_BLKROGET 0x125e -#define LINUX_BLKRRPART 0x125f -#define LINUX_BLKGETSIZE 0x1260 -#define LINUX_BLKFLSBUF 0x1261 -#define LINUX_BLKRASET 0x1262 -#define LINUX_BLKRAGET 0x1263 -#define LINUX_BLKFRASET 0x1264 -#define LINUX_BLKFRAGET 0x1265 -#define LINUX_BLKSECTSET 0x1266 -#define LINUX_BLKSECTGET 0x1267 -#define LINUX_BLKSSZGET 0x1268 - -#define LINUX_IOCTL_DISK_MIN LINUX_BLKROSET -#define LINUX_IOCTL_DISK_MAX LINUX_BLKSSZGET - -/* - * cdrom - */ -#define LINUX_CDROMPAUSE 0x5301 -#define LINUX_CDROMRESUME 0x5302 -#define LINUX_CDROMPLAYMSF 0x5303 -#define LINUX_CDROMPLAYTRKIND 0x5304 -#define LINUX_CDROMREADTOCHDR 0x5305 -#define LINUX_CDROMREADTOCENTRY 0x5306 -#define LINUX_CDROMSTOP 0x5307 -#define LINUX_CDROMSTART 0x5308 -#define LINUX_CDROMEJECT 0x5309 -#define LINUX_CDROMVOLCTRL 0x530a -#define LINUX_CDROMSUBCHNL 0x530b -#define LINUX_CDROMREADMODE2 0x530c -#define LINUX_CDROMREADMODE1 0x530d -#define LINUX_CDROMREADAUDIO 0x530e -#define LINUX_CDROMEJECT_SW 0x530f -#define LINUX_CDROMMULTISESSION 0x5310 -#define LINUX_CDROM_GET_UPC 0x5311 -#define LINUX_CDROMRESET 0x5312 -#define LINUX_CDROMVOLREAD 0x5313 -#define LINUX_CDROMREADRAW 0x5314 -#define LINUX_CDROMREADCOOKED 0x5315 -#define LINUX_CDROMSEEK 0x5316 -#define LINUX_CDROMPLAYBLK 0x5317 -#define LINUX_CDROMREADALL 0x5318 -#define LINUX_CDROMCLOSETRAY 0x5319 -#define LINUX_CDROMLOADFROMSLOT 0x531a - -#define LINUX_IOCTL_CDROM_MIN LINUX_CDROMPAUSE -#define LINUX_IOCTL_CDROM_MAX LINUX_CDROMLOADFROMSLOT - -#define LINUX_CDROM_LBA 0x01 -#define LINUX_CDROM_MSF 0x02 - -/* - * console - */ -#define LINUX_KIOCSOUND 0x4B2F -#define LINUX_KDMKTONE 0x4B30 -#define LINUX_KDGETLED 0x4B31 -#define LINUX_KDSETLED 0x4B32 -#define LINUX_KDSETMODE 0x4B3A -#define LINUX_KDGETMODE 0x4B3B -#define LINUX_KDGKBMODE 0x4B44 -#define LINUX_KDSKBMODE 0x4B45 -#define LINUX_VT_OPENQRY 0x5600 -#define LINUX_VT_GETMODE 0x5601 -#define LINUX_VT_SETMODE 0x5602 -#define LINUX_VT_GETSTATE 0x5603 -#define LINUX_VT_RELDISP 0x5605 -#define LINUX_VT_ACTIVATE 0x5606 -#define LINUX_VT_WAITACTIVE 0x5607 - -#define LINUX_IOCTL_CONSOLE_MIN LINUX_KIOCSOUND -#define LINUX_IOCTL_CONSOLE_MAX LINUX_VT_WAITACTIVE - -#define LINUX_LED_SCR 0x01 -#define LINUX_LED_NUM 0x02 -#define LINUX_LED_CAP 0x04 - -#define LINUX_KD_TEXT 0x0 -#define LINUX_KD_GRAPHICS 0x1 -#define LINUX_KD_TEXT0 0x2 -#define LINUX_KD_TEXT1 0x3 - -#define LINUX_KBD_RAW 0 -#define LINUX_KBD_XLATE 1 -#define LINUX_KBD_MEDIUMRAW 2 - -/* - * socket - */ -#define LINUX_FIOSETOWN 0x8901 -#define LINUX_SIOCSPGRP 0x8902 -#define LINUX_FIOGETOWN 0x8903 -#define LINUX_SIOCGPGRP 0x8904 -#define LINUX_SIOCATMARK 0x8905 -#define LINUX_SIOCGSTAMP 0x8906 -#define LINUX_SIOCGIFCONF 0x8912 -#define LINUX_SIOCGIFFLAGS 0x8913 -#define LINUX_SIOCGIFADDR 0x8915 -#define LINUX_SIOCGIFDSTADDR 0x8917 -#define LINUX_SIOCGIFBRDADDR 0x8919 -#define LINUX_SIOCGIFNETMASK 0x891b -#define LINUX_SIOCGIFHWADDR 0x8927 -#define LINUX_SIOCADDMULTI 0x8931 -#define LINUX_SIOCDELMULTI 0x8932 - -#define LINUX_IOCTL_SOCKET_MIN LINUX_FIOSETOWN -#define LINUX_IOCTL_SOCKET_MAX LINUX_SIOCDELMULTI - -/* - * sound - */ -#define LINUX_SOUND_MIXER_WRITE_VOLUME 0x4d00 -#define LINUX_SOUND_MIXER_WRITE_BASS 0x4d01 -#define LINUX_SOUND_MIXER_WRITE_TREBLE 0x4d02 -#define LINUX_SOUND_MIXER_WRITE_SYNTH 0x4d03 -#define LINUX_SOUND_MIXER_WRITE_PCM 0x4d04 -#define LINUX_SOUND_MIXER_WRITE_SPEAKER 0x4d05 -#define LINUX_SOUND_MIXER_WRITE_LINE 0x4d06 -#define LINUX_SOUND_MIXER_WRITE_MIC 0x4d07 -#define LINUX_SOUND_MIXER_WRITE_CD 0x4d08 -#define LINUX_SOUND_MIXER_WRITE_IMIX 0x4d09 -#define LINUX_SOUND_MIXER_WRITE_ALTPCM 0x4d0A -#define LINUX_SOUND_MIXER_WRITE_RECLEV 0x4d0B -#define LINUX_SOUND_MIXER_WRITE_IGAIN 0x4d0C -#define LINUX_SOUND_MIXER_WRITE_OGAIN 0x4d0D -#define LINUX_SOUND_MIXER_WRITE_LINE1 0x4d0E -#define LINUX_SOUND_MIXER_WRITE_LINE2 0x4d0F -#define LINUX_SOUND_MIXER_WRITE_LINE3 0x4d10 -#define LINUX_OSS_GETVERSION 0x4d76 -#define LINUX_SOUND_MIXER_READ_DEVMASK 0x4dfe -#define LINUX_SNDCTL_DSP_RESET 0x5000 -#define LINUX_SNDCTL_DSP_SYNC 0x5001 -#define LINUX_SNDCTL_DSP_SPEED 0x5002 -#define LINUX_SNDCTL_DSP_STEREO 0x5003 -#define LINUX_SNDCTL_DSP_GETBLKSIZE 0x5004 -#define LINUX_SNDCTL_DSP_SETBLKSIZE LINUX_SNDCTL_DSP_GETBLKSIZE -#define LINUX_SNDCTL_DSP_SETFMT 0x5005 -#define LINUX_SOUND_PCM_WRITE_CHANNELS 0x5006 -#define LINUX_SOUND_PCM_WRITE_FILTER 0x5007 -#define LINUX_SNDCTL_DSP_POST 0x5008 -#define LINUX_SNDCTL_DSP_SUBDIVIDE 0x5009 -#define LINUX_SNDCTL_DSP_SETFRAGMENT 0x500A -#define LINUX_SNDCTL_DSP_GETFMTS 0x500B -#define LINUX_SNDCTL_DSP_GETOSPACE 0x500C -#define LINUX_SNDCTL_DSP_GETISPACE 0x500D -#define LINUX_SNDCTL_DSP_NONBLOCK 0x500E -#define LINUX_SNDCTL_DSP_GETCAPS 0x500F -#define LINUX_SNDCTL_DSP_GETTRIGGER 0x5010 -#define LINUX_SNDCTL_DSP_SETTRIGGER LINUX_SNDCTL_DSP_GETTRIGGER -#define LINUX_SNDCTL_DSP_GETIPTR 0x5011 -#define LINUX_SNDCTL_DSP_GETOPTR 0x5012 -#define LINUX_SNDCTL_DSP_GETODELAY 0x5017 -#define LINUX_SNDCTL_SEQ_RESET 0x5100 -#define LINUX_SNDCTL_SEQ_SYNC 0x5101 -#define LINUX_SNDCTL_SYNTH_INFO 0x5102 -#define LINUX_SNDCTL_SEQ_CTRLRATE 0x5103 -#define LINUX_SNDCTL_SEQ_GETOUTCOUNT 0x5104 -#define LINUX_SNDCTL_SEQ_GETINCOUNT 0x5105 -#define LINUX_SNDCTL_SEQ_PERCMODE 0x5106 -#define LINUX_SNDCTL_FM_LOAD_INSTR 0x5107 -#define LINUX_SNDCTL_SEQ_TESTMIDI 0x5108 -#define LINUX_SNDCTL_SEQ_RESETSAMPLES 0x5109 -#define LINUX_SNDCTL_SEQ_NRSYNTHS 0x510A -#define LINUX_SNDCTL_SEQ_NRMIDIS 0x510B -#define LINUX_SNDCTL_MIDI_INFO 0x510C -#define LINUX_SNDCTL_SEQ_TRESHOLD 0x510D -#define LINUX_SNDCTL_SYNTH_MEMAVL 0x510E - -#define LINUX_IOCTL_SOUND_MIN LINUX_SOUND_MIXER_WRITE_VOLUME -#define LINUX_IOCTL_SOUND_MAX LINUX_SNDCTL_SYNTH_MEMAVL - -/* - * termio - */ -#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 - -#define LINUX_IOCTL_TERMIO_MIN LINUX_TCGETS -#define LINUX_IOCTL_TERMIO_MAX LINUX_TIOCSLCKTRMIOS - -/* arguments for tcflow() and LINUX_TCXONC */ -#define LINUX_TCOOFF 0 -#define LINUX_TCOON 1 -#define LINUX_TCIOFF 2 -#define LINUX_TCION 3 - -/* arguments for tcflush() and LINUX_TCFLSH */ -#define LINUX_TCIFLUSH 0 -#define LINUX_TCOFLUSH 1 -#define LINUX_TCIOFLUSH 2 - -/* 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 19 - -#define LINUX_POSIX_VDISABLE '\0' - -/* 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 - -/* serial_struct values for TIOC[GS]SERIAL ioctls */ -#define LINUX_ASYNC_CLOSING_WAIT_INF 0 -#define LINUX_ASYNC_CLOSING_WAIT_NONE 65535 - -#define LINUX_PORT_UNKNOWN 0 -#define LINUX_PORT_8250 1 -#define LINUX_PORT_16450 2 -#define LINUX_PORT_16550 3 -#define LINUX_PORT_16550A 4 -#define LINUX_PORT_CIRRUS 5 -#define LINUX_PORT_16650 6 - -#define LINUX_PORT_MAX 6 - -#define LINUX_ASYNC_HUP_NOTIFY 0x0001 -#define LINUX_ASYNC_FOURPORT 0x0002 -#define LINUX_ASYNC_SAK 0x0004 -#define LINUX_ASYNC_SPLIT_TERMIOS 0x0008 -#define LINUX_ASYNC_SPD_MASK 0x0030 -#define LINUX_ASYNC_SPD_HI 0x0010 -#define LINUX_ASYNC_SPD_VHI 0x0020 -#define LINUX_ASYNC_SPD_CUST 0x0030 -#define LINUX_ASYNC_SKIP_TEST 0x0040 -#define LINUX_ASYNC_AUTO_IRQ 0x0080 -#define LINUX_ASYNC_SESSION_LOCKOUT 0x0100 -#define LINUX_ASYNC_PGRP_LOCKOUT 0x0200 -#define LINUX_ASYNC_CALLOUT_NOHUP 0x0400 -#define LINUX_ASYNC_FLAGS 0x0FFF - -#endif /* !_LINUX_IOCTL_H_ */ diff --git a/sys/i386/linux/linux_file.c b/sys/i386/linux/linux_file.c deleted file mode 100644 index 2cb2303..0000000 --- a/sys/i386/linux/linux_file.c +++ /dev/null @@ -1,879 +0,0 @@ -/*- - * 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. - * - * $FreeBSD$ - */ - -#include "opt_compat.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/sysproto.h> -#include <sys/fcntl.h> -#include <sys/file.h> -#include <sys/filedesc.h> -#include <sys/lock.h> -#include <sys/proc.h> -#include <sys/vnode.h> -#include <sys/malloc.h> -#include <sys/dirent.h> -#include <sys/conf.h> -#include <sys/tty.h> - -#include <i386/linux/linux.h> -#include <i386/linux/linux_proto.h> -#include <i386/linux/linux_util.h> - -int -linux_creat(struct proc *p, struct linux_creat_args *args) -{ - struct open_args /* { - char *path; - int flags; - int mode; - } */ bsd_open_args; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTCREAT(p, &sg, args->path); - -#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); -} - -int -linux_open(struct proc *p, struct linux_open_args *args) -{ - struct open_args /* { - char *path; - int flags; - int mode; - } */ bsd_open_args; - int error; - caddr_t sg; - - sg = stackgap_init(); - - if (args->flags & LINUX_O_CREAT) - CHECKALTCREAT(p, &sg, args->path); - else - CHECKALTEXIST(p, &sg, args->path); - -#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); - 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[p->p_retval[0]]; - - if (fp->f_type == DTYPE_VNODE) - fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, p); - } -#ifdef DEBUG - printf("Linux-emul(%d): open returns error %d\n", - p->p_pid, error); -#endif - 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; - default: - bsd_flock->l_type = -1; - 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; -} - -int -linux_fcntl(struct proc *p, struct linux_fcntl_args *args) -{ - int error, result; - struct fcntl_args /* { - int fd; - int cmd; - int arg; - } */ fcntl_args; - struct linux_flock linux_flock; - struct flock *bsd_flock; - caddr_t sg; - - sg = stackgap_init(); - bsd_flock = (struct flock *)stackgap_alloc(&sg, 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; - - switch (args->cmd) { - case LINUX_F_DUPFD: - fcntl_args.cmd = F_DUPFD; - fcntl_args.arg = args->arg; - return fcntl(p, &fcntl_args); - - case LINUX_F_GETFD: - fcntl_args.cmd = F_GETFD; - return fcntl(p, &fcntl_args); - - case LINUX_F_SETFD: - fcntl_args.cmd = F_SETFD; - fcntl_args.arg = args->arg; - return fcntl(p, &fcntl_args); - - case LINUX_F_GETFL: - fcntl_args.cmd = F_GETFL; - error = fcntl(p, &fcntl_args); - result = p->p_retval[0]; - p->p_retval[0] = 0; - if (result & O_RDONLY) p->p_retval[0] |= LINUX_O_RDONLY; - if (result & O_WRONLY) p->p_retval[0] |= LINUX_O_WRONLY; - if (result & O_RDWR) p->p_retval[0] |= LINUX_O_RDWR; - if (result & O_NDELAY) p->p_retval[0] |= LINUX_O_NONBLOCK; - if (result & O_APPEND) p->p_retval[0] |= LINUX_O_APPEND; - if (result & O_FSYNC) p->p_retval[0] |= LINUX_O_SYNC; - if (result & O_ASYNC) p->p_retval[0] |= LINUX_FASYNC; - return error; - - case LINUX_F_SETFL: - fcntl_args.arg = 0; - 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; - if (args->arg & LINUX_FASYNC) fcntl_args.arg |= O_ASYNC; - fcntl_args.cmd = F_SETFL; - return fcntl(p, &fcntl_args); - - 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; - error = fcntl(p, &fcntl_args); - if (error) - 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); - - 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); - - case LINUX_F_GETOWN: - fcntl_args.cmd = F_GETOWN; - return fcntl(p, &fcntl_args); - - case LINUX_F_SETOWN: - fcntl_args.cmd = F_SETOWN; - fcntl_args.arg = args->arg; - return fcntl(p, &fcntl_args); - } - return EINVAL; -} - -int -linux_lseek(struct proc *p, struct linux_lseek_args *args) -{ - - struct lseek_args /* { - int fd; - int pad; - off_t offset; - int whence; - } */ tmp_args; - int error; - -#ifdef DEBUG - printf("Linux-emul(%ld): lseek(%d, %ld, %d)\n", - (long)p->p_pid, args->fdes, args->off, args->whence); -#endif - tmp_args.fd = args->fdes; - tmp_args.offset = (off_t)args->off; - tmp_args.whence = args->whence; - error = lseek(p, &tmp_args); - return error; -} - -int -linux_llseek(struct proc *p, struct linux_llseek_args *args) -{ - struct lseek_args bsd_args; - int error; - off_t off; - -#ifdef DEBUG - printf("Linux-emul(%d): llseek(%d, %d:%d, %d)\n", - p->p_pid, args->fd, args->ohigh, args->olow, args->whence); -#endif - off = (args->olow) | (((off_t) args->ohigh) << 32); - - bsd_args.fd = args->fd; - bsd_args.offset = off; - bsd_args.whence = args->whence; - - if ((error = lseek(p, &bsd_args))) - return error; - - if ((error = copyout(p->p_retval, (caddr_t)args->res, sizeof (off_t)))) - return error; - - p->p_retval[0] = 0; - return 0; -} - - -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)) - -int -linux_readdir(struct proc *p, struct linux_readdir_args *args) -{ - struct linux_getdents_args lda; - - lda.fd = args->fd; - lda.dent = args->dent; - lda.count = 1; - return linux_getdents(p, &lda); -} - -int -linux_getdents(struct proc *p, struct linux_getdents_args *args) -{ - 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; - u_long *cookies = NULL, *cookiep; - int ncookies; - -#ifdef DEBUG - printf("Linux-emul(%d): getdents(%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; - - off = fp->f_offset; -#define DIRBLKSIZ 512 /* XXX we used to use ufs's DIRBLKSIZ */ - buflen = max(DIRBLKSIZ, nbytes); - buflen = min(buflen, MAXBSIZE); - buf = malloc(buflen, M_TEMP, M_WAITOK); - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); -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; - - if (cookies) { - free(cookies, M_TEMP); - cookies = NULL; - } - - error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies, &cookies); - if (error) { - goto out; - } - - inp = buf; - outp = (caddr_t) args->dent; - resid = nbytes; - if ((len = buflen - auio.uio_resid) <= 0) { - goto eof; - } - - cookiep = cookies; - - if (cookies) { - /* - * When using cookies, the vfs has the option of reading from - * a different offset than that supplied (UFS truncates the - * offset to a block boundary to make sure that it never reads - * partway through a directory entry, even if the directory - * has been compacted). - */ - while (len > 0 && ncookies > 0 && *cookiep <= off) { - bdp = (struct dirent *) inp; - len -= bdp->d_reclen; - inp += bdp->d_reclen; - cookiep++; - ncookies--; - } - } - - while (len > 0) { - if (cookiep && ncookies == 0) - break; - bdp = (struct dirent *) inp; - reclen = bdp->d_reclen; - if (reclen & 3) { - printf("linux_readdir: reclen=%d\n", reclen); - error = EFAULT; - goto out; - } - - if (bdp->d_fileno == 0) { - inp += reclen; - if (cookiep) { - off = *cookiep++; - ncookies--; - } else - off += reclen; - len -= reclen; - continue; - } - linuxreclen = LINUX_RECLEN(&linux_dirent, bdp->d_namlen); - if (reclen > len || resid < linuxreclen) { - outp++; - break; - } - linux_dirent.dino = (long) bdp->d_fileno; - if (justone) { - /* - * old linux-style readdir usage. - */ - linux_dirent.doff = (linux_off_t) linuxreclen; - linux_dirent.dreclen = (u_short) bdp->d_namlen; - } else { - linux_dirent.doff = (linux_off_t)(off + reclen); - linux_dirent.dreclen = (u_short) linuxreclen; - } - strcpy(linux_dirent.dname, bdp->d_name); - if ((error = copyout((caddr_t)&linux_dirent, outp, linuxreclen))) { - goto out; - } - inp += reclen; - if (cookiep) { - off = *cookiep++; - ncookies--; - } else - off += 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: - p->p_retval[0] = nbytes - resid; -out: - if (cookies) - free(cookies, M_TEMP); - VOP_UNLOCK(vp, 0, p); - free(buf, M_TEMP); - return error; -} - -/* - * These exist mainly for hooks for doing /compat/linux translation. - */ - -int -linux_access(struct proc *p, struct linux_access_args *args) -{ - struct access_args bsd; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTEXIST(p, &sg, args->path); - -#ifdef DEBUG - printf("Linux-emul(%d): access(%s, %d)\n", - p->p_pid, args->path, args->flags); -#endif - bsd.path = args->path; - bsd.flags = args->flags; - - return access(p, &bsd); -} - -int -linux_unlink(struct proc *p, struct linux_unlink_args *args) -{ - struct unlink_args bsd; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTEXIST(p, &sg, args->path); - -#ifdef DEBUG - printf("Linux-emul(%d): unlink(%s)\n", - p->p_pid, args->path); -#endif - bsd.path = args->path; - - return unlink(p, &bsd); -} - -int -linux_chdir(struct proc *p, struct linux_chdir_args *args) -{ - struct chdir_args bsd; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTEXIST(p, &sg, args->path); - -#ifdef DEBUG - printf("Linux-emul(%d): chdir(%s)\n", - p->p_pid, args->path); -#endif - bsd.path = args->path; - - return chdir(p, &bsd); -} - -int -linux_chmod(struct proc *p, struct linux_chmod_args *args) -{ - struct chmod_args bsd; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTEXIST(p, &sg, args->path); - -#ifdef DEBUG - printf("Linux-emul(%d): chmod(%s, %d)\n", - p->p_pid, args->path, args->mode); -#endif - bsd.path = args->path; - bsd.mode = args->mode; - - return chmod(p, &bsd); -} - -int -linux_chown(struct proc *p, struct linux_chown_args *args) -{ - struct chown_args bsd; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTEXIST(p, &sg, args->path); - -#ifdef DEBUG - printf("Linux-emul(%d): chown(%s, %d, %d)\n", - p->p_pid, args->path, args->uid, args->gid); -#endif - bsd.path = args->path; - /* XXX size casts here */ - bsd.uid = args->uid; - bsd.gid = args->gid; - - return chown(p, &bsd); -} - -int -linux_lchown(struct proc *p, struct linux_lchown_args *args) -{ - struct lchown_args bsd; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTEXIST(p, &sg, args->path); - -#ifdef DEBUG - printf("Linux-emul(%d): lchown(%s, %d, %d)\n", - p->p_pid, args->path, args->uid, args->gid); -#endif - bsd.path = args->path; - /* XXX size casts here */ - bsd.uid = args->uid; - bsd.gid = args->gid; - - return lchown(p, &bsd); -} - -int -linux_mkdir(struct proc *p, struct linux_mkdir_args *args) -{ - struct mkdir_args bsd; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTCREAT(p, &sg, args->path); - -#ifdef DEBUG - printf("Linux-emul(%d): mkdir(%s, %d)\n", - p->p_pid, args->path, args->mode); -#endif - bsd.path = args->path; - bsd.mode = args->mode; - - return mkdir(p, &bsd); -} - -int -linux_rmdir(struct proc *p, struct linux_rmdir_args *args) -{ - struct rmdir_args bsd; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTEXIST(p, &sg, args->path); - -#ifdef DEBUG - printf("Linux-emul(%d): rmdir(%s)\n", - p->p_pid, args->path); -#endif - bsd.path = args->path; - - return rmdir(p, &bsd); -} - -int -linux_rename(struct proc *p, struct linux_rename_args *args) -{ - struct rename_args bsd; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTEXIST(p, &sg, args->from); - CHECKALTCREAT(p, &sg, args->to); - -#ifdef DEBUG - printf("Linux-emul(%d): rename(%s, %s)\n", - p->p_pid, args->from, args->to); -#endif - bsd.from = args->from; - bsd.to = args->to; - - return rename(p, &bsd); -} - -int -linux_symlink(struct proc *p, struct linux_symlink_args *args) -{ - struct symlink_args bsd; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTEXIST(p, &sg, args->path); - CHECKALTCREAT(p, &sg, args->to); - -#ifdef DEBUG - printf("Linux-emul(%d): symlink(%s, %s)\n", - p->p_pid, args->path, args->to); -#endif - bsd.path = args->path; - bsd.link = args->to; - - return symlink(p, &bsd); -} - -int -linux_execve(struct proc *p, struct linux_execve_args *args) -{ - struct execve_args bsd; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTEXIST(p, &sg, args->path); - -#ifdef DEBUG - printf("Linux-emul(%d): execve(%s)\n", - p->p_pid, args->path); -#endif - bsd.fname = args->path; - bsd.argv = args->argp; - bsd.envv = args->envp; - - return execve(p, &bsd); -} - -int -linux_readlink(struct proc *p, struct linux_readlink_args *args) -{ - struct readlink_args bsd; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTEXIST(p, &sg, args->name); - -#ifdef DEBUG - printf("Linux-emul(%ld): readlink(%s, %p, %d)\n", - (long)p->p_pid, args->name, (void *)args->buf, args->count); -#endif - bsd.path = args->name; - bsd.buf = args->buf; - bsd.count = args->count; - - return readlink(p, &bsd); -} - -int -linux_truncate(struct proc *p, struct linux_truncate_args *args) -{ - struct truncate_args bsd; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTEXIST(p, &sg, args->path); - -#ifdef DEBUG - printf("Linux-emul(%d): truncate(%s, %ld)\n", - p->p_pid, args->path, args->length); -#endif - bsd.path = args->path; - bsd.length = args->length; - - return truncate(p, &bsd); -} - -int -linux_link(struct proc *p, struct linux_link_args *args) -{ - struct link_args bsd; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTEXIST(p, &sg, args->path); - CHECKALTCREAT(p, &sg, args->to); - -#ifdef DEBUG - printf("Linux-emul(%d): link(%s, %s)\n", p->p_pid, args->path, args->to); -#endif - - bsd.path = args->path; - bsd.link = args->to; - - return link(p, &bsd); -} - -int -linux_getcwd(struct proc *p, struct linux_getcwd_args *args) -{ - struct __getcwd_args bsd; - caddr_t sg; - int error, len; - -#ifdef DEBUG - printf("Linux-emul(%ld): getcwd(%p, %ld)\n", (long)p->p_pid, - args->buf, args->bufsize); -#endif - - sg = stackgap_init(); - bsd.buf = stackgap_alloc(&sg, SPARE_USRSPACE); - bsd.buflen = SPARE_USRSPACE; - error = __getcwd(p, &bsd); - if (!error) { - len = strlen(bsd.buf) + 1; - if (len <= args->bufsize) { - p->p_retval[0] = len; - error = copyout(bsd.buf, args->buf, len); - } - else - error = ERANGE; - } - return (error); -} - -int -linux_fdatasync(p, uap) - struct proc *p; - struct linux_fdatasync_args *uap; -{ - struct fsync_args bsd; - - bsd.fd = uap->fd; - return fsync(p, &bsd); -} - -int -linux_pread(p, uap) - struct proc *p; - struct linux_pread_args *uap; -{ - struct pread_args bsd; - - bsd.fd = uap->fd; - bsd.buf = uap->buf; - bsd.nbyte = uap->nbyte; - bsd.offset = uap->offset; - return pread(p, &bsd); -} - -int -linux_pwrite(p, uap) - struct proc *p; - struct linux_pwrite_args *uap; -{ - struct pwrite_args bsd; - - bsd.fd = uap->fd; - bsd.buf = uap->buf; - bsd.nbyte = uap->nbyte; - bsd.offset = uap->offset; - return pwrite(p, &bsd); -} diff --git a/sys/i386/linux/linux_ioctl.c b/sys/i386/linux/linux_ioctl.c deleted file mode 100644 index 582770f..0000000 --- a/sys/i386/linux/linux_ioctl.c +++ /dev/null @@ -1,1529 +0,0 @@ -/* - * 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. - * - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/sysproto.h> -#include <sys/proc.h> -#include <sys/cdio.h> -#include <sys/fcntl.h> -#include <sys/file.h> -#include <sys/filedesc.h> -#include <sys/filio.h> -#include <sys/linker_set.h> -#include <sys/malloc.h> -#include <sys/tty.h> -#include <sys/socket.h> -#include <net/if.h> -#include <net/if_dl.h> -#include <net/if_types.h> -#include <sys/sockio.h> -#include <sys/soundcard.h> -#include <sys/disklabel.h> - -#include <machine/console.h> - -#include <i386/linux/linux.h> -#include <i386/linux/linux_ioctl.h> -#include <i386/linux/linux_mib.h> -#include <i386/linux/linux_proto.h> -#include <i386/linux/linux_util.h> - -static linux_ioctl_function_t linux_ioctl_cdrom; -static linux_ioctl_function_t linux_ioctl_console; -static linux_ioctl_function_t linux_ioctl_disk; -static linux_ioctl_function_t linux_ioctl_socket; -static linux_ioctl_function_t linux_ioctl_sound; -static linux_ioctl_function_t linux_ioctl_termio; - -static struct linux_ioctl_handler cdrom_handler = -{ linux_ioctl_cdrom, LINUX_IOCTL_CDROM_MIN, LINUX_IOCTL_CDROM_MAX }; -static struct linux_ioctl_handler console_handler = -{ linux_ioctl_console, LINUX_IOCTL_CONSOLE_MIN, LINUX_IOCTL_CONSOLE_MAX }; -static struct linux_ioctl_handler disk_handler = -{ linux_ioctl_disk, LINUX_IOCTL_DISK_MIN, LINUX_IOCTL_DISK_MAX }; -static struct linux_ioctl_handler socket_handler = -{ linux_ioctl_socket, LINUX_IOCTL_SOCKET_MIN, LINUX_IOCTL_SOCKET_MAX }; -static struct linux_ioctl_handler sound_handler = -{ linux_ioctl_sound, LINUX_IOCTL_SOUND_MIN, LINUX_IOCTL_SOUND_MAX }; -static struct linux_ioctl_handler termio_handler = -{ linux_ioctl_termio, LINUX_IOCTL_TERMIO_MIN, LINUX_IOCTL_TERMIO_MAX }; - -DATA_SET(linux_ioctl_handler_set, cdrom_handler); -DATA_SET(linux_ioctl_handler_set, console_handler); -DATA_SET(linux_ioctl_handler_set, disk_handler); -DATA_SET(linux_ioctl_handler_set, socket_handler); -DATA_SET(linux_ioctl_handler_set, sound_handler); -DATA_SET(linux_ioctl_handler_set, termio_handler); - -struct handler_element -{ - TAILQ_ENTRY(handler_element) list; - int (*func)(struct proc *, struct linux_ioctl_args *); - int low, high, span; -}; - -static TAILQ_HEAD(, handler_element) handlers = - TAILQ_HEAD_INITIALIZER(handlers); - -static int -linux_ioctl_disk(struct proc *p, struct linux_ioctl_args *args) -{ - struct file *fp = p->p_fd->fd_ofiles[args->fd]; - int error; - struct disklabel dl; - - switch (args->cmd & 0xffff) { - case LINUX_BLKGETSIZE: - error = fo_ioctl(fp, DIOCGDINFO, (caddr_t)&dl, p); - if (error) - return (error); - return copyout(&(dl.d_secperunit), (caddr_t)args->arg, sizeof(dl.d_secperunit)); - break; - } - return (ENOIOCTL); -} - -/* - * termio related ioctls - */ - -struct linux_termio { - unsigned short c_iflag; - unsigned short c_oflag; - unsigned short c_cflag; - unsigned short c_lflag; - unsigned char c_line; - unsigned char c_cc[LINUX_NCC]; -}; - -struct linux_termios { - unsigned int c_iflag; - unsigned int c_oflag; - unsigned int c_cflag; - unsigned int 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[] = { - { B0, LINUX_B0 }, { B50, LINUX_B50 }, - { B75, LINUX_B75 }, { B110, LINUX_B110 }, - { B134, LINUX_B134 }, { B150, LINUX_B150 }, - { B200, LINUX_B200 }, { B300, LINUX_B300 }, - { B600, LINUX_B600 }, { B1200, LINUX_B1200 }, - { B1800, LINUX_B1800 }, { B2400, LINUX_B2400 }, - { B4800, LINUX_B4800 }, { B9600, LINUX_B9600 }, - { B19200, LINUX_B19200 }, { B38400, LINUX_B38400 }, - { B57600, LINUX_B57600 }, { B115200, LINUX_B115200 }, - {-1, -1 } -}; - -struct linux_serial_struct { - int type; - int line; - int port; - int irq; - int flags; - int xmit_fifo_size; - int custom_divisor; - int baud_base; - unsigned short close_delay; - char reserved_char[2]; - int hub6; - unsigned short closing_wait; - unsigned short closing_wait2; - int reserved[4]; -}; - -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 *bios, struct linux_termios *lios) -{ - int i; - -#ifdef DEBUG - printf("LINUX: BSD termios structure (input):\n"); - printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n", - bios->c_iflag, bios->c_oflag, bios->c_cflag, bios->c_lflag, - bios->c_ispeed, bios->c_ospeed); - printf("c_cc "); - for (i=0; i<NCCS; i++) - printf("%02x ", bios->c_cc[i]); - printf("\n"); -#endif - - lios->c_iflag = 0; - if (bios->c_iflag & IGNBRK) - lios->c_iflag |= LINUX_IGNBRK; - if (bios->c_iflag & BRKINT) - lios->c_iflag |= LINUX_BRKINT; - if (bios->c_iflag & IGNPAR) - lios->c_iflag |= LINUX_IGNPAR; - if (bios->c_iflag & PARMRK) - lios->c_iflag |= LINUX_PARMRK; - if (bios->c_iflag & INPCK) - lios->c_iflag |= LINUX_INPCK; - if (bios->c_iflag & ISTRIP) - lios->c_iflag |= LINUX_ISTRIP; - if (bios->c_iflag & INLCR) - lios->c_iflag |= LINUX_INLCR; - if (bios->c_iflag & IGNCR) - lios->c_iflag |= LINUX_IGNCR; - if (bios->c_iflag & ICRNL) - lios->c_iflag |= LINUX_ICRNL; - if (bios->c_iflag & IXON) - lios->c_iflag |= LINUX_IXON; - if (bios->c_iflag & IXANY) - lios->c_iflag |= LINUX_IXANY; - if (bios->c_iflag & IXOFF) - lios->c_iflag |= LINUX_IXOFF; - if (bios->c_iflag & IMAXBEL) - lios->c_iflag |= LINUX_IMAXBEL; - - lios->c_oflag = 0; - if (bios->c_oflag & OPOST) - lios->c_oflag |= LINUX_OPOST; - if (bios->c_oflag & ONLCR) - lios->c_oflag |= LINUX_ONLCR; - if (bios->c_oflag & OXTABS) - lios->c_oflag |= LINUX_XTABS; - - lios->c_cflag = bsd_to_linux_speed(bios->c_ispeed, sptab); - lios->c_cflag |= (bios->c_cflag & CSIZE) >> 4; - if (bios->c_cflag & CSTOPB) - lios->c_cflag |= LINUX_CSTOPB; - if (bios->c_cflag & CREAD) - lios->c_cflag |= LINUX_CREAD; - if (bios->c_cflag & PARENB) - lios->c_cflag |= LINUX_PARENB; - if (bios->c_cflag & PARODD) - lios->c_cflag |= LINUX_PARODD; - if (bios->c_cflag & HUPCL) - lios->c_cflag |= LINUX_HUPCL; - if (bios->c_cflag & CLOCAL) - lios->c_cflag |= LINUX_CLOCAL; - if (bios->c_cflag & CRTSCTS) - lios->c_cflag |= LINUX_CRTSCTS; - - lios->c_lflag = 0; - if (bios->c_lflag & ISIG) - lios->c_lflag |= LINUX_ISIG; - if (bios->c_lflag & ICANON) - lios->c_lflag |= LINUX_ICANON; - if (bios->c_lflag & ECHO) - lios->c_lflag |= LINUX_ECHO; - if (bios->c_lflag & ECHOE) - lios->c_lflag |= LINUX_ECHOE; - if (bios->c_lflag & ECHOK) - lios->c_lflag |= LINUX_ECHOK; - if (bios->c_lflag & ECHONL) - lios->c_lflag |= LINUX_ECHONL; - if (bios->c_lflag & NOFLSH) - lios->c_lflag |= LINUX_NOFLSH; - if (bios->c_lflag & TOSTOP) - lios->c_lflag |= LINUX_TOSTOP; - if (bios->c_lflag & ECHOCTL) - lios->c_lflag |= LINUX_ECHOCTL; - if (bios->c_lflag & ECHOPRT) - lios->c_lflag |= LINUX_ECHOPRT; - if (bios->c_lflag & ECHOKE) - lios->c_lflag |= LINUX_ECHOKE; - if (bios->c_lflag & FLUSHO) - lios->c_lflag |= LINUX_FLUSHO; - if (bios->c_lflag & PENDIN) - lios->c_lflag |= LINUX_PENDIN; - if (bios->c_lflag & IEXTEN) - lios->c_lflag |= LINUX_IEXTEN; - - for (i=0; i<LINUX_NCCS; i++) - lios->c_cc[i] = LINUX_POSIX_VDISABLE; - lios->c_cc[LINUX_VINTR] = bios->c_cc[VINTR]; - lios->c_cc[LINUX_VQUIT] = bios->c_cc[VQUIT]; - lios->c_cc[LINUX_VERASE] = bios->c_cc[VERASE]; - lios->c_cc[LINUX_VKILL] = bios->c_cc[VKILL]; - lios->c_cc[LINUX_VEOF] = bios->c_cc[VEOF]; - lios->c_cc[LINUX_VEOL] = bios->c_cc[VEOL]; - lios->c_cc[LINUX_VMIN] = bios->c_cc[VMIN]; - lios->c_cc[LINUX_VTIME] = bios->c_cc[VTIME]; - lios->c_cc[LINUX_VEOL2] = bios->c_cc[VEOL2]; - lios->c_cc[LINUX_VSUSP] = bios->c_cc[VSUSP]; - lios->c_cc[LINUX_VSTART] = bios->c_cc[VSTART]; - lios->c_cc[LINUX_VSTOP] = bios->c_cc[VSTOP]; - lios->c_cc[LINUX_VREPRINT] = bios->c_cc[VREPRINT]; - lios->c_cc[LINUX_VDISCARD] = bios->c_cc[VDISCARD]; - lios->c_cc[LINUX_VWERASE] = bios->c_cc[VWERASE]; - lios->c_cc[LINUX_VLNEXT] = bios->c_cc[VLNEXT]; - - for (i=0; i<LINUX_NCCS; i++) { - if (lios->c_cc[i] == _POSIX_VDISABLE) - lios->c_cc[i] = LINUX_POSIX_VDISABLE; - } - lios->c_line = 0; - -#ifdef DEBUG - printf("LINUX: LINUX termios structure (output):\n"); - printf("i=%08x o=%08x c=%08x l=%08x line=%d\n", lios->c_iflag, - lios->c_oflag, lios->c_cflag, lios->c_lflag, (int)lios->c_line); - printf("c_cc "); - for (i=0; i<LINUX_NCCS; i++) - printf("%02x ", lios->c_cc[i]); - printf("\n"); -#endif -} - -static void -linux_to_bsd_termios(struct linux_termios *lios, struct termios *bios) -{ - int i; - -#ifdef DEBUG - printf("LINUX: LINUX termios structure (input):\n"); - printf("i=%08x o=%08x c=%08x l=%08x line=%d\n", lios->c_iflag, - lios->c_oflag, lios->c_cflag, lios->c_lflag, (int)lios->c_line); - printf("c_cc "); - for (i=0; i<LINUX_NCCS; i++) - printf("%02x ", lios->c_cc[i]); - printf("\n"); -#endif - - bios->c_iflag = 0; - if (lios->c_iflag & LINUX_IGNBRK) - bios->c_iflag |= IGNBRK; - if (lios->c_iflag & LINUX_BRKINT) - bios->c_iflag |= BRKINT; - if (lios->c_iflag & LINUX_IGNPAR) - bios->c_iflag |= IGNPAR; - if (lios->c_iflag & LINUX_PARMRK) - bios->c_iflag |= PARMRK; - if (lios->c_iflag & LINUX_INPCK) - bios->c_iflag |= INPCK; - if (lios->c_iflag & LINUX_ISTRIP) - bios->c_iflag |= ISTRIP; - if (lios->c_iflag & LINUX_INLCR) - bios->c_iflag |= INLCR; - if (lios->c_iflag & LINUX_IGNCR) - bios->c_iflag |= IGNCR; - if (lios->c_iflag & LINUX_ICRNL) - bios->c_iflag |= ICRNL; - if (lios->c_iflag & LINUX_IXON) - bios->c_iflag |= IXON; - if (lios->c_iflag & LINUX_IXANY) - bios->c_iflag |= IXANY; - if (lios->c_iflag & LINUX_IXOFF) - bios->c_iflag |= IXOFF; - if (lios->c_iflag & LINUX_IMAXBEL) - bios->c_iflag |= IMAXBEL; - - bios->c_oflag = 0; - if (lios->c_oflag & LINUX_OPOST) - bios->c_oflag |= OPOST; - if (lios->c_oflag & LINUX_ONLCR) - bios->c_oflag |= ONLCR; - if (lios->c_oflag & LINUX_XTABS) - bios->c_oflag |= OXTABS; - - bios->c_cflag = (lios->c_cflag & LINUX_CSIZE) << 4; - if (lios->c_cflag & LINUX_CSTOPB) - bios->c_cflag |= CSTOPB; - if (lios->c_cflag & LINUX_CREAD) - bios->c_cflag |= CREAD; - if (lios->c_cflag & LINUX_PARENB) - bios->c_cflag |= PARENB; - if (lios->c_cflag & LINUX_PARODD) - bios->c_cflag |= PARODD; - if (lios->c_cflag & LINUX_HUPCL) - bios->c_cflag |= HUPCL; - if (lios->c_cflag & LINUX_CLOCAL) - bios->c_cflag |= CLOCAL; - if (lios->c_cflag & LINUX_CRTSCTS) - bios->c_cflag |= CRTSCTS; - - bios->c_lflag = 0; - if (lios->c_lflag & LINUX_ISIG) - bios->c_lflag |= ISIG; - if (lios->c_lflag & LINUX_ICANON) - bios->c_lflag |= ICANON; - if (lios->c_lflag & LINUX_ECHO) - bios->c_lflag |= ECHO; - if (lios->c_lflag & LINUX_ECHOE) - bios->c_lflag |= ECHOE; - if (lios->c_lflag & LINUX_ECHOK) - bios->c_lflag |= ECHOK; - if (lios->c_lflag & LINUX_ECHONL) - bios->c_lflag |= ECHONL; - if (lios->c_lflag & LINUX_NOFLSH) - bios->c_lflag |= NOFLSH; - if (lios->c_lflag & LINUX_TOSTOP) - bios->c_lflag |= TOSTOP; - if (lios->c_lflag & LINUX_ECHOCTL) - bios->c_lflag |= ECHOCTL; - if (lios->c_lflag & LINUX_ECHOPRT) - bios->c_lflag |= ECHOPRT; - if (lios->c_lflag & LINUX_ECHOKE) - bios->c_lflag |= ECHOKE; - if (lios->c_lflag & LINUX_FLUSHO) - bios->c_lflag |= FLUSHO; - if (lios->c_lflag & LINUX_PENDIN) - bios->c_lflag |= PENDIN; - if (lios->c_lflag & LINUX_IEXTEN) - bios->c_lflag |= IEXTEN; - - for (i=0; i<NCCS; i++) - bios->c_cc[i] = _POSIX_VDISABLE; - bios->c_cc[VINTR] = lios->c_cc[LINUX_VINTR]; - bios->c_cc[VQUIT] = lios->c_cc[LINUX_VQUIT]; - bios->c_cc[VERASE] = lios->c_cc[LINUX_VERASE]; - bios->c_cc[VKILL] = lios->c_cc[LINUX_VKILL]; - bios->c_cc[VEOF] = lios->c_cc[LINUX_VEOF]; - bios->c_cc[VEOL] = lios->c_cc[LINUX_VEOL]; - bios->c_cc[VMIN] = lios->c_cc[LINUX_VMIN]; - bios->c_cc[VTIME] = lios->c_cc[LINUX_VTIME]; - bios->c_cc[VEOL2] = lios->c_cc[LINUX_VEOL2]; - bios->c_cc[VSUSP] = lios->c_cc[LINUX_VSUSP]; - bios->c_cc[VSTART] = lios->c_cc[LINUX_VSTART]; - bios->c_cc[VSTOP] = lios->c_cc[LINUX_VSTOP]; - bios->c_cc[VREPRINT] = lios->c_cc[LINUX_VREPRINT]; - bios->c_cc[VDISCARD] = lios->c_cc[LINUX_VDISCARD]; - bios->c_cc[VWERASE] = lios->c_cc[LINUX_VWERASE]; - bios->c_cc[VLNEXT] = lios->c_cc[LINUX_VLNEXT]; - - for (i=0; i<NCCS; i++) { - if (bios->c_cc[i] == LINUX_POSIX_VDISABLE) - bios->c_cc[i] = _POSIX_VDISABLE; - } - - bios->c_ispeed = bios->c_ospeed = - linux_to_bsd_speed(lios->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", - bios->c_iflag, bios->c_oflag, bios->c_cflag, bios->c_lflag, - bios->c_ispeed, bios->c_ospeed); - printf("c_cc "); - for (i=0; i<NCCS; i++) - printf("%02x ", bios->c_cc[i]); - printf("\n"); -#endif -} - -static void -bsd_to_linux_termio(struct termios *bios, struct linux_termio *lio) -{ - struct linux_termios lios; - - bsd_to_linux_termios(bios, &lios); - lio->c_iflag = lios.c_iflag; - lio->c_oflag = lios.c_oflag; - lio->c_cflag = lios.c_cflag; - lio->c_lflag = lios.c_lflag; - lio->c_line = lios.c_line; - memcpy(lio->c_cc, lios.c_cc, LINUX_NCC); -} - -static void -linux_to_bsd_termio(struct linux_termio *lio, struct termios *bios) -{ - struct linux_termios lios; - int i; - - lios.c_iflag = lio->c_iflag; - lios.c_oflag = lio->c_oflag; - lios.c_cflag = lio->c_cflag; - lios.c_lflag = lio->c_lflag; - for (i=LINUX_NCC; i<LINUX_NCCS; i++) - lios.c_cc[i] = LINUX_POSIX_VDISABLE; - memcpy(lios.c_cc, lio->c_cc, LINUX_NCC); - linux_to_bsd_termios(&lios, bios); -} - -static int -linux_ioctl_termio(struct proc *p, struct linux_ioctl_args *args) -{ - struct termios bios; - struct linux_termios lios; - struct linux_termio lio; - struct file *fp = p->p_fd->fd_ofiles[args->fd]; - int error; - - switch (args->cmd & 0xffff) { - - case LINUX_TCGETS: - error = fo_ioctl(fp, TIOCGETA, (caddr_t)&bios, p); - if (error) - return (error); - bsd_to_linux_termios(&bios, &lios); - return copyout(&lios, (caddr_t)args->arg, sizeof(lios)); - - case LINUX_TCSETS: - error = copyin((caddr_t)args->arg, &lios, sizeof(lios)); - if (error) - return (error); - linux_to_bsd_termios(&lios, &bios); - return (fo_ioctl(fp, TIOCSETA, (caddr_t)&bios, p)); - - case LINUX_TCSETSW: - error = copyin((caddr_t)args->arg, &lios, sizeof(lios)); - if (error) - return (error); - linux_to_bsd_termios(&lios, &bios); - return (fo_ioctl(fp, TIOCSETAW, (caddr_t)&bios, p)); - - case LINUX_TCSETSF: - error = copyin((caddr_t)args->arg, &lios, sizeof(lios)); - if (error) - return (error); - linux_to_bsd_termios(&lios, &bios); - return (fo_ioctl(fp, TIOCSETAF, (caddr_t)&bios, p)); - - case LINUX_TCGETA: - error = fo_ioctl(fp, TIOCGETA, (caddr_t)&bios, p); - if (error) - return (error); - bsd_to_linux_termio(&bios, &lio); - return (copyout(&lio, (caddr_t)args->arg, sizeof(lio))); - - case LINUX_TCSETA: - error = copyin((caddr_t)args->arg, &lio, sizeof(lio)); - if (error) - return (error); - linux_to_bsd_termio(&lio, &bios); - return (fo_ioctl(fp, TIOCSETA, (caddr_t)&bios, p)); - - case LINUX_TCSETAW: - error = copyin((caddr_t)args->arg, &lio, sizeof(lio)); - if (error) - return (error); - linux_to_bsd_termio(&lio, &bios); - return (fo_ioctl(fp, TIOCSETAW, (caddr_t)&bios, p)); - - case LINUX_TCSETAF: - error = copyin((caddr_t)args->arg, &lio, sizeof(lio)); - if (error) - return (error); - linux_to_bsd_termio(&lio, &bios); - return (fo_ioctl(fp, TIOCSETAF, (caddr_t)&bios, p)); - - /* LINUX_TCSBRK */ - - case LINUX_TCXONC: { - switch (args->arg) { - case LINUX_TCOOFF: - args->cmd = TIOCSTOP; - break; - case LINUX_TCOON: - args->cmd = TIOCSTART; - break; - case LINUX_TCIOFF: - case LINUX_TCION: { - int c; - struct write_args wr; - error = fo_ioctl(fp, TIOCGETA, (caddr_t)&bios, p); - if (error) - return (error); - c = (args->arg == LINUX_TCIOFF) ? VSTOP : VSTART; - c = bios.c_cc[c]; - if (c != _POSIX_VDISABLE) { - wr.fd = args->fd; - wr.buf = &c; - wr.nbyte = sizeof(c); - return (write(p, &wr)); - } else - return (0); - } - default: - return (EINVAL); - } - args->arg = 0; - return (ioctl(p, (struct ioctl_args *)args)); - } - - case LINUX_TCFLSH: { - args->cmd = TIOCFLUSH; - switch (args->arg) { - case LINUX_TCIFLUSH: - args->arg = FREAD; - break; - case LINUX_TCOFLUSH: - args->arg = FWRITE; - break; - case LINUX_TCIOFLUSH: - args->arg = FREAD | FWRITE; - break; - default: - return (EINVAL); - } - return (ioctl(p, (struct ioctl_args *)args)); - } - - case LINUX_TIOCEXCL: - args->cmd = TIOCEXCL; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_TIOCNXCL: - args->cmd = TIOCNXCL; - return (ioctl(p, (struct ioctl_args *)args)); - - /* LINUX_TIOCSCTTY */ - - case LINUX_TIOCGPGRP: - args->cmd = TIOCGPGRP; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_TIOCSPGRP: - args->cmd = TIOCSPGRP; - return (ioctl(p, (struct ioctl_args *)args)); - - /* LINUX_TIOCOUTQ */ - /* LINUX_TIOCSTI */ - - case LINUX_TIOCGWINSZ: - args->cmd = TIOCGWINSZ; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_TIOCSWINSZ: - args->cmd = TIOCSWINSZ; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_TIOCMGET: - args->cmd = TIOCMGET; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_TIOCMBIS: - args->cmd = TIOCMBIS; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_TIOCMBIC: - args->cmd = TIOCMBIC; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_TIOCMSET: - args->cmd = TIOCMSET; - return (ioctl(p, (struct ioctl_args *)args)); - - /* TIOCGSOFTCAR */ - /* TIOCSSOFTCAR */ - - case LINUX_FIONREAD: /* LINUX_TIOCINQ */ - args->cmd = FIONREAD; - return (ioctl(p, (struct ioctl_args *)args)); - - /* LINUX_TIOCLINUX */ - - case LINUX_TIOCCONS: - args->cmd = TIOCCONS; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_TIOCGSERIAL: { - struct linux_serial_struct lss; - lss.type = LINUX_PORT_16550A; - lss.flags = 0; - lss.close_delay = 0; - return copyout(&lss, (caddr_t)args->arg, sizeof(lss)); - } - - case LINUX_TIOCSSERIAL: { - struct linux_serial_struct lss; - error = copyin((caddr_t)args->arg, &lss, sizeof(lss)); - if (error) - return (error); - /* XXX - It really helps to have an implementation that - * does nothing. NOT! - */ - return (0); - } - - /* LINUX_TIOCPKT */ - - case LINUX_FIONBIO: - args->cmd = FIONBIO; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_TIOCNOTTY: - args->cmd = TIOCNOTTY; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_TIOCSETD: { - int line; - switch (args->arg) { - case LINUX_N_TTY: - line = TTYDISC; - break; - case LINUX_N_SLIP: - line = SLIPDISC; - break; - case LINUX_N_PPP: - line = PPPDISC; - break; - default: - return (EINVAL); - } - return (fo_ioctl(fp, TIOCSETD, (caddr_t)&line, p)); - } - - case LINUX_TIOCGETD: { - int linux_line; - int bsd_line = TTYDISC; - error = fo_ioctl(fp, TIOCGETD, (caddr_t)&bsd_line, p); - if (error) - 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))); - } - - /* LINUX_TCSBRKP */ - /* LINUX_TIOCTTYGSTRUCT */ - - case LINUX_FIONCLEX: - args->cmd = FIONCLEX; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_FIOCLEX: - args->cmd = FIOCLEX; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_FIOASYNC: - args->cmd = FIOASYNC; - return (ioctl(p, (struct ioctl_args *)args)); - - /* LINUX_TIOCSERCONFIG */ - /* LINUX_TIOCSERGWILD */ - /* LINUX_TIOCSERSWILD */ - /* LINUX_TIOCGLCKTRMIOS */ - /* LINUX_TIOCSLCKTRMIOS */ - - } - - return (ENOIOCTL); -} - -/* - * CDROM related ioctls - */ - -struct linux_cdrom_msf -{ - u_char cdmsf_min0; - u_char cdmsf_sec0; - u_char cdmsf_frame0; - u_char cdmsf_min1; - u_char cdmsf_sec1; - u_char cdmsf_frame1; -}; - -struct linux_cdrom_tochdr -{ - u_char cdth_trk0; - u_char cdth_trk1; -}; - -union linux_cdrom_addr -{ - struct { - u_char minute; - u_char second; - u_char frame; - } msf; - int lba; -}; - -struct linux_cdrom_tocentry -{ - u_char cdte_track; - u_char cdte_adr:4; - u_char cdte_ctrl:4; - u_char cdte_format; - union linux_cdrom_addr cdte_addr; - u_char cdte_datamode; -}; - -struct linux_cdrom_subchnl -{ - u_char cdsc_format; - u_char cdsc_audiostatus; - u_char cdsc_adr:4; - u_char cdsc_ctrl:4; - u_char cdsc_trk; - u_char cdsc_ind; - union linux_cdrom_addr cdsc_absaddr; - union linux_cdrom_addr cdsc_reladdr; -}; - -static void -bsd_to_linux_msf_lba(u_char af, union msf_lba *bp, union linux_cdrom_addr *lp) -{ - if (af == CD_LBA_FORMAT) - lp->lba = bp->lba; - else { - lp->msf.minute = bp->msf.minute; - lp->msf.second = bp->msf.second; - lp->msf.frame = bp->msf.frame; - } -} - -static void -set_linux_cdrom_addr(union linux_cdrom_addr *addr, int format, int lba) -{ - if (format == LINUX_CDROM_MSF) { - addr->msf.frame = lba % 75; - lba /= 75; - lba += 2; - addr->msf.second = lba % 60; - addr->msf.minute = lba / 60; - } else - addr->lba = lba; -} - -static int -linux_ioctl_cdrom(struct proc *p, struct linux_ioctl_args *args) -{ - struct file *fp = p->p_fd->fd_ofiles[args->fd]; - int error; - - switch (args->cmd & 0xffff) { - - case LINUX_CDROMPAUSE: - args->cmd = CDIOCPAUSE; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_CDROMRESUME: - args->cmd = CDIOCRESUME; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_CDROMPLAYMSF: - args->cmd = CDIOCPLAYMSF; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_CDROMPLAYTRKIND: - args->cmd = CDIOCPLAYTRACKS; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_CDROMREADTOCHDR: { - struct ioc_toc_header th; - struct linux_cdrom_tochdr lth; - error = fo_ioctl(fp, CDIOREADTOCHEADER, (caddr_t)&th, p); - if (!error) { - lth.cdth_trk0 = th.starting_track; - lth.cdth_trk1 = th.ending_track; - copyout(<h, (caddr_t)args->arg, sizeof(lth)); - } - return (error); - } - - case LINUX_CDROMREADTOCENTRY: { - struct linux_cdrom_tocentry lte, *ltep = - (struct linux_cdrom_tocentry *)args->arg; - struct ioc_read_toc_single_entry irtse; - irtse.address_format = ltep->cdte_format; - irtse.track = ltep->cdte_track; - error = fo_ioctl(fp, CDIOREADTOCENTRY, (caddr_t)&irtse, p); - if (!error) { - lte = *ltep; - lte.cdte_ctrl = irtse.entry.control; - lte.cdte_adr = irtse.entry.addr_type; - bsd_to_linux_msf_lba(irtse.address_format, - &irtse.entry.addr, <e.cdte_addr); - copyout(<e, (caddr_t)args->arg, sizeof(lte)); - } - return (error); - } - - case LINUX_CDROMSTOP: - args->cmd = CDIOCSTOP; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_CDROMSTART: - args->cmd = CDIOCSTART; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_CDROMEJECT: - args->cmd = CDIOCEJECT; - return (ioctl(p, (struct ioctl_args *)args)); - - /* LINUX_CDROMVOLCTRL */ - - case LINUX_CDROMSUBCHNL: { - struct linux_cdrom_subchnl sc; - struct ioc_read_subchannel bsdsc; - struct cd_sub_channel_info *bsdinfo; - caddr_t sg = stackgap_init(); - bsdinfo = (struct cd_sub_channel_info*)stackgap_alloc(&sg, - sizeof(struct cd_sub_channel_info)); - bsdsc.address_format = CD_LBA_FORMAT; - bsdsc.data_format = CD_CURRENT_POSITION; - bsdsc.track = 0; - bsdsc.data_len = sizeof(struct cd_sub_channel_info); - bsdsc.data = bsdinfo; - error = fo_ioctl(fp, CDIOCREADSUBCHANNEL, (caddr_t)&bsdsc, p); - if (error) - return (error); - error = copyin((caddr_t)args->arg, &sc, - sizeof(struct linux_cdrom_subchnl)); - if (error) - return (error); - sc.cdsc_audiostatus = bsdinfo->header.audio_status; - sc.cdsc_adr = bsdinfo->what.position.addr_type; - sc.cdsc_ctrl = bsdinfo->what.position.control; - sc.cdsc_trk = bsdinfo->what.position.track_number; - sc.cdsc_ind = bsdinfo->what.position.index_number; - set_linux_cdrom_addr(&sc.cdsc_absaddr, sc.cdsc_format, - bsdinfo->what.position.absaddr.lba); - set_linux_cdrom_addr(&sc.cdsc_reladdr, sc.cdsc_format, - bsdinfo->what.position.reladdr.lba); - error = copyout(&sc, (caddr_t)args->arg, - sizeof(struct linux_cdrom_subchnl)); - return (error); - } - - /* LINUX_CDROMREADMODE2 */ - /* LINUX_CDROMREADMODE1 */ - /* LINUX_CDROMREADAUDIO */ - /* LINUX_CDROMEJECT_SW */ - /* LINUX_CDROMMULTISESSION */ - /* LINUX_CDROM_GET_UPC */ - - case LINUX_CDROMRESET: - args->cmd = CDIOCRESET; - return (ioctl(p, (struct ioctl_args *)args)); - - /* LINUX_CDROMVOLREAD */ - /* LINUX_CDROMREADRAW */ - /* LINUX_CDROMREADCOOKED */ - /* LINUX_CDROMSEEK */ - /* LINUX_CDROMPLAYBLK */ - /* LINUX_CDROMREADALL */ - /* LINUX_CDROMCLOSETRAY */ - /* LINUX_CDROMLOADFROMSLOT */ - - } - - return (ENOIOCTL); -} - -/* - * Sound related ioctls - */ - -static unsigned dirbits[4] = { IOC_VOID, IOC_IN, IOC_OUT, IOC_INOUT }; - -#define SETDIR(c) (((c) & ~IOC_DIRMASK) | dirbits[args->cmd >> 30]) - -static int -linux_ioctl_sound(struct proc *p, struct linux_ioctl_args *args) -{ - - switch (args->cmd & 0xffff) { - - case LINUX_SOUND_MIXER_WRITE_VOLUME: - args->cmd = SETDIR(SOUND_MIXER_WRITE_VOLUME); - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SOUND_MIXER_WRITE_BASS: - args->cmd = SETDIR(SOUND_MIXER_WRITE_BASS); - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SOUND_MIXER_WRITE_TREBLE: - args->cmd = SETDIR(SOUND_MIXER_WRITE_TREBLE); - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SOUND_MIXER_WRITE_SYNTH: - args->cmd = SETDIR(SOUND_MIXER_WRITE_SYNTH); - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SOUND_MIXER_WRITE_PCM: - args->cmd = SETDIR(SOUND_MIXER_WRITE_PCM); - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SOUND_MIXER_WRITE_SPEAKER: - args->cmd = SETDIR(SOUND_MIXER_WRITE_SPEAKER); - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SOUND_MIXER_WRITE_LINE: - args->cmd = SETDIR(SOUND_MIXER_WRITE_LINE); - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SOUND_MIXER_WRITE_MIC: - args->cmd = SETDIR(SOUND_MIXER_WRITE_MIC); - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SOUND_MIXER_WRITE_CD: - args->cmd = SETDIR(SOUND_MIXER_WRITE_CD); - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SOUND_MIXER_WRITE_IMIX: - args->cmd = SETDIR(SOUND_MIXER_WRITE_IMIX); - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SOUND_MIXER_WRITE_ALTPCM: - args->cmd = SETDIR(SOUND_MIXER_WRITE_ALTPCM); - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SOUND_MIXER_WRITE_RECLEV: - args->cmd = SETDIR(SOUND_MIXER_WRITE_RECLEV); - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SOUND_MIXER_WRITE_IGAIN: - args->cmd = SETDIR(SOUND_MIXER_WRITE_IGAIN); - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SOUND_MIXER_WRITE_OGAIN: - args->cmd = SETDIR(SOUND_MIXER_WRITE_OGAIN); - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SOUND_MIXER_WRITE_LINE1: - args->cmd = SETDIR(SOUND_MIXER_WRITE_LINE1); - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SOUND_MIXER_WRITE_LINE2: - args->cmd = SETDIR(SOUND_MIXER_WRITE_LINE2); - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SOUND_MIXER_WRITE_LINE3: - args->cmd = SETDIR(SOUND_MIXER_WRITE_LINE3); - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_OSS_GETVERSION: { - int version = linux_get_oss_version(p); - return (copyout(&version, (caddr_t)args->arg, sizeof(int))); - } - - case LINUX_SOUND_MIXER_READ_DEVMASK: - args->cmd = SOUND_MIXER_READ_DEVMASK; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_DSP_RESET: - args->cmd = SNDCTL_DSP_RESET; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_DSP_SYNC: - args->cmd = SNDCTL_DSP_SYNC; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_DSP_SPEED: - args->cmd = SNDCTL_DSP_SPEED; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_DSP_STEREO: - args->cmd = SNDCTL_DSP_STEREO; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_DSP_GETBLKSIZE: /* LINUX_SNDCTL_DSP_SETBLKSIZE */ - args->cmd = SNDCTL_DSP_GETBLKSIZE; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_DSP_SETFMT: - args->cmd = SNDCTL_DSP_SETFMT; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SOUND_PCM_WRITE_CHANNELS: - args->cmd = SOUND_PCM_WRITE_CHANNELS; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SOUND_PCM_WRITE_FILTER: - args->cmd = SOUND_PCM_WRITE_FILTER; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_DSP_POST: - args->cmd = SNDCTL_DSP_POST; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_DSP_SUBDIVIDE: - args->cmd = SNDCTL_DSP_SUBDIVIDE; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_DSP_SETFRAGMENT: - args->cmd = SNDCTL_DSP_SETFRAGMENT; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_DSP_GETFMTS: - args->cmd = SNDCTL_DSP_GETFMTS; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_DSP_GETOSPACE: - args->cmd = SNDCTL_DSP_GETOSPACE; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_DSP_GETISPACE: - args->cmd = SNDCTL_DSP_GETISPACE; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_DSP_NONBLOCK: - args->cmd = SNDCTL_DSP_NONBLOCK; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_DSP_GETCAPS: - args->cmd = SNDCTL_DSP_GETCAPS; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_DSP_SETTRIGGER: /* LINUX_SNDCTL_GETTRIGGER */ - args->cmd = SNDCTL_DSP_SETTRIGGER; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_DSP_GETIPTR: - args->cmd = SNDCTL_DSP_GETIPTR; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_DSP_GETOPTR: - args->cmd = SNDCTL_DSP_GETOPTR; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_DSP_GETODELAY: - args->cmd = SNDCTL_DSP_GETODELAY; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_SEQ_RESET: - args->cmd = SNDCTL_SEQ_RESET; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_SEQ_SYNC: - args->cmd = SNDCTL_SEQ_SYNC; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_SYNTH_INFO: - args->cmd = SNDCTL_SYNTH_INFO; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_SEQ_CTRLRATE: - args->cmd = SNDCTL_SEQ_CTRLRATE; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_SEQ_GETOUTCOUNT: - args->cmd = SNDCTL_SEQ_GETOUTCOUNT; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_SEQ_GETINCOUNT: - args->cmd = SNDCTL_SEQ_GETINCOUNT; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_SEQ_PERCMODE: - args->cmd = SNDCTL_SEQ_PERCMODE; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_FM_LOAD_INSTR: - args->cmd = SNDCTL_FM_LOAD_INSTR; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_SEQ_TESTMIDI: - args->cmd = SNDCTL_SEQ_TESTMIDI; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_SEQ_RESETSAMPLES: - args->cmd = SNDCTL_SEQ_RESETSAMPLES; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_SEQ_NRSYNTHS: - args->cmd = SNDCTL_SEQ_NRSYNTHS; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_SEQ_NRMIDIS: - args->cmd = SNDCTL_SEQ_NRMIDIS; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_MIDI_INFO: - args->cmd = SNDCTL_MIDI_INFO; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_SEQ_TRESHOLD: - args->cmd = SNDCTL_SEQ_TRESHOLD; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SNDCTL_SYNTH_MEMAVL: - args->cmd = SNDCTL_SYNTH_MEMAVL; - return (ioctl(p, (struct ioctl_args *)args)); - - } - - return (ENOIOCTL); -} - -/* - * Console related ioctls - */ - -#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG) - -static int -linux_ioctl_console(struct proc *p, struct linux_ioctl_args *args) -{ - struct file *fp = p->p_fd->fd_ofiles[args->fd]; - - switch (args->cmd & 0xffff) { - - case LINUX_KIOCSOUND: - args->cmd = KIOCSOUND; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_KDMKTONE: - args->cmd = KDMKTONE; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_KDGETLED: - args->cmd = KDGETLED; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_KDSETLED: - args->cmd = KDSETLED; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_KDSETMODE: - args->cmd = KDSETMODE; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_KDGETMODE: - args->cmd = KDGETMODE; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_KDGKBMODE: - args->cmd = KDGKBMODE; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_KDSKBMODE: { - int kbdmode; - switch (args->arg) { - case LINUX_KBD_RAW: - kbdmode = K_RAW; - break; - case LINUX_KBD_XLATE: - kbdmode = K_XLATE; - break; - case LINUX_KBD_MEDIUMRAW: - kbdmode = K_RAW; - break; - default: - return (EINVAL); - } - return (fo_ioctl(fp, KDSKBMODE, (caddr_t)&kbdmode, p)); - } - - case LINUX_VT_OPENQRY: - args->cmd = VT_OPENQRY; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_VT_GETMODE: - args->cmd = VT_GETMODE; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_VT_SETMODE: { - struct vt_mode *mode; - args->cmd = VT_SETMODE; - mode = (struct vt_mode *)args->arg; - if (!ISSIGVALID(mode->frsig) && ISSIGVALID(mode->acqsig)) - mode->frsig = mode->acqsig; - return (ioctl(p, (struct ioctl_args *)args)); - } - - case LINUX_VT_GETSTATE: - args->cmd = VT_GETACTIVE; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_VT_RELDISP: - args->cmd = VT_RELDISP; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_VT_ACTIVATE: - args->cmd = VT_ACTIVATE; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_VT_WAITACTIVE: - args->cmd = VT_WAITACTIVE; - return (ioctl(p, (struct ioctl_args *)args)); - - } - - return (ENOIOCTL); -} - -/* - * Socket related ioctls - */ - -static int -linux_ioctl_socket(struct proc *p, struct linux_ioctl_args *args) -{ - - switch (args->cmd & 0xffff) { - - case LINUX_FIOSETOWN: - args->cmd = FIOSETOWN; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SIOCSPGRP: - args->cmd = SIOCSPGRP; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_FIOGETOWN: - args->cmd = FIOGETOWN; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SIOCGPGRP: - args->cmd = SIOCGPGRP; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SIOCATMARK: - args->cmd = SIOCATMARK; - return (ioctl(p, (struct ioctl_args *)args)); - - /* LINUX_SIOCGSTAMP */ - - case LINUX_SIOCGIFCONF: - args->cmd = OSIOCGIFCONF; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SIOCGIFFLAGS: - args->cmd = SIOCGIFFLAGS; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SIOCGIFADDR: - args->cmd = OSIOCGIFADDR; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SIOCGIFDSTADDR: - args->cmd = OSIOCGIFDSTADDR; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SIOCGIFBRDADDR: - args->cmd = OSIOCGIFBRDADDR; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SIOCGIFNETMASK: - args->cmd = OSIOCGIFNETMASK; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SIOCGIFHWADDR: { - int ifn; - struct ifnet *ifp; - struct ifaddr *ifa; - struct sockaddr_dl *sdl; - struct linux_ifreq *ifr = (struct linux_ifreq *)args->arg; - - /* Note that we don't actually respect the name in the ifreq - * structure, as Linux interface names are all different. - */ - for (ifn = 0; ifn < if_index; ifn++) { - ifp = ifnet_addrs[ifn]->ifa_ifp; - if (ifp->if_type == IFT_ETHER) { - ifa = TAILQ_FIRST(&ifp->if_addrhead); - while (ifa) { - sdl=(struct sockaddr_dl*)ifa->ifa_addr; - if (sdl != NULL && - (sdl->sdl_family == AF_LINK) && - (sdl->sdl_type == IFT_ETHER)) { - return (copyout(LLADDR(sdl), - &ifr->ifr_hwaddr.sa_data, - LINUX_IFHWADDRLEN)); - } - ifa = TAILQ_NEXT(ifa, ifa_link); - } - } - } - return (ENOENT); - } - - case LINUX_SIOCADDMULTI: - args->cmd = SIOCADDMULTI; - return (ioctl(p, (struct ioctl_args *)args)); - - case LINUX_SIOCDELMULTI: - args->cmd = SIOCDELMULTI; - return (ioctl(p, (struct ioctl_args *)args)); - - } - - return (ENOIOCTL); -} - -/* - * main ioctl syscall function - */ - -int -linux_ioctl(struct proc *p, struct linux_ioctl_args *args) -{ - struct filedesc *fdp = p->p_fd; - struct file *fp; - struct handler_element *he; - int error, cmd; - -#ifdef DEBUG - printf("Linux-emul(%ld): ioctl(%d, %04lx, *)\n", (long)p->p_pid, - args->fd, args->cmd); -#endif - - if ((unsigned)args->fd >= fdp->fd_nfiles) - return (EBADF); - - fp = fdp->fd_ofiles[args->fd]; - if (fp == NULL || (fp->f_flag & (FREAD|FWRITE)) == 0) - return (EBADF); - - /* Iterate over the ioctl handlers */ - cmd = args->cmd & 0xffff; - TAILQ_FOREACH(he, &handlers, list) { - if (cmd >= he->low && cmd <= he->high) { - error = (*he->func)(p, args); - if (error != ENOIOCTL) - return (error); - } - } - - printf("linux: 'ioctl' fd=%d, cmd=%x ('%c',%d) not implemented\n", - args->fd, (int)(args->cmd & 0xffff), - (int)(args->cmd & 0xff00) >> 8, (int)(args->cmd & 0xff)); - - return (EINVAL); -} - -int -linux_ioctl_register_handler(struct linux_ioctl_handler *h) -{ - struct handler_element *he, *cur; - - if (h == NULL || h->func == NULL) - return (EINVAL); - - /* - * Reuse the element if the handler is already on the list, otherwise - * create a new element. - */ - TAILQ_FOREACH(he, &handlers, list) { - if (he->func == h->func) - break; - } - if (he == NULL) { - MALLOC(he, struct handler_element *, sizeof(*he), - M_LINUX, M_WAITOK); - he->func = h->func; - } else - TAILQ_REMOVE(&handlers, he, list); - - /* Initialize range information. */ - he->low = h->low; - he->high = h->high; - he->span = h->high - h->low + 1; - - /* Add the element to the list, sorted on span. */ - TAILQ_FOREACH(cur, &handlers, list) { - if (cur->span > he->span) { - TAILQ_INSERT_BEFORE(cur, he, list); - return (0); - } - } - TAILQ_INSERT_TAIL(&handlers, he, list); - - return (0); -} - -int -linux_ioctl_unregister_handler(struct linux_ioctl_handler *h) -{ - struct handler_element *he; - - if (h == NULL || h->func == NULL) - return (EINVAL); - - TAILQ_FOREACH(he, &handlers, list) { - if (he->func == h->func) { - TAILQ_REMOVE(&handlers, he, list); - FREE(he, M_LINUX); - return (0); - } - } - - return (EINVAL); -} - -int -linux_ioctl_register_handlers(struct linker_set *s) -{ - int error, i; - - if (s == NULL) - return (EINVAL); - - for (i = 0; i < s->ls_length; i++) { - error = linux_ioctl_register_handler(s->ls_items[i]); - if (error) - return (error); - } - - return (0); -} - -int -linux_ioctl_unregister_handlers(struct linker_set *s) -{ - int error, i; - - if (s == NULL) - return (EINVAL); - - for (i = 0; i < s->ls_length; i++) { - error = linux_ioctl_unregister_handler(s->ls_items[i]); - if (error) - return (error); - } - - return (0); -} diff --git a/sys/i386/linux/linux_ioctl.h b/sys/i386/linux/linux_ioctl.h deleted file mode 100644 index e20a34f..0000000 --- a/sys/i386/linux/linux_ioctl.h +++ /dev/null @@ -1,437 +0,0 @@ -/*- - * Copyright (c) 1999 Marcel Moolenaar - * 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. - * - * $FreeBSD$ - */ - -#ifndef _LINUX_IOCTL_H_ -#define _LINUX_IOCTL_H_ - -/* - * disk - */ -#define LINUX_BLKROSET 0x125d -#define LINUX_BLKROGET 0x125e -#define LINUX_BLKRRPART 0x125f -#define LINUX_BLKGETSIZE 0x1260 -#define LINUX_BLKFLSBUF 0x1261 -#define LINUX_BLKRASET 0x1262 -#define LINUX_BLKRAGET 0x1263 -#define LINUX_BLKFRASET 0x1264 -#define LINUX_BLKFRAGET 0x1265 -#define LINUX_BLKSECTSET 0x1266 -#define LINUX_BLKSECTGET 0x1267 -#define LINUX_BLKSSZGET 0x1268 - -#define LINUX_IOCTL_DISK_MIN LINUX_BLKROSET -#define LINUX_IOCTL_DISK_MAX LINUX_BLKSSZGET - -/* - * cdrom - */ -#define LINUX_CDROMPAUSE 0x5301 -#define LINUX_CDROMRESUME 0x5302 -#define LINUX_CDROMPLAYMSF 0x5303 -#define LINUX_CDROMPLAYTRKIND 0x5304 -#define LINUX_CDROMREADTOCHDR 0x5305 -#define LINUX_CDROMREADTOCENTRY 0x5306 -#define LINUX_CDROMSTOP 0x5307 -#define LINUX_CDROMSTART 0x5308 -#define LINUX_CDROMEJECT 0x5309 -#define LINUX_CDROMVOLCTRL 0x530a -#define LINUX_CDROMSUBCHNL 0x530b -#define LINUX_CDROMREADMODE2 0x530c -#define LINUX_CDROMREADMODE1 0x530d -#define LINUX_CDROMREADAUDIO 0x530e -#define LINUX_CDROMEJECT_SW 0x530f -#define LINUX_CDROMMULTISESSION 0x5310 -#define LINUX_CDROM_GET_UPC 0x5311 -#define LINUX_CDROMRESET 0x5312 -#define LINUX_CDROMVOLREAD 0x5313 -#define LINUX_CDROMREADRAW 0x5314 -#define LINUX_CDROMREADCOOKED 0x5315 -#define LINUX_CDROMSEEK 0x5316 -#define LINUX_CDROMPLAYBLK 0x5317 -#define LINUX_CDROMREADALL 0x5318 -#define LINUX_CDROMCLOSETRAY 0x5319 -#define LINUX_CDROMLOADFROMSLOT 0x531a - -#define LINUX_IOCTL_CDROM_MIN LINUX_CDROMPAUSE -#define LINUX_IOCTL_CDROM_MAX LINUX_CDROMLOADFROMSLOT - -#define LINUX_CDROM_LBA 0x01 -#define LINUX_CDROM_MSF 0x02 - -/* - * console - */ -#define LINUX_KIOCSOUND 0x4B2F -#define LINUX_KDMKTONE 0x4B30 -#define LINUX_KDGETLED 0x4B31 -#define LINUX_KDSETLED 0x4B32 -#define LINUX_KDSETMODE 0x4B3A -#define LINUX_KDGETMODE 0x4B3B -#define LINUX_KDGKBMODE 0x4B44 -#define LINUX_KDSKBMODE 0x4B45 -#define LINUX_VT_OPENQRY 0x5600 -#define LINUX_VT_GETMODE 0x5601 -#define LINUX_VT_SETMODE 0x5602 -#define LINUX_VT_GETSTATE 0x5603 -#define LINUX_VT_RELDISP 0x5605 -#define LINUX_VT_ACTIVATE 0x5606 -#define LINUX_VT_WAITACTIVE 0x5607 - -#define LINUX_IOCTL_CONSOLE_MIN LINUX_KIOCSOUND -#define LINUX_IOCTL_CONSOLE_MAX LINUX_VT_WAITACTIVE - -#define LINUX_LED_SCR 0x01 -#define LINUX_LED_NUM 0x02 -#define LINUX_LED_CAP 0x04 - -#define LINUX_KD_TEXT 0x0 -#define LINUX_KD_GRAPHICS 0x1 -#define LINUX_KD_TEXT0 0x2 -#define LINUX_KD_TEXT1 0x3 - -#define LINUX_KBD_RAW 0 -#define LINUX_KBD_XLATE 1 -#define LINUX_KBD_MEDIUMRAW 2 - -/* - * socket - */ -#define LINUX_FIOSETOWN 0x8901 -#define LINUX_SIOCSPGRP 0x8902 -#define LINUX_FIOGETOWN 0x8903 -#define LINUX_SIOCGPGRP 0x8904 -#define LINUX_SIOCATMARK 0x8905 -#define LINUX_SIOCGSTAMP 0x8906 -#define LINUX_SIOCGIFCONF 0x8912 -#define LINUX_SIOCGIFFLAGS 0x8913 -#define LINUX_SIOCGIFADDR 0x8915 -#define LINUX_SIOCGIFDSTADDR 0x8917 -#define LINUX_SIOCGIFBRDADDR 0x8919 -#define LINUX_SIOCGIFNETMASK 0x891b -#define LINUX_SIOCGIFHWADDR 0x8927 -#define LINUX_SIOCADDMULTI 0x8931 -#define LINUX_SIOCDELMULTI 0x8932 - -#define LINUX_IOCTL_SOCKET_MIN LINUX_FIOSETOWN -#define LINUX_IOCTL_SOCKET_MAX LINUX_SIOCDELMULTI - -/* - * sound - */ -#define LINUX_SOUND_MIXER_WRITE_VOLUME 0x4d00 -#define LINUX_SOUND_MIXER_WRITE_BASS 0x4d01 -#define LINUX_SOUND_MIXER_WRITE_TREBLE 0x4d02 -#define LINUX_SOUND_MIXER_WRITE_SYNTH 0x4d03 -#define LINUX_SOUND_MIXER_WRITE_PCM 0x4d04 -#define LINUX_SOUND_MIXER_WRITE_SPEAKER 0x4d05 -#define LINUX_SOUND_MIXER_WRITE_LINE 0x4d06 -#define LINUX_SOUND_MIXER_WRITE_MIC 0x4d07 -#define LINUX_SOUND_MIXER_WRITE_CD 0x4d08 -#define LINUX_SOUND_MIXER_WRITE_IMIX 0x4d09 -#define LINUX_SOUND_MIXER_WRITE_ALTPCM 0x4d0A -#define LINUX_SOUND_MIXER_WRITE_RECLEV 0x4d0B -#define LINUX_SOUND_MIXER_WRITE_IGAIN 0x4d0C -#define LINUX_SOUND_MIXER_WRITE_OGAIN 0x4d0D -#define LINUX_SOUND_MIXER_WRITE_LINE1 0x4d0E -#define LINUX_SOUND_MIXER_WRITE_LINE2 0x4d0F -#define LINUX_SOUND_MIXER_WRITE_LINE3 0x4d10 -#define LINUX_OSS_GETVERSION 0x4d76 -#define LINUX_SOUND_MIXER_READ_DEVMASK 0x4dfe -#define LINUX_SNDCTL_DSP_RESET 0x5000 -#define LINUX_SNDCTL_DSP_SYNC 0x5001 -#define LINUX_SNDCTL_DSP_SPEED 0x5002 -#define LINUX_SNDCTL_DSP_STEREO 0x5003 -#define LINUX_SNDCTL_DSP_GETBLKSIZE 0x5004 -#define LINUX_SNDCTL_DSP_SETBLKSIZE LINUX_SNDCTL_DSP_GETBLKSIZE -#define LINUX_SNDCTL_DSP_SETFMT 0x5005 -#define LINUX_SOUND_PCM_WRITE_CHANNELS 0x5006 -#define LINUX_SOUND_PCM_WRITE_FILTER 0x5007 -#define LINUX_SNDCTL_DSP_POST 0x5008 -#define LINUX_SNDCTL_DSP_SUBDIVIDE 0x5009 -#define LINUX_SNDCTL_DSP_SETFRAGMENT 0x500A -#define LINUX_SNDCTL_DSP_GETFMTS 0x500B -#define LINUX_SNDCTL_DSP_GETOSPACE 0x500C -#define LINUX_SNDCTL_DSP_GETISPACE 0x500D -#define LINUX_SNDCTL_DSP_NONBLOCK 0x500E -#define LINUX_SNDCTL_DSP_GETCAPS 0x500F -#define LINUX_SNDCTL_DSP_GETTRIGGER 0x5010 -#define LINUX_SNDCTL_DSP_SETTRIGGER LINUX_SNDCTL_DSP_GETTRIGGER -#define LINUX_SNDCTL_DSP_GETIPTR 0x5011 -#define LINUX_SNDCTL_DSP_GETOPTR 0x5012 -#define LINUX_SNDCTL_DSP_GETODELAY 0x5017 -#define LINUX_SNDCTL_SEQ_RESET 0x5100 -#define LINUX_SNDCTL_SEQ_SYNC 0x5101 -#define LINUX_SNDCTL_SYNTH_INFO 0x5102 -#define LINUX_SNDCTL_SEQ_CTRLRATE 0x5103 -#define LINUX_SNDCTL_SEQ_GETOUTCOUNT 0x5104 -#define LINUX_SNDCTL_SEQ_GETINCOUNT 0x5105 -#define LINUX_SNDCTL_SEQ_PERCMODE 0x5106 -#define LINUX_SNDCTL_FM_LOAD_INSTR 0x5107 -#define LINUX_SNDCTL_SEQ_TESTMIDI 0x5108 -#define LINUX_SNDCTL_SEQ_RESETSAMPLES 0x5109 -#define LINUX_SNDCTL_SEQ_NRSYNTHS 0x510A -#define LINUX_SNDCTL_SEQ_NRMIDIS 0x510B -#define LINUX_SNDCTL_MIDI_INFO 0x510C -#define LINUX_SNDCTL_SEQ_TRESHOLD 0x510D -#define LINUX_SNDCTL_SYNTH_MEMAVL 0x510E - -#define LINUX_IOCTL_SOUND_MIN LINUX_SOUND_MIXER_WRITE_VOLUME -#define LINUX_IOCTL_SOUND_MAX LINUX_SNDCTL_SYNTH_MEMAVL - -/* - * termio - */ -#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 - -#define LINUX_IOCTL_TERMIO_MIN LINUX_TCGETS -#define LINUX_IOCTL_TERMIO_MAX LINUX_TIOCSLCKTRMIOS - -/* arguments for tcflow() and LINUX_TCXONC */ -#define LINUX_TCOOFF 0 -#define LINUX_TCOON 1 -#define LINUX_TCIOFF 2 -#define LINUX_TCION 3 - -/* arguments for tcflush() and LINUX_TCFLSH */ -#define LINUX_TCIFLUSH 0 -#define LINUX_TCOFLUSH 1 -#define LINUX_TCIOFLUSH 2 - -/* 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 19 - -#define LINUX_POSIX_VDISABLE '\0' - -/* 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 - -/* serial_struct values for TIOC[GS]SERIAL ioctls */ -#define LINUX_ASYNC_CLOSING_WAIT_INF 0 -#define LINUX_ASYNC_CLOSING_WAIT_NONE 65535 - -#define LINUX_PORT_UNKNOWN 0 -#define LINUX_PORT_8250 1 -#define LINUX_PORT_16450 2 -#define LINUX_PORT_16550 3 -#define LINUX_PORT_16550A 4 -#define LINUX_PORT_CIRRUS 5 -#define LINUX_PORT_16650 6 - -#define LINUX_PORT_MAX 6 - -#define LINUX_ASYNC_HUP_NOTIFY 0x0001 -#define LINUX_ASYNC_FOURPORT 0x0002 -#define LINUX_ASYNC_SAK 0x0004 -#define LINUX_ASYNC_SPLIT_TERMIOS 0x0008 -#define LINUX_ASYNC_SPD_MASK 0x0030 -#define LINUX_ASYNC_SPD_HI 0x0010 -#define LINUX_ASYNC_SPD_VHI 0x0020 -#define LINUX_ASYNC_SPD_CUST 0x0030 -#define LINUX_ASYNC_SKIP_TEST 0x0040 -#define LINUX_ASYNC_AUTO_IRQ 0x0080 -#define LINUX_ASYNC_SESSION_LOCKOUT 0x0100 -#define LINUX_ASYNC_PGRP_LOCKOUT 0x0200 -#define LINUX_ASYNC_CALLOUT_NOHUP 0x0400 -#define LINUX_ASYNC_FLAGS 0x0FFF - -#endif /* !_LINUX_IOCTL_H_ */ diff --git a/sys/i386/linux/linux_ipc.c b/sys/i386/linux/linux_ipc.c deleted file mode 100644 index 0428702..0000000 --- a/sys/i386/linux/linux_ipc.c +++ /dev/null @@ -1,490 +0,0 @@ -/*- - * 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. - * - * $FreeBSD$ - */ - - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/sysproto.h> -#include <sys/proc.h> -#include <sys/sem.h> -#include <sys/shm.h> - -#include <i386/linux/linux.h> -#include <i386/linux/linux_proto.h> -#include <i386/linux/linux_util.h> - -static int linux_semop __P((struct proc *, struct linux_ipc_args *)); -static int linux_semget __P((struct proc *, struct linux_ipc_args *)); -static int linux_semctl __P((struct proc *, struct linux_ipc_args *)); -static int linux_msgsnd __P((struct proc *, struct linux_ipc_args *)); -static int linux_msgrcv __P((struct proc *, struct linux_ipc_args *)); -static int linux_msgctl __P((struct proc *, struct linux_ipc_args *)); -static int linux_shmat __P((struct proc *, struct linux_ipc_args *)); -static int linux_shmdt __P((struct proc *, struct linux_ipc_args *)); -static int linux_shmget __P((struct proc *, struct linux_ipc_args *)); -static int linux_shmctl __P((struct proc *, struct linux_ipc_args *)); - -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_semid_ds { - struct linux_ipc_perm sem_perm; - linux_time_t sem_otime; - linux_time_t sem_ctime; - void *sem_base; - void *sem_pending; - void *sem_pending_last; - void *undo; - ushort sem_nsems; -}; - -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_semid_ds(struct linux_semid_ds *lsp, struct semid_ds *bsp) -{ - linux_to_bsd_ipc_perm(&lsp->sem_perm, &bsp->sem_perm); - bsp->sem_otime = lsp->sem_otime; - bsp->sem_ctime = lsp->sem_ctime; - bsp->sem_nsems = lsp->sem_nsems; - bsp->sem_base = lsp->sem_base; -} - -static void -bsd_to_linux_semid_ds(struct semid_ds *bsp, struct linux_semid_ds *lsp) -{ - bsd_to_linux_ipc_perm(&bsp->sem_perm, &lsp->sem_perm); - lsp->sem_otime = bsp->sem_otime; - lsp->sem_ctime = bsp->sem_ctime; - lsp->sem_nsems = bsp->sem_nsems; - lsp->sem_base = bsp->sem_base; -} - -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 */ -} - -static int -linux_semop(struct proc *p, struct linux_ipc_args *args) -{ - struct semop_args /* { - int semid; - struct sembuf *sops; - int nsops; - } */ bsd_args; - - bsd_args.semid = args->arg1; - bsd_args.sops = (struct sembuf *)args->ptr; - bsd_args.nsops = args->arg2; - return semop(p, &bsd_args); -} - -static int -linux_semget(struct proc *p, struct linux_ipc_args *args) -{ - struct semget_args /* { - key_t key; - int nsems; - int semflg; - } */ bsd_args; - - bsd_args.key = args->arg1; - bsd_args.nsems = args->arg2; - bsd_args.semflg = args->arg3; - return semget(p, &bsd_args); -} - -static int -linux_semctl(struct proc *p, struct linux_ipc_args *args) -{ - struct linux_semid_ds linux_semid; - struct semid_ds bsd_semid; - struct __semctl_args /* { - int semid; - int semnum; - int cmd; - union semun *arg; - } */ bsd_args; - int error; - caddr_t sg, unptr, dsp, ldsp; - - sg = stackgap_init(); - bsd_args.semid = args->arg1; - bsd_args.semnum = args->arg2; - bsd_args.cmd = args->arg3; - bsd_args.arg = (union semun *)args->ptr; - - switch (args->arg3) { - case LINUX_IPC_RMID: - bsd_args.cmd = IPC_RMID; - break; - case LINUX_GETNCNT: - bsd_args.cmd = GETNCNT; - break; - case LINUX_GETPID: - bsd_args.cmd = GETPID; - break; - case LINUX_GETVAL: - bsd_args.cmd = GETVAL; - break; - case LINUX_GETZCNT: - bsd_args.cmd = GETZCNT; - break; - case LINUX_SETVAL: - bsd_args.cmd = SETVAL; - break; - case LINUX_IPC_SET: - bsd_args.cmd = IPC_SET; - error = copyin(args->ptr, &ldsp, sizeof(ldsp)); - if (error) - return error; - error = copyin(ldsp, (caddr_t)&linux_semid, sizeof(linux_semid)); - if (error) - return error; - linux_to_bsd_semid_ds(&linux_semid, &bsd_semid); - unptr = stackgap_alloc(&sg, sizeof(union semun)); - dsp = stackgap_alloc(&sg, sizeof(struct semid_ds)); - error = copyout((caddr_t)&bsd_semid, dsp, sizeof(bsd_semid)); - if (error) - return error; - error = copyout((caddr_t)&dsp, unptr, sizeof(dsp)); - if (error) - return error; - bsd_args.arg = (union semun *)unptr; - return __semctl(p, &bsd_args); - case LINUX_IPC_STAT: - bsd_args.cmd = IPC_STAT; - unptr = stackgap_alloc(&sg, sizeof(union semun *)); - dsp = stackgap_alloc(&sg, sizeof(struct semid_ds)); - error = copyout((caddr_t)&dsp, unptr, sizeof(dsp)); - if (error) - return error; - bsd_args.arg = (union semun *)unptr; - error = __semctl(p, &bsd_args); - if (error) - return error; - error = copyin(dsp, (caddr_t)&bsd_semid, sizeof(bsd_semid)); - if (error) - return error; - bsd_to_linux_semid_ds(&bsd_semid, &linux_semid); - error = copyin(args->ptr, &ldsp, sizeof(ldsp)); - if (error) - return error; - return copyout((caddr_t)&linux_semid, ldsp, sizeof(linux_semid)); - case LINUX_GETALL: - /* FALLTHROUGH */ - case LINUX_SETALL: - /* FALLTHROUGH */ - default: - uprintf("LINUX: 'ipc' typ=%d not implemented\n", args->what); - return EINVAL; - } - return __semctl(p, &bsd_args); -} - -static int -linux_msgsnd(struct proc *p, struct linux_ipc_args *args) -{ - struct msgsnd_args /* { - int msqid; - void *msgp; - size_t msgsz; - int msgflg; - } */ bsd_args; - - bsd_args.msqid = args->arg1; - bsd_args.msgp = args->ptr; - bsd_args.msgsz = args->arg2; - bsd_args.msgflg = args->arg3; - return msgsnd(p, &bsd_args); -} - -static int -linux_msgrcv(struct proc *p, struct linux_ipc_args *args) -{ - struct msgrcv_args /* { - int msqid; - void *msgp; - size_t msgsz; - long msgtyp; - int msgflg; - } */ bsd_args; - - bsd_args.msqid = args->arg1; - bsd_args.msgp = args->ptr; - bsd_args.msgsz = args->arg2; - bsd_args.msgtyp = 0; - bsd_args.msgflg = args->arg3; - return msgrcv(p, &bsd_args); -} - -static int -linux_msgget(struct proc *p, struct linux_ipc_args *args) -{ - struct msgget_args /* { - key_t key; - int msgflg; - } */ bsd_args; - - bsd_args.key = args->arg1; - bsd_args.msgflg = args->arg2; - return msgget(p, &bsd_args); -} - -static int -linux_msgctl(struct proc *p, struct linux_ipc_args *args) -{ - struct msgctl_args /* { - int msqid; - int cmd; - struct msqid_ds *buf; - } */ bsd_args; - int error; - - bsd_args.msqid = args->arg1; - bsd_args.cmd = args->arg2; - bsd_args.buf = (struct msqid_ds *)args->ptr; - error = msgctl(p, &bsd_args); - return ((args->arg2 == LINUX_IPC_RMID && error == EINVAL) ? 0 : error); -} - -static int -linux_shmat(struct proc *p, struct linux_ipc_args *args) -{ - 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))) - return error; - if ((error = copyout(p->p_retval, (caddr_t)args->arg3, sizeof(int)))) - return error; - p->p_retval[0] = 0; - return 0; -} - -static int -linux_shmdt(struct proc *p, struct linux_ipc_args *args) -{ - struct shmdt_args /* { - void *shmaddr; - } */ bsd_args; - - bsd_args.shmaddr = args->ptr; - return shmdt(p, &bsd_args); -} - -static int -linux_shmget(struct proc *p, struct linux_ipc_args *args) -{ - 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); -} - -static int -linux_shmctl(struct proc *p, struct linux_ipc_args *args) -{ - 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; - caddr_t sg = stackgap_init(); - - switch (args->arg2) { - case LINUX_IPC_STAT: - bsd_args.shmid = args->arg1; - bsd_args.cmd = IPC_STAT; - bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds)); - if ((error = shmctl(p, &bsd_args))) - return error; - if ((error = copyin((caddr_t)bsd_args.buf, (caddr_t)&bsd_shmid, - 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*)stackgap_alloc(&sg, 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); - - case LINUX_IPC_RMID: - bsd_args.shmid = args->arg1; - bsd_args.cmd = IPC_RMID; - if (NULL == args->ptr) - bsd_args.buf = NULL; - else { - 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*)stackgap_alloc(&sg, 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); - - 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) -{ - switch (args->what) { - case LINUX_SEMOP: - return linux_semop(p, args); - case LINUX_SEMGET: - return linux_semget(p, args); - case LINUX_SEMCTL: - return linux_semctl(p, args); - case LINUX_MSGSND: - return linux_msgsnd(p, args); - case LINUX_MSGRCV: - return linux_msgrcv(p, args); - case LINUX_MSGGET: - return linux_msgget(p, args); - case LINUX_MSGCTL: - return linux_msgctl(p, args); - case LINUX_SHMAT: - return linux_shmat(p, args); - case LINUX_SHMDT: - return linux_shmdt(p, args); - case LINUX_SHMGET: - return linux_shmget(p, args); - case LINUX_SHMCTL: - return linux_shmctl(p, args); - default: - uprintf("LINUX: 'ipc' typ=%d not implemented\n", args->what); - return ENOSYS; - } -} diff --git a/sys/i386/linux/linux_mib.c b/sys/i386/linux/linux_mib.c deleted file mode 100644 index 867b511..0000000 --- a/sys/i386/linux/linux_mib.c +++ /dev/null @@ -1,231 +0,0 @@ -/*- - * Copyright (c) 1999 Marcel Moolenaar - * 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. - * - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/kernel.h> -#include <sys/systm.h> -#include <sys/sysctl.h> -#include <sys/proc.h> -#include <sys/malloc.h> -#include <sys/jail.h> - -#include <i386/linux/linux.h> -#include <i386/linux/linux_mib.h> - -struct linux_prison { - char pr_osname[LINUX_MAX_UTSNAME]; - char pr_osrelease[LINUX_MAX_UTSNAME]; - int pr_oss_version; -}; - -SYSCTL_NODE(_compat, OID_AUTO, linux, CTLFLAG_RW, 0, - "Linux mode"); - -static char linux_osname[LINUX_MAX_UTSNAME] = "Linux"; - -static int -linux_sysctl_osname(SYSCTL_HANDLER_ARGS) -{ - char osname[LINUX_MAX_UTSNAME]; - int error; - - strcpy(osname, linux_get_osname(req->p)); - error = sysctl_handle_string(oidp, osname, LINUX_MAX_UTSNAME, req); - if (error || req->newptr == NULL) - return (error); - error = linux_set_osname(req->p, osname); - return (error); -} - -SYSCTL_PROC(_compat_linux, OID_AUTO, osname, - CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON, - 0, 0, linux_sysctl_osname, "A", - "Linux kernel OS name"); - -static char linux_osrelease[LINUX_MAX_UTSNAME] = "2.2.12"; - -static int -linux_sysctl_osrelease(SYSCTL_HANDLER_ARGS) -{ - char osrelease[LINUX_MAX_UTSNAME]; - int error; - - strcpy(osrelease, linux_get_osrelease(req->p)); - error = sysctl_handle_string(oidp, osrelease, LINUX_MAX_UTSNAME, req); - if (error || req->newptr == NULL) - return (error); - error = linux_set_osrelease(req->p, osrelease); - return (error); -} - -SYSCTL_PROC(_compat_linux, OID_AUTO, osrelease, - CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON, - 0, 0, linux_sysctl_osrelease, "A", - "Linux kernel OS release"); - -static int linux_oss_version = 0x030600; - -static int -linux_sysctl_oss_version(SYSCTL_HANDLER_ARGS) -{ - int oss_version; - int error; - - oss_version = linux_get_oss_version(req->p); - error = sysctl_handle_int(oidp, &oss_version, 0, req); - if (error || req->newptr == NULL) - return (error); - error = linux_set_oss_version(req->p, oss_version); - return (error); -} - -SYSCTL_PROC(_compat_linux, OID_AUTO, oss_version, - CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_PRISON, - 0, 0, linux_sysctl_oss_version, "I", - "Linux OSS version"); - -static struct linux_prison * -get_prison(struct proc *p) -{ - register struct prison *pr; - register struct linux_prison *lpr; - - pr = p->p_prison; - if (pr == NULL) - return (NULL); - - if (pr->pr_linux == NULL) { - MALLOC(lpr, struct linux_prison *, sizeof *lpr, - M_PRISON, M_WAITOK); - bzero((caddr_t)lpr, sizeof *lpr); - pr->pr_linux = lpr; - } - - return (pr->pr_linux); -} - -char * -linux_get_osname(p) - struct proc *p; -{ - register struct prison *pr; - register struct linux_prison *lpr; - - pr = p->p_prison; - if (pr != NULL && pr->pr_linux != NULL) { - lpr = pr->pr_linux; - if (lpr->pr_osname[0]) - return (lpr->pr_osname); - } - - return (linux_osname); -} - -int -linux_set_osname(p, osname) - struct proc *p; - char *osname; -{ - register struct linux_prison *lpr; - - lpr = get_prison(p); - if (lpr != NULL) - strcpy(lpr->pr_osname, osname); - else - strcpy(linux_osname, osname); - - return (0); -} - -char * -linux_get_osrelease(p) - struct proc *p; -{ - register struct prison *pr; - register struct linux_prison *lpr; - - pr = p->p_prison; - if (pr != NULL && pr->pr_linux != NULL) { - lpr = pr->pr_linux; - if (lpr->pr_osrelease[0]) - return (lpr->pr_osrelease); - } - - return (linux_osrelease); -} - -int -linux_set_osrelease(p, osrelease) - struct proc *p; - char *osrelease; -{ - register struct linux_prison *lpr; - - lpr = get_prison(p); - if (lpr != NULL) - strcpy(lpr->pr_osrelease, osrelease); - else - strcpy(linux_osrelease, osrelease); - - return (0); -} - -int -linux_get_oss_version(p) - struct proc *p; -{ - register struct prison *pr; - register struct linux_prison *lpr; - - pr = p->p_prison; - if (pr != NULL && pr->pr_linux != NULL) { - lpr = pr->pr_linux; - if (lpr->pr_oss_version) - return (lpr->pr_oss_version); - } - - return (linux_oss_version); -} - -int -linux_set_oss_version(p, oss_version) - struct proc *p; - int oss_version; -{ - register struct linux_prison *lpr; - - lpr = get_prison(p); - if (lpr != NULL) - lpr->pr_oss_version = oss_version; - else - linux_oss_version = oss_version; - - return (0); -} diff --git a/sys/i386/linux/linux_mib.h b/sys/i386/linux/linux_mib.h deleted file mode 100644 index 5a6884c..0000000 --- a/sys/i386/linux/linux_mib.h +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * Copyright (c) 1999 Marcel Moolenaar - * 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. - * - * $FreeBSD$ - */ - -#ifndef _LINUX_MIB_H_ -#define _LINUX_MIB_H_ - -char* linux_get_osname __P((struct proc *p)); -int linux_set_osname __P((struct proc *p, char *osname)); - -char* linux_get_osrelease __P((struct proc *p)); -int linux_set_osrelease __P((struct proc *p, char *osrelease)); - -int linux_get_oss_version __P((struct proc *p)); -int linux_set_oss_version __P((struct proc *p, int oss_version)); - -#endif /* _LINUX_MIB_H_ */ diff --git a/sys/i386/linux/linux_misc.c b/sys/i386/linux/linux_misc.c deleted file mode 100644 index dcbff98..0000000 --- a/sys/i386/linux/linux_misc.c +++ /dev/null @@ -1,1470 +0,0 @@ -/*- - * 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. - * - * $FreeBSD$ - */ - -#include "opt_compat.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/sysproto.h> -#include <sys/kernel.h> -#include <sys/mman.h> -#include <sys/proc.h> -#include <sys/fcntl.h> -#include <sys/imgact_aout.h> -#include <sys/mount.h> -#include <sys/namei.h> -#include <sys/resourcevar.h> -#include <sys/stat.h> -#include <sys/sysctl.h> -#include <sys/unistd.h> -#include <sys/vnode.h> -#include <sys/wait.h> -#include <sys/time.h> -#include <sys/signalvar.h> - -#include <vm/vm.h> -#include <vm/pmap.h> -#include <vm/vm_kern.h> -#include <vm/vm_map.h> -#include <vm/vm_extern.h> - -#include <machine/frame.h> -#include <machine/psl.h> -#include <machine/sysarch.h> -#include <machine/segments.h> - -#include <i386/linux/linux.h> -#include <i386/linux/linux_proto.h> -#include <i386/linux/linux_util.h> -#include <i386/linux/linux_mib.h> - -#include <posix4/sched.h> - -#define BSD_TO_LINUX_SIGNAL(sig) \ - (((sig) <= LINUX_SIGTBLSZ) ? bsd_to_linux_signal[_SIG_IDX(sig)] : sig) - -static unsigned int linux_to_bsd_resource[LINUX_RLIM_NLIMITS] = -{ RLIMIT_CPU, RLIMIT_FSIZE, RLIMIT_DATA, RLIMIT_STACK, - RLIMIT_CORE, RLIMIT_RSS, RLIMIT_NPROC, RLIMIT_NOFILE, - RLIMIT_MEMLOCK, -1 -}; - -int -linux_alarm(struct proc *p, struct linux_alarm_args *args) -{ - struct itimerval it, old_it; - struct timeval tv; - int s; - -#ifdef DEBUG - printf("Linux-emul(%ld): alarm(%u)\n", (long)p->p_pid, args->secs); -#endif - if (args->secs > 100000000) - return EINVAL; - 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 = splsoftclock(); - old_it = p->p_realtimer; - getmicrouptime(&tv); - if (timevalisset(&old_it.it_value)) - untimeout(realitexpire, (caddr_t)p, p->p_ithandle); - if (it.it_value.tv_sec != 0) { - p->p_ithandle = timeout(realitexpire, (caddr_t)p, tvtohz(&it.it_value)); - timevaladd(&it.it_value, &tv); - } - p->p_realtimer = it; - splx(s); - if (timevalcmp(&old_it.it_value, &tv, >)) { - timevalsub(&old_it.it_value, &tv); - if (old_it.it_value.tv_usec != 0) - old_it.it_value.tv_sec++; - p->p_retval[0] = old_it.it_value.tv_sec; - } - return 0; -} - -int -linux_brk(struct proc *p, struct linux_brk_args *args) -{ -#if 0 - struct vmspace *vm = p->p_vmspace; - vm_offset_t new, old; - int error; - - 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); - p->p_retval[0] = old; - if ((new-old) > 0) { - if (swap_pager_full) - return ENOMEM; - error = vm_map_find(&vm->vm_map, NULL, 0, &old, (new-old), FALSE, - VM_PROT_ALL, VM_PROT_ALL, 0); - if (error) - return error; - vm->vm_dsize += btoc((new-old)); - p->p_retval[0] = (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 /* { - char * nsize; - } */ tmp; - -#ifdef DEBUG - printf("Linux-emul(%ld): brk(%p)\n", (long)p->p_pid, (void *)args->dsend); -#endif - old = (vm_offset_t)vm->vm_daddr + ctob(vm->vm_dsize); - new = (vm_offset_t)args->dsend; - tmp.nsize = (char *) new; - if (((caddr_t)new > vm->vm_daddr) && !obreak(p, &tmp)) - p->p_retval[0] = (int)new; - else - p->p_retval[0] = (int)old; - - return 0; -#endif -} - -int -linux_uselib(struct proc *p, struct linux_uselib_args *args) -{ - struct nameidata ni; - struct vnode *vp; - struct exec *a_out; - struct vattr attr; - vm_offset_t vmaddr; - unsigned long file_offset; - vm_offset_t buffer; - unsigned long bss_size; - int error; - caddr_t sg; - int locked; - - sg = stackgap_init(); - CHECKALTEXIST(p, &sg, args->library); - -#ifdef DEBUG - printf("Linux-emul(%ld): uselib(%s)\n", (long)p->p_pid, args->library); -#endif - - a_out = NULL; - locked = 0; - vp = NULL; - - NDINIT(&ni, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, args->library, p); - error = namei(&ni); - if (error) - goto cleanup; - - vp = ni.ni_vp; - /* - * XXX This looks like a bogus check - a LOCKLEAF namei should not succeed - * without returning a vnode. - */ - if (vp == NULL) { - error = ENOEXEC; /* ?? */ - goto cleanup; - } - NDFREE(&ni, NDF_ONLY_PNBUF); - - /* - * From here on down, we have a locked vnode that must be unlocked. - */ - locked++; - - /* - * Writable? - */ - if (vp->v_writecount) { - error = ETXTBSY; - goto cleanup; - } - - /* - * Executable? - */ - error = VOP_GETATTR(vp, &attr, p->p_ucred, p); - if (error) - goto cleanup; - - if ((vp->v_mount->mnt_flag & MNT_NOEXEC) || - ((attr.va_mode & 0111) == 0) || - (attr.va_type != VREG)) { - error = ENOEXEC; - goto cleanup; - } - - /* - * Sensible size? - */ - if (attr.va_size == 0) { - error = ENOEXEC; - goto cleanup; - } - - /* - * Can we access it? - */ - error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p); - if (error) - goto cleanup; - - error = VOP_OPEN(vp, FREAD, p->p_ucred, p); - if (error) - goto cleanup; - - /* - * Lock no longer needed - */ - VOP_UNLOCK(vp, 0, p); - locked = 0; - - /* - * Pull in executable header into kernel_map - */ - error = vm_mmap(kernel_map, (vm_offset_t *)&a_out, PAGE_SIZE, - VM_PROT_READ, VM_PROT_READ, 0, (caddr_t)vp, 0); - if (error) - goto cleanup; - - /* - * Is it a Linux binary ? - */ - if (((a_out->a_magic >> 16) & 0xff) != 0x64) { - error = ENOEXEC; - goto cleanup; - } - - /* While we are here, we should REALLY do some more checks */ - - /* - * Set file/virtual offset based on a.out variant. - */ - switch ((int)(a_out->a_magic & 0xffff)) { - case 0413: /* ZMAGIC */ - file_offset = 1024; - break; - case 0314: /* QMAGIC */ - file_offset = 0; - break; - default: - error = ENOEXEC; - goto cleanup; - } - - bss_size = round_page(a_out->a_bss); - - /* - * Check various fields in header for validity/bounds. - */ - if (a_out->a_text & PAGE_MASK || a_out->a_data & PAGE_MASK) { - error = ENOEXEC; - goto cleanup; - } - - /* text + data can't exceed file size */ - if (a_out->a_data + a_out->a_text > attr.va_size) { - error = EFAULT; - goto cleanup; - } - - /* - * text/data/bss must not exceed limits - * XXX: this is not complete. it should check current usage PLUS - * the resources needed by this library. - */ - if (a_out->a_text > MAXTSIZ || - a_out->a_data + bss_size > p->p_rlimit[RLIMIT_DATA].rlim_cur) { - error = ENOMEM; - goto cleanup; - } - - /* - * prevent more writers - */ - vp->v_flag |= VTEXT; - - /* - * 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 & PAGE_MASK) { -#ifdef DEBUG -printf("uselib: Non page aligned binary %lu\n", file_offset); -#endif - /* - * Map text+data read/write/execute - */ - - /* a_entry is the load address and is page aligned */ - vmaddr = trunc_page(a_out->a_entry); - - /* get anon user mapping, read+write+execute */ - error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr, - a_out->a_text + a_out->a_data, FALSE, - VM_PROT_ALL, VM_PROT_ALL, 0); - if (error) - goto cleanup; - - /* map file into kernel_map */ - error = vm_mmap(kernel_map, &buffer, - round_page(a_out->a_text + a_out->a_data + file_offset), - VM_PROT_READ, VM_PROT_READ, 0, - (caddr_t)vp, trunc_page(file_offset)); - if (error) - goto cleanup; - - /* copy from kernel VM space to user space */ - error = copyout((caddr_t)(void *)(uintptr_t)(buffer + file_offset), - (caddr_t)vmaddr, a_out->a_text + a_out->a_data); - - /* release temporary kernel space */ - vm_map_remove(kernel_map, buffer, - buffer + round_page(a_out->a_text + a_out->a_data + file_offset)); - - if (error) - goto cleanup; - } - else { -#ifdef DEBUG -printf("uselib: Page aligned binary %lu\n", file_offset); -#endif - /* - * for QMAGIC, a_entry is 20 bytes beyond the load address - * to skip the executable header - */ - vmaddr = trunc_page(a_out->a_entry); - - /* - * Map it all into the process's space as a single copy-on-write - * "data" segment. - */ - 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)vp, file_offset); - if (error) - goto cleanup; - } -#ifdef DEBUG -printf("mem=%08x = %08x %08x\n", vmaddr, ((int*)vmaddr)[0], ((int*)vmaddr)[1]); -#endif - if (bss_size != 0) { - /* - * Calculate BSS start address - */ - vmaddr = trunc_page(a_out->a_entry) + a_out->a_text + a_out->a_data; - - /* - * allocate some 'anon' space - */ - error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr, - bss_size, FALSE, - VM_PROT_ALL, VM_PROT_ALL, 0); - if (error) - goto cleanup; - } - -cleanup: - /* - * Unlock vnode if needed - */ - if (locked) - VOP_UNLOCK(vp, 0, p); - - /* - * Release the kernel mapping. - */ - if (a_out) - vm_map_remove(kernel_map, (vm_offset_t)a_out, (vm_offset_t)a_out + PAGE_SIZE); - - return error; -} - -/* XXX move */ -struct linux_select_argv { - int nfds; - fd_set *readfds; - fd_set *writefds; - fd_set *exceptfds; - struct timeval *timeout; -}; - -int -linux_select(struct proc *p, struct linux_select_args *args) -{ - struct linux_select_argv linux_args; - struct linux_newselect_args newsel; - int error; - -#ifdef SELECT_DEBUG - printf("Linux-emul(%ld): select(%x)\n", (long)p->p_pid, args->ptr); -#endif - if ((error = copyin((caddr_t)args->ptr, (caddr_t)&linux_args, - sizeof(linux_args)))) - return error; - - newsel.nfds = linux_args.nfds; - newsel.readfds = linux_args.readfds; - newsel.writefds = linux_args.writefds; - newsel.exceptfds = linux_args.exceptfds; - newsel.timeout = linux_args.timeout; - - return linux_newselect(p, &newsel); -} - -int -linux_newselect(struct proc *p, struct linux_newselect_args *args) -{ - struct select_args bsa; - struct timeval tv0, tv1, utv, *tvp; - caddr_t sg; - int error; - -#ifdef DEBUG - printf("Linux-emul(%ld): newselect(%d, %p, %p, %p, %p)\n", - (long)p->p_pid, args->nfds, (void *)args->readfds, - (void *)args->writefds, (void *)args->exceptfds, - (void *)args->timeout); -#endif - error = 0; - bsa.nd = args->nfds; - bsa.in = args->readfds; - bsa.ou = args->writefds; - bsa.ex = args->exceptfds; - bsa.tv = args->timeout; - - /* - * Store current time for computation of the amount of - * time left. - */ - if (args->timeout) { - if ((error = copyin(args->timeout, &utv, sizeof(utv)))) - goto select_out; -#ifdef DEBUG - printf("Linux-emul(%ld): incoming timeout (%ld/%ld)\n", - (long)p->p_pid, utv.tv_sec, utv.tv_usec); -#endif - if (itimerfix(&utv)) { - /* - * The timeval was invalid. Convert it to something - * valid that will act as it does under Linux. - */ - sg = stackgap_init(); - tvp = stackgap_alloc(&sg, sizeof(utv)); - utv.tv_sec += utv.tv_usec / 1000000; - utv.tv_usec %= 1000000; - if (utv.tv_usec < 0) { - utv.tv_sec -= 1; - utv.tv_usec += 1000000; - } - if (utv.tv_sec < 0) - timevalclear(&utv); - if ((error = copyout(&utv, tvp, sizeof(utv)))) - goto select_out; - bsa.tv = tvp; - } - microtime(&tv0); - } - - error = select(p, &bsa); -#ifdef DEBUG - printf("Linux-emul(%ld): real select returns %d\n", (long)p->p_pid, error); -#endif - - if (error) { - /* - * See fs/select.c in the Linux kernel. Without this, - * Maelstrom doesn't work. - */ - if (error == ERESTART) - error = EINTR; - goto select_out; - } - - if (args->timeout) { - if (p->p_retval[0]) { - /* - * Compute how much time was left of the timeout, - * by subtracting the current time and the time - * before we started the call, and subtracting - * that result from the user-supplied value. - */ - microtime(&tv1); - timevalsub(&tv1, &tv0); - timevalsub(&utv, &tv1); - if (utv.tv_sec < 0) - timevalclear(&utv); - } else - timevalclear(&utv); -#ifdef DEBUG - printf("Linux-emul(%ld): outgoing timeout (%ld/%ld)\n", - (long)p->p_pid, utv.tv_sec, utv.tv_usec); -#endif - if ((error = copyout(&utv, args->timeout, sizeof(utv)))) - goto select_out; - } - -select_out: -#ifdef DEBUG - printf("Linux-emul(%ld): newselect_out -> %d\n", (long)p->p_pid, error); -#endif - return error; -} - -int -linux_getpgid(struct proc *p, struct linux_getpgid_args *args) -{ - struct proc *curp; - -#ifdef DEBUG - printf("Linux-emul(%ld): getpgid(%d)\n", (long)p->p_pid, args->pid); -#endif - if (args->pid != p->p_pid) { - if (!(curp = pfind(args->pid))) - return ESRCH; - } - else - curp = p; - p->p_retval[0] = curp->p_pgid; - return 0; -} - -int -linux_fork(struct proc *p, struct linux_fork_args *args) -{ - int error; - -#ifdef DEBUG - printf("Linux-emul(%ld): fork()\n", (long)p->p_pid); -#endif - if ((error = fork(p, (struct fork_args *)args)) != 0) - return error; - if (p->p_retval[1] == 1) - p->p_retval[0] = 0; - return 0; -} - -int -linux_vfork(struct proc *p, struct linux_vfork_args *args) -{ - int error; - -#ifdef DEBUG - printf("Linux-emul(%ld): vfork()\n", (long)p->p_pid); -#endif - - if ((error = vfork(p, (struct vfork_args *)args)) != 0) - return error; - /* Are we the child? */ - if (p->p_retval[1] == 1) - p->p_retval[0] = 0; - return 0; -} - -#define CLONE_VM 0x100 -#define CLONE_FS 0x200 -#define CLONE_FILES 0x400 -#define CLONE_SIGHAND 0x800 -#define CLONE_PID 0x1000 - -int -linux_clone(struct proc *p, struct linux_clone_args *args) -{ - int error, ff = RFPROC; - struct proc *p2; - int exit_signal; - vm_offset_t start; - struct rfork_args rf_args; - -#ifdef DEBUG - if (args->flags & CLONE_PID) - printf("linux_clone(%ld): CLONE_PID not yet supported\n", - (long)p->p_pid); - printf("linux_clone(%ld): invoked with flags %x and stack %x\n", - (long)p->p_pid, (unsigned int)args->flags, - (unsigned int)args->stack); -#endif - - if (!args->stack) - return (EINVAL); - - exit_signal = args->flags & 0x000000ff; - if (exit_signal >= LINUX_NSIG) - return EINVAL; - - if (exit_signal <= LINUX_SIGTBLSZ) - exit_signal = linux_to_bsd_signal[_SIG_IDX(exit_signal)]; - - /* RFTHREAD probably not necessary here, but it shouldn't hurt either */ - ff |= RFTHREAD; - - if (args->flags & CLONE_VM) - ff |= RFMEM; - if (args->flags & CLONE_SIGHAND) - ff |= RFSIGSHARE; - if (!(args->flags & CLONE_FILES)) - ff |= RFFDG; - - error = 0; - start = 0; - - rf_args.flags = ff; - if ((error = rfork(p, &rf_args)) != 0) - return error; - - p2 = pfind(p->p_retval[0]); - if (p2 == 0) - return ESRCH; - - p2->p_sigparent = exit_signal; - p2->p_md.md_regs->tf_esp = (unsigned int)args->stack; - -#ifdef DEBUG - printf ("linux_clone(%ld): successful rfork to %ld\n", - (long)p->p_pid, (long)p2->p_pid); -#endif - return 0; -} - -/* XXX move */ -struct linux_mmap_argv { - linux_caddr_t addr; - int len; - int prot; - int flags; - int fd; - int pos; -}; - -#define STACK_SIZE (2 * 1024 * 1024) -#define GUARD_SIZE (4 * PAGE_SIZE) -int -linux_mmap(struct proc *p, struct linux_mmap_args *args) -{ - struct mmap_args /* { - caddr_t addr; - size_t len; - int prot; - int flags; - int fd; - long pad; - off_t pos; - } */ bsd_args; - int error; - struct linux_mmap_argv linux_args; - - if ((error = copyin((caddr_t)args->ptr, (caddr_t)&linux_args, - sizeof(linux_args)))) - return error; -#ifdef DEBUG - printf("Linux-emul(%ld): mmap(%p, %d, %d, 0x%08x, %d, %d)", - (long)p->p_pid, (void *)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; - if (linux_args.flags & LINUX_MAP_GROWSDOWN) { - bsd_args.flags |= MAP_STACK; - - /* The linux MAP_GROWSDOWN option does not limit auto - * growth of the region. Linux mmap with this option - * takes as addr the inital BOS, and as len, the initial - * region size. It can then grow down from addr without - * limit. However, linux threads has an implicit internal - * limit to stack size of STACK_SIZE. Its just not - * enforced explicitly in linux. But, here we impose - * a limit of (STACK_SIZE - GUARD_SIZE) on the stack - * region, since we can do this with our mmap. - * - * Our mmap with MAP_STACK takes addr as the maximum - * downsize limit on BOS, and as len the max size of - * the region. It them maps the top SGROWSIZ bytes, - * and autgrows the region down, up to the limit - * in addr. - * - * If we don't use the MAP_STACK option, the effect - * of this code is to allocate a stack region of a - * fixed size of (STACK_SIZE - GUARD_SIZE). - */ - - /* This gives us TOS */ - bsd_args.addr = linux_args.addr + linux_args.len; - - /* This gives us our maximum stack size */ - if (linux_args.len > STACK_SIZE - GUARD_SIZE) - bsd_args.len = linux_args.len; - else - bsd_args.len = STACK_SIZE - GUARD_SIZE; - - /* This gives us a new BOS. If we're using VM_STACK, then - * mmap will just map the top SGROWSIZ bytes, and let - * the stack grow down to the limit at BOS. If we're - * not using VM_STACK we map the full stack, since we - * don't have a way to autogrow it. - */ - bsd_args.addr -= bsd_args.len; - - } else { - bsd_args.addr = linux_args.addr; - bsd_args.len = linux_args.len; - } - - bsd_args.prot = linux_args.prot | PROT_READ; /* always required */ - if (linux_args.flags & LINUX_MAP_ANON) - bsd_args.fd = -1; - else - bsd_args.fd = linux_args.fd; - bsd_args.pos = linux_args.pos; - bsd_args.pad = 0; -#ifdef DEBUG - printf("-> (%p, %d, %d, 0x%08x, %d, %d)\n", - (void *)bsd_args.addr, bsd_args.len, - bsd_args.prot, bsd_args.flags, bsd_args.fd, (int)bsd_args.pos); -#endif - return mmap(p, &bsd_args); -} - -int -linux_mremap(struct proc *p, struct linux_mremap_args *args) -{ - struct munmap_args /* { - void *addr; - size_t len; - } */ bsd_args; - int error = 0; - -#ifdef DEBUG - printf("Linux-emul(%ld): mremap(%p, %08x, %08x, %08x)\n", - (long)p->p_pid, (void *)args->addr, args->old_len, args->new_len, - args->flags); -#endif - args->new_len = round_page(args->new_len); - args->old_len = round_page(args->old_len); - - if (args->new_len > args->old_len) { - p->p_retval[0] = 0; - return ENOMEM; - } - - if (args->new_len < args->old_len) { - bsd_args.addr = args->addr + args->new_len; - bsd_args.len = args->old_len - args->new_len; - error = munmap(p, &bsd_args); - } - - p->p_retval[0] = error ? 0 : (int)args->addr; - return error; -} - -int -linux_msync(struct proc *p, struct linux_msync_args *args) -{ - struct msync_args bsd_args; - - bsd_args.addr = args->addr; - bsd_args.len = args->len; - bsd_args.flags = 0; /* XXX ignore */ - - return msync(p, &bsd_args); -} - -int -linux_pipe(struct proc *p, struct linux_pipe_args *args) -{ - int error; - int reg_edx; - -#ifdef DEBUG - printf("Linux-emul(%ld): pipe(*)\n", (long)p->p_pid); -#endif - reg_edx = p->p_retval[1]; - error = pipe(p, 0); - if (error) { - p->p_retval[1] = reg_edx; - return error; - } - - error = copyout(p->p_retval, args->pipefds, 2*sizeof(int)); - if (error) { - p->p_retval[1] = reg_edx; - return error; - } - - p->p_retval[1] = reg_edx; - p->p_retval[0] = 0; - return 0; -} - -int -linux_time(struct proc *p, struct linux_time_args *args) -{ - struct timeval tv; - linux_time_t tm; - int error; - -#ifdef DEBUG - printf("Linux-emul(%ld): time(*)\n", (long)p->p_pid); -#endif - microtime(&tv); - tm = tv.tv_sec; - if (args->tm && (error = copyout(&tm, args->tm, sizeof(linux_time_t)))) - return error; - p->p_retval[0] = tm; - return 0; -} - -struct linux_times_argv { - long tms_utime; - long tms_stime; - long tms_cutime; - long tms_cstime; -}; - -#define CLK_TCK 100 /* Linux uses 100 */ -#define CONVTCK(r) (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK)) - -int -linux_times(struct proc *p, struct linux_times_args *args) -{ - struct timeval tv; - struct linux_times_argv tms; - struct rusage ru; - int error; - -#ifdef DEBUG - printf("Linux-emul(%ld): times(*)\n", (long)p->p_pid); -#endif - calcru(p, &ru.ru_utime, &ru.ru_stime, NULL); - - tms.tms_utime = CONVTCK(ru.ru_utime); - tms.tms_stime = CONVTCK(ru.ru_stime); - - tms.tms_cutime = CONVTCK(p->p_stats->p_cru.ru_utime); - tms.tms_cstime = CONVTCK(p->p_stats->p_cru.ru_stime); - - if ((error = copyout((caddr_t)&tms, (caddr_t)args->buf, - sizeof(struct linux_times_argv)))) - return error; - - microuptime(&tv); - p->p_retval[0] = (int)CONVTCK(tv); - return 0; -} - -int -linux_newuname(struct proc *p, struct linux_newuname_args *args) -{ - struct linux_new_utsname utsname; - char *osrelease, *osname; - -#ifdef DEBUG - printf("Linux-emul(%ld): newuname(*)\n", (long)p->p_pid); -#endif - - osname = linux_get_osname(p); - osrelease = linux_get_osrelease(p); - - bzero(&utsname, sizeof(struct linux_new_utsname)); - strncpy(utsname.sysname, osname, LINUX_MAX_UTSNAME-1); - strncpy(utsname.nodename, hostname, LINUX_MAX_UTSNAME-1); - strncpy(utsname.release, osrelease, LINUX_MAX_UTSNAME-1); - strncpy(utsname.version, version, LINUX_MAX_UTSNAME-1); - strncpy(utsname.machine, machine, LINUX_MAX_UTSNAME-1); - strncpy(utsname.domainname, domainname, LINUX_MAX_UTSNAME-1); - - return (copyout((caddr_t)&utsname, (caddr_t)args->buf, - sizeof(struct linux_new_utsname))); -} - -struct linux_utimbuf { - linux_time_t l_actime; - linux_time_t l_modtime; -}; - -int -linux_utime(struct proc *p, struct linux_utime_args *args) -{ - struct utimes_args /* { - char *path; - struct timeval *tptr; - } */ bsdutimes; - struct timeval tv[2], *tvp; - struct linux_utimbuf lut; - int error; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTEXIST(p, &sg, args->fname); - -#ifdef DEBUG - printf("Linux-emul(%ld): utime(%s, *)\n", (long)p->p_pid, args->fname); -#endif - if (args->times) { - if ((error = copyin(args->times, &lut, sizeof lut))) - return error; - tv[0].tv_sec = lut.l_actime; - tv[0].tv_usec = 0; - tv[1].tv_sec = lut.l_modtime; - tv[1].tv_usec = 0; - /* so that utimes can copyin */ - tvp = (struct timeval *)stackgap_alloc(&sg, sizeof(tv)); - if (tvp == NULL) - return (ENAMETOOLONG); - if ((error = copyout(tv, tvp, sizeof(tv)))) - return error; - bsdutimes.tptr = tvp; - } else - bsdutimes.tptr = NULL; - - bsdutimes.path = args->fname; - return utimes(p, &bsdutimes); -} - -#define __WCLONE 0x80000000 - -int -linux_waitpid(struct proc *p, struct linux_waitpid_args *args) -{ - struct wait_args /* { - int pid; - int *status; - int options; - struct rusage *rusage; - } */ tmp; - int error, tmpstat; - -#ifdef DEBUG - printf("Linux-emul(%ld): waitpid(%d, %p, %d)\n", - (long)p->p_pid, args->pid, (void *)args->status, args->options); -#endif - tmp.pid = args->pid; - tmp.status = args->status; - tmp.options = (args->options & (WNOHANG | WUNTRACED)); - /* WLINUXCLONE should be equal to __WCLONE, but we make sure */ - if (args->options & __WCLONE) - tmp.options |= WLINUXCLONE; - tmp.rusage = NULL; - - if ((error = wait4(p, &tmp)) != 0) - return error; - - if (args->status) { - if ((error = copyin(args->status, &tmpstat, sizeof(int))) != 0) - return error; - tmpstat &= 0xffff; - 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)); - } else - return 0; -} - -int -linux_wait4(struct proc *p, struct linux_wait4_args *args) -{ - struct wait_args /* { - int pid; - int *status; - int options; - struct rusage *rusage; - } */ tmp; - int error, tmpstat; - -#ifdef DEBUG - printf("Linux-emul(%ld): wait4(%d, %p, %d, %p)\n", - (long)p->p_pid, args->pid, (void *)args->status, args->options, - (void *)args->rusage); -#endif - tmp.pid = args->pid; - tmp.status = args->status; - tmp.options = (args->options & (WNOHANG | WUNTRACED)); - /* WLINUXCLONE should be equal to __WCLONE, but we make sure */ - if (args->options & __WCLONE) - tmp.options |= WLINUXCLONE; - tmp.rusage = args->rusage; - - if ((error = wait4(p, &tmp)) != 0) - return error; - - SIGDELSET(p->p_siglist, SIGCHLD); - - if (args->status) { - if ((error = copyin(args->status, &tmpstat, sizeof(int))) != 0) - return error; - tmpstat &= 0xffff; - 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)); - } else - return 0; -} - -int -linux_mknod(struct proc *p, struct linux_mknod_args *args) -{ - caddr_t sg; - struct mknod_args bsd_mknod; - struct mkfifo_args bsd_mkfifo; - - sg = stackgap_init(); - - CHECKALTCREAT(p, &sg, args->path); - -#ifdef DEBUG - printf("Linux-emul(%ld): mknod(%s, %d, %d)\n", - (long)p->p_pid, args->path, args->mode, args->dev); -#endif - - if (args->mode & S_IFIFO) { - bsd_mkfifo.path = args->path; - bsd_mkfifo.mode = args->mode; - return mkfifo(p, &bsd_mkfifo); - } else { - bsd_mknod.path = args->path; - bsd_mknod.mode = args->mode; - bsd_mknod.dev = args->dev; - return mknod(p, &bsd_mknod); - } -} - -/* - * UGH! This is just about the dumbest idea I've ever heard!! - */ -int -linux_personality(struct proc *p, struct linux_personality_args *args) -{ -#ifdef DEBUG - printf("Linux-emul(%ld): personality(%d)\n", - (long)p->p_pid, args->per); -#endif - if (args->per != 0) - return EINVAL; - - /* Yes Jim, it's still a Linux... */ - p->p_retval[0] = 0; - return 0; -} - -/* - * Wrappers for get/setitimer for debugging.. - */ -int -linux_setitimer(struct proc *p, struct linux_setitimer_args *args) -{ - struct setitimer_args bsa; - struct itimerval foo; - int error; - -#ifdef DEBUG - printf("Linux-emul(%ld): setitimer(%p, %p)\n", - (long)p->p_pid, (void *)args->itv, (void *)args->oitv); -#endif - bsa.which = args->which; - bsa.itv = args->itv; - bsa.oitv = args->oitv; - if (args->itv) { - if ((error = copyin((caddr_t)args->itv, (caddr_t)&foo, - sizeof(foo)))) - return error; -#ifdef DEBUG - printf("setitimer: value: sec: %ld, usec: %ld\n", - foo.it_value.tv_sec, foo.it_value.tv_usec); - printf("setitimer: interval: sec: %ld, usec: %ld\n", - foo.it_interval.tv_sec, foo.it_interval.tv_usec); -#endif - } - return setitimer(p, &bsa); -} - -int -linux_getitimer(struct proc *p, struct linux_getitimer_args *args) -{ - struct getitimer_args bsa; -#ifdef DEBUG - printf("Linux-emul(%ld): getitimer(%p)\n", - (long)p->p_pid, (void *)args->itv); -#endif - bsa.which = args->which; - bsa.itv = args->itv; - return getitimer(p, &bsa); -} - -int -linux_ioperm(struct proc *p, struct linux_ioperm_args *args) -{ - struct sysarch_args sa; - struct i386_ioperm_args *iia; - caddr_t sg; - - sg = stackgap_init(); - iia = stackgap_alloc(&sg, sizeof(struct i386_ioperm_args)); - iia->start = args->start; - iia->length = args->length; - iia->enable = args->enable; - sa.op = I386_SET_IOPERM; - sa.parms = (char *)iia; - return sysarch(p, &sa); -} - -int -linux_iopl(struct proc *p, struct linux_iopl_args *args) -{ - int error; - - if (args->level < 0 || args->level > 3) - return (EINVAL); - if ((error = suser(p)) != 0) - return (error); - if (securelevel > 0) - return (EPERM); - p->p_md.md_regs->tf_eflags = (p->p_md.md_regs->tf_eflags & ~PSL_IOPL) | - (args->level * (PSL_IOPL / 3)); - return (0); -} - -int -linux_nice(struct proc *p, struct linux_nice_args *args) -{ - struct setpriority_args bsd_args; - - bsd_args.which = PRIO_PROCESS; - bsd_args.who = 0; /* current process */ - bsd_args.prio = args->inc; - return setpriority(p, &bsd_args); -} - -int -linux_setgroups(p, uap) - struct proc *p; - struct linux_setgroups_args *uap; -{ - struct pcred *pc; - linux_gid_t linux_gidset[NGROUPS]; - gid_t *bsd_gidset; - int ngrp, error; - - pc = p->p_cred; - ngrp = uap->gidsetsize; - - /* - * cr_groups[0] holds egid. Setting the whole set from - * the supplied set will cause egid to be changed too. - * Keep cr_groups[0] unchanged to prevent that. - */ - - if ((error = suser(p)) != 0) - return (error); - - if (ngrp >= NGROUPS) - return (EINVAL); - - pc->pc_ucred = crcopy(pc->pc_ucred); - if (ngrp > 0) { - error = copyin((caddr_t)uap->gidset, (caddr_t)linux_gidset, - ngrp * sizeof(linux_gid_t)); - if (error) - return (error); - - pc->pc_ucred->cr_ngroups = ngrp + 1; - - bsd_gidset = pc->pc_ucred->cr_groups; - ngrp--; - while (ngrp >= 0) { - bsd_gidset[ngrp + 1] = linux_gidset[ngrp]; - ngrp--; - } - } - else - pc->pc_ucred->cr_ngroups = 1; - - setsugid(p); - return (0); -} - -int -linux_getgroups(p, uap) - struct proc *p; - struct linux_getgroups_args *uap; -{ - struct pcred *pc; - linux_gid_t linux_gidset[NGROUPS]; - gid_t *bsd_gidset; - int bsd_gidsetsz, ngrp, error; - - pc = p->p_cred; - bsd_gidset = pc->pc_ucred->cr_groups; - bsd_gidsetsz = pc->pc_ucred->cr_ngroups - 1; - - /* - * cr_groups[0] holds egid. Returning the whole set - * here will cause a duplicate. Exclude cr_groups[0] - * to prevent that. - */ - - if ((ngrp = uap->gidsetsize) == 0) { - p->p_retval[0] = bsd_gidsetsz; - return (0); - } - - if (ngrp < bsd_gidsetsz) - return (EINVAL); - - ngrp = 0; - while (ngrp < bsd_gidsetsz) { - linux_gidset[ngrp] = bsd_gidset[ngrp + 1]; - ngrp++; - } - - if ((error = copyout((caddr_t)linux_gidset, (caddr_t)uap->gidset, - ngrp * sizeof(linux_gid_t)))) - return (error); - - p->p_retval[0] = ngrp; - return (0); -} - -int -linux_setrlimit(p, uap) - struct proc *p; - struct linux_setrlimit_args *uap; -{ - struct osetrlimit_args bsd; - -#ifdef DEBUG - printf("Linux-emul(%ld): setrlimit(%d, %p)\n", - (long)p->p_pid, uap->resource, (void *)uap->rlim); -#endif - - if (uap->resource >= LINUX_RLIM_NLIMITS) - return EINVAL; - - bsd.which = linux_to_bsd_resource[uap->resource]; - - if (bsd.which == -1) - return EINVAL; - - bsd.rlp = uap->rlim; - return osetrlimit(p, &bsd); -} - -int -linux_getrlimit(p, uap) - struct proc *p; - struct linux_getrlimit_args *uap; -{ - struct ogetrlimit_args bsd; - -#ifdef DEBUG - printf("Linux-emul(%ld): getrlimit(%d, %p)\n", - (long)p->p_pid, uap->resource, (void *)uap->rlim); -#endif - - if (uap->resource >= LINUX_RLIM_NLIMITS) - return EINVAL; - - bsd.which = linux_to_bsd_resource[uap->resource]; - - if (bsd.which == -1) - return EINVAL; - - bsd.rlp = uap->rlim; - return ogetrlimit(p, &bsd); -} - -int -linux_sched_setscheduler(p, uap) - struct proc *p; - struct linux_sched_setscheduler_args *uap; -{ - struct sched_setscheduler_args bsd; - -#ifdef DEBUG - printf("Linux-emul(%ld): sched_setscheduler(%d, %d, %p)\n", - (long)p->p_pid, uap->pid, uap->policy, (const void *)uap->param); -#endif - - switch (uap->policy) { - case LINUX_SCHED_OTHER: - bsd.policy = SCHED_OTHER; - break; - case LINUX_SCHED_FIFO: - bsd.policy = SCHED_FIFO; - break; - case LINUX_SCHED_RR: - bsd.policy = SCHED_RR; - break; - default: - return EINVAL; - } - - bsd.pid = uap->pid; - bsd.param = uap->param; - return sched_setscheduler(p, &bsd); -} - -int -linux_sched_getscheduler(p, uap) - struct proc *p; - struct linux_sched_getscheduler_args *uap; -{ - struct sched_getscheduler_args bsd; - int error; - -#ifdef DEBUG - printf("Linux-emul(%ld): sched_getscheduler(%d)\n", - (long)p->p_pid, uap->pid); -#endif - - bsd.pid = uap->pid; - error = sched_getscheduler(p, &bsd); - - switch (p->p_retval[0]) { - case SCHED_OTHER: - p->p_retval[0] = LINUX_SCHED_OTHER; - break; - case SCHED_FIFO: - p->p_retval[0] = LINUX_SCHED_FIFO; - break; - case SCHED_RR: - p->p_retval[0] = LINUX_SCHED_RR; - break; - } - - return error; -} - -struct linux_descriptor { - unsigned int entry_number; - unsigned long base_addr; - unsigned int limit; - unsigned int seg_32bit:1; - unsigned int contents:2; - unsigned int read_exec_only:1; - unsigned int limit_in_pages:1; - unsigned int seg_not_present:1; - unsigned int useable:1; -}; - -int -linux_modify_ldt(p, uap) - struct proc *p; - struct linux_modify_ldt_args *uap; -{ - int error; - caddr_t sg; - struct sysarch_args args; - struct i386_ldt_args *ldt; - struct linux_descriptor ld; - union descriptor *desc; - - sg = stackgap_init(); - - if (uap->ptr == NULL) - return (EINVAL); - - switch (uap->func) { - case 0x00: /* read_ldt */ - ldt = stackgap_alloc(&sg, sizeof(*ldt)); - ldt->start = 0; - ldt->descs = uap->ptr; - ldt->num = uap->bytecount / sizeof(union descriptor); - args.op = I386_GET_LDT; - args.parms = (char*)ldt; - error = sysarch(p, &args); - p->p_retval[0] *= sizeof(union descriptor); - break; - case 0x01: /* write_ldt */ - case 0x11: /* write_ldt */ - if (uap->bytecount != sizeof(ld)) - return (EINVAL); - - error = copyin(uap->ptr, &ld, sizeof(ld)); - if (error) - return (error); - - ldt = stackgap_alloc(&sg, sizeof(*ldt)); - desc = stackgap_alloc(&sg, sizeof(*desc)); - ldt->start = ld.entry_number; - ldt->descs = desc; - ldt->num = 1; - desc->sd.sd_lolimit = (ld.limit & 0x0000ffff); - desc->sd.sd_hilimit = (ld.limit & 0x000f0000) >> 16; - desc->sd.sd_lobase = (ld.base_addr & 0x00ffffff); - desc->sd.sd_hibase = (ld.base_addr & 0xff000000) >> 24; - desc->sd.sd_type = SDT_MEMRO | ((ld.read_exec_only ^ 1) << 1) | - (ld.contents << 2); - desc->sd.sd_dpl = 3; - desc->sd.sd_p = (ld.seg_not_present ^ 1); - desc->sd.sd_xx = 0; - desc->sd.sd_def32 = ld.seg_32bit; - desc->sd.sd_gran = ld.limit_in_pages; - args.op = I386_SET_LDT; - args.parms = (char*)ldt; - error = sysarch(p, &args); - break; - default: - error = EINVAL; - break; - } - - if (error == EOPNOTSUPP) { - printf("linux: modify_ldt needs kernel option USER_LDT\n"); - error = ENOSYS; - } - - return (error); -} diff --git a/sys/i386/linux/linux_signal.c b/sys/i386/linux/linux_signal.c deleted file mode 100644 index ba4c481..0000000 --- a/sys/i386/linux/linux_signal.c +++ /dev/null @@ -1,555 +0,0 @@ -/*- - * 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. - * - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/sysproto.h> -#include <sys/proc.h> -#include <sys/signalvar.h> - -#include <i386/linux/linux.h> -#include <i386/linux/linux_proto.h> -#include <i386/linux/linux_util.h> - -static void -linux_to_bsd_sigset(linux_sigset_t *lss, sigset_t *bss) -{ - int b, l; - - SIGEMPTYSET(*bss); - bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1); - bss->__bits[1] = lss->__bits[1]; - for (l = 1; l <= LINUX_SIGTBLSZ; l++) { - if (LINUX_SIGISMEMBER(*lss, l)) { - b = linux_to_bsd_signal[_SIG_IDX(l)]; - if (b) - SIGADDSET(*bss, b); - } - } -} - -static void -bsd_to_linux_sigset(sigset_t *bss, linux_sigset_t *lss) -{ - int b, l; - - LINUX_SIGEMPTYSET(*lss); - lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1); - lss->__bits[1] = bss->__bits[1]; - for (b = 1; b <= LINUX_SIGTBLSZ; b++) { - if (SIGISMEMBER(*bss, b)) { - l = bsd_to_linux_signal[_SIG_IDX(b)]; - if (l) - LINUX_SIGADDSET(*lss, l); - } - } -} - -static void -linux_to_bsd_sigaction(linux_sigaction_t *lsa, struct sigaction *bsa) -{ - - linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask); - bsa->sa_handler = lsa->lsa_handler; - bsa->sa_flags = 0; - if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP) - bsa->sa_flags |= SA_NOCLDSTOP; - if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT) - bsa->sa_flags |= SA_NOCLDWAIT; - if (lsa->lsa_flags & LINUX_SA_SIGINFO) - bsa->sa_flags |= SA_SIGINFO; - if (lsa->lsa_flags & LINUX_SA_ONSTACK) - bsa->sa_flags |= SA_ONSTACK; - if (lsa->lsa_flags & LINUX_SA_RESTART) - bsa->sa_flags |= SA_RESTART; - if (lsa->lsa_flags & LINUX_SA_ONESHOT) - bsa->sa_flags |= SA_RESETHAND; - if (lsa->lsa_flags & LINUX_SA_NOMASK) - bsa->sa_flags |= SA_NODEFER; -} - -static void -bsd_to_linux_sigaction(struct sigaction *bsa, linux_sigaction_t *lsa) -{ - - bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask); - lsa->lsa_handler = bsa->sa_handler; - lsa->lsa_restorer = NULL; /* unsupported */ - lsa->lsa_flags = 0; - if (bsa->sa_flags & SA_NOCLDSTOP) - lsa->lsa_flags |= LINUX_SA_NOCLDSTOP; - if (bsa->sa_flags & SA_NOCLDWAIT) - lsa->lsa_flags |= LINUX_SA_NOCLDWAIT; - if (bsa->sa_flags & SA_SIGINFO) - lsa->lsa_flags |= LINUX_SA_SIGINFO; - if (bsa->sa_flags & SA_ONSTACK) - lsa->lsa_flags |= LINUX_SA_ONSTACK; - if (bsa->sa_flags & SA_RESTART) - lsa->lsa_flags |= LINUX_SA_RESTART; - if (bsa->sa_flags & SA_RESETHAND) - lsa->lsa_flags |= LINUX_SA_ONESHOT; - if (bsa->sa_flags & SA_NODEFER) - lsa->lsa_flags |= LINUX_SA_NOMASK; -} - -static int -linux_do_sigaction(struct proc *p, int linux_sig, linux_sigaction_t *linux_nsa, - linux_sigaction_t *linux_osa) -{ - struct sigaction *nsa, *osa; - struct sigaction_args sa_args; - int error; - caddr_t sg = stackgap_init(); - - if (linux_sig <= 0 || linux_sig > LINUX_NSIG) - return (EINVAL); - - if (linux_osa != NULL) - osa = stackgap_alloc(&sg, sizeof(struct sigaction)); - else - osa = NULL; - - if (linux_nsa != NULL) { - nsa = stackgap_alloc(&sg, sizeof(struct sigaction)); - linux_to_bsd_sigaction(linux_nsa, nsa); - } - else - nsa = NULL; - - if (linux_sig <= LINUX_SIGTBLSZ) - sa_args.sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)]; - else - sa_args.sig = linux_sig; - - sa_args.act = nsa; - sa_args.oact = osa; - error = sigaction(p, &sa_args); - if (error) - return (error); - - if (linux_osa != NULL) - bsd_to_linux_sigaction(osa, linux_osa); - - return (0); -} - -int -linux_sigaction(struct proc *p, struct linux_sigaction_args *args) -{ - linux_osigaction_t osa; - linux_sigaction_t act, oact; - int error; - -#ifdef DEBUG - printf("Linux-emul(%ld): sigaction(%d, %p, %p)\n", (long)p->p_pid, - args->sig, (void *)args->nsa, (void *)args->osa); -#endif - - if (args->nsa != NULL) { - error = copyin(args->nsa, &osa, sizeof(linux_osigaction_t)); - if (error) - return (error); - act.lsa_handler = osa.lsa_handler; - act.lsa_flags = osa.lsa_flags; - act.lsa_restorer = osa.lsa_restorer; - LINUX_SIGEMPTYSET(act.lsa_mask); - act.lsa_mask.__bits[0] = osa.lsa_mask; - } - - error = linux_do_sigaction(p, args->sig, - args->nsa ? &act : NULL, - args->osa ? &oact : NULL); - - if (args->osa != NULL && !error) { - osa.lsa_handler = oact.lsa_handler; - osa.lsa_flags = oact.lsa_flags; - osa.lsa_restorer = oact.lsa_restorer; - osa.lsa_mask = oact.lsa_mask.__bits[0]; - error = copyout(&osa, args->osa, sizeof(linux_osigaction_t)); - } - - return (error); -} - -int -linux_signal(struct proc *p, struct linux_signal_args *args) -{ - linux_sigaction_t nsa, osa; - int error; - -#ifdef DEBUG - printf("Linux-emul(%ld): signal(%d, %p)\n", - (long)p->p_pid, args->sig, (void *)args->handler); -#endif - - nsa.lsa_handler = args->handler; - nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK; - LINUX_SIGEMPTYSET(nsa.lsa_mask); - - error = linux_do_sigaction(p, args->sig, &nsa, &osa); - p->p_retval[0] = (int)osa.lsa_handler; - - return (error); -} - -int -linux_rt_sigaction(struct proc *p, struct linux_rt_sigaction_args *args) -{ - linux_sigaction_t nsa, osa; - int error; - -#ifdef DEBUG - printf("Linux-emul(%ld): rt_sigaction(%d, %p, %p, %d)\n", - (long)p->p_pid, args->sig, (void *)args->act, - (void *)args->oact, args->sigsetsize); -#endif - - if (args->sigsetsize != sizeof(linux_sigset_t)) - return (EINVAL); - - if (args->act != NULL) { - error = copyin(args->act, &nsa, sizeof(linux_sigaction_t)); - if (error) - return (error); - } - - error = linux_do_sigaction(p, args->sig, - args->act ? &nsa : NULL, - args->oact ? &osa : NULL); - - if (args->oact != NULL && !error) { - error = copyout(&osa, args->oact, sizeof(linux_sigaction_t)); - } - - return (error); -} - -static int -linux_do_sigprocmask(struct proc *p, int how, linux_sigset_t *new, - linux_sigset_t *old) -{ - int error, s; - sigset_t mask; - - error = 0; - p->p_retval[0] = 0; - - if (old != NULL) - bsd_to_linux_sigset(&p->p_sigmask, old); - - if (new != NULL) { - linux_to_bsd_sigset(new, &mask); - - s = splhigh(); - - switch (how) { - case LINUX_SIG_BLOCK: - SIGSETOR(p->p_sigmask, mask); - SIG_CANTMASK(p->p_sigmask); - break; - case LINUX_SIG_UNBLOCK: - SIGSETNAND(p->p_sigmask, mask); - break; - case LINUX_SIG_SETMASK: - p->p_sigmask = mask; - SIG_CANTMASK(p->p_sigmask); - break; - default: - error = EINVAL; - break; - } - - splx(s); - } - - return (error); -} - -int -linux_sigprocmask(struct proc *p, struct linux_sigprocmask_args *args) -{ - linux_osigset_t mask; - linux_sigset_t set, oset; - int error; - -#ifdef DEBUG - printf("Linux-emul(%d): sigprocmask(%d, *, *)\n", p->p_pid, args->how); -#endif - - if (args->mask != NULL) { - error = copyin(args->mask, &mask, sizeof(linux_osigset_t)); - if (error) - return (error); - LINUX_SIGEMPTYSET(set); - set.__bits[0] = mask; - } - - error = linux_do_sigprocmask(p, args->how, - args->mask ? &set : NULL, - args->omask ? &oset : NULL); - - if (args->omask != NULL && !error) { - mask = oset.__bits[0]; - error = copyout(&mask, args->omask, sizeof(linux_osigset_t)); - } - - return (error); -} - -int -linux_rt_sigprocmask(struct proc *p, struct linux_rt_sigprocmask_args *args) -{ - linux_sigset_t set, oset; - int error; - -#ifdef DEBUG - printf("Linux-emul(%ld): rt_sigprocmask(%d, %p, %p, %d)\n", - (long)p->p_pid, args->how, (void *)args->mask, - (void *)args->omask, args->sigsetsize); -#endif - - if (args->sigsetsize != sizeof(linux_sigset_t)) - return EINVAL; - - if (args->mask != NULL) { - error = copyin(args->mask, &set, sizeof(linux_sigset_t)); - if (error) - return (error); - } - - error = linux_do_sigprocmask(p, args->how, - args->mask ? &set : NULL, - args->omask ? &oset : NULL); - - if (args->omask != NULL && !error) { - error = copyout(&oset, args->omask, sizeof(linux_sigset_t)); - } - - return (error); -} - -int -linux_siggetmask(struct proc *p, struct linux_siggetmask_args *args) -{ - linux_sigset_t mask; - -#ifdef DEBUG - printf("Linux-emul(%d): siggetmask()\n", p->p_pid); -#endif - - bsd_to_linux_sigset(&p->p_sigmask, &mask); - p->p_retval[0] = mask.__bits[0]; - return (0); -} - -int -linux_sigsetmask(struct proc *p, struct linux_sigsetmask_args *args) -{ - linux_sigset_t lset; - sigset_t bset; - int s; - -#ifdef DEBUG - printf("Linux-emul(%ld): sigsetmask(%08lx)\n", - (long)p->p_pid, (unsigned long)args->mask); -#endif - - bsd_to_linux_sigset(&p->p_sigmask, &lset); - p->p_retval[0] = lset.__bits[0]; - LINUX_SIGEMPTYSET(lset); - lset.__bits[0] = args->mask; - linux_to_bsd_sigset(&lset, &bset); - s = splhigh(); - p->p_sigmask = bset; - SIG_CANTMASK(p->p_sigmask); - splx(s); - return (0); -} - -int -linux_sigpending(struct proc *p, struct linux_sigpending_args *args) -{ - sigset_t bset; - linux_sigset_t lset; - linux_osigset_t mask; - -#ifdef DEBUG - printf("Linux-emul(%d): sigpending(*)\n", p->p_pid); -#endif - - bset = p->p_siglist; - SIGSETAND(bset, p->p_sigmask); - bsd_to_linux_sigset(&bset, &lset); - mask = lset.__bits[0]; - return (copyout(&mask, args->mask, sizeof(mask))); -} - -/* - * Linux has two extra args, restart and oldmask. We dont use these, - * but it seems that "restart" is actually a context pointer that - * enables the signal to happen with a different register set. - */ -int -linux_sigsuspend(struct proc *p, struct linux_sigsuspend_args *args) -{ - struct sigsuspend_args bsd; - sigset_t *sigmask; - linux_sigset_t mask; - caddr_t sg = stackgap_init(); - -#ifdef DEBUG - printf("Linux-emul(%ld): sigsuspend(%08lx)\n", - (long)p->p_pid, (unsigned long)args->mask); -#endif - - sigmask = stackgap_alloc(&sg, sizeof(sigset_t)); - LINUX_SIGEMPTYSET(mask); - mask.__bits[0] = args->mask; - linux_to_bsd_sigset(&mask, sigmask); - bsd.sigmask = sigmask; - return (sigsuspend(p, &bsd)); -} - -int -linux_rt_sigsuspend(p, uap) - struct proc *p; - struct linux_rt_sigsuspend_args *uap; -{ - linux_sigset_t lmask; - sigset_t *bmask; - struct sigsuspend_args bsd; - caddr_t sg = stackgap_init(); - int error; - -#ifdef DEBUG - printf("Linux-emul(%ld): rt_sigsuspend(%p, %d)\n", (long)p->p_pid, - (void *)uap->newset, uap->sigsetsize); -#endif - - if (uap->sigsetsize != sizeof(linux_sigset_t)) - return (EINVAL); - - error = copyin(uap->newset, &lmask, sizeof(linux_sigset_t)); - if (error) - return (error); - - bmask = stackgap_alloc(&sg, sizeof(sigset_t)); - linux_to_bsd_sigset(&lmask, bmask); - bsd.sigmask = bmask; - return (sigsuspend(p, &bsd)); -} - -int -linux_pause(struct proc *p, struct linux_pause_args *args) -{ - struct sigsuspend_args bsd; - sigset_t *sigmask; - caddr_t sg = stackgap_init(); - -#ifdef DEBUG - printf("Linux-emul(%d): pause()\n", p->p_pid); -#endif - - sigmask = stackgap_alloc(&sg, sizeof(sigset_t)); - *sigmask = p->p_sigmask; - bsd.sigmask = sigmask; - return sigsuspend(p, &bsd); -} - -int -linux_kill(struct proc *p, struct linux_kill_args *args) -{ - struct kill_args /* { - int pid; - int signum; - } */ tmp; - -#ifdef DEBUG - printf("Linux-emul(%d): kill(%d, %d)\n", - p->p_pid, args->pid, args->signum); -#endif - - /* - * Allow signal 0 as a means to check for privileges - */ - if (args->signum < 0 || args->signum > LINUX_NSIG) - return EINVAL; - - if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ) - tmp.signum = linux_to_bsd_signal[_SIG_IDX(args->signum)]; - else - tmp.signum = args->signum; - - tmp.pid = args->pid; - return (kill(p, &tmp)); -} - -int -linux_sigaltstack(p, uap) - struct proc *p; - struct linux_sigaltstack_args *uap; -{ - struct sigaltstack_args bsd; - stack_t *ss, *oss; - linux_stack_t lss; - int error; - caddr_t sg = stackgap_init(); - -#ifdef DEBUG - printf("Linux-emul(%ld): sigaltstack(%p, %p)\n", - (long)p->p_pid, uap->uss, uap->uoss); -#endif - - error = copyin(uap->uss, &lss, sizeof(linux_stack_t)); - if (error) - return (error); - - ss = stackgap_alloc(&sg, sizeof(stack_t)); - ss->ss_sp = lss.ss_sp; - ss->ss_size = lss.ss_size; - ss->ss_flags = lss.ss_flags; - - oss = (uap->uoss != NULL) - ? stackgap_alloc(&sg, sizeof(stack_t)) - : NULL; - - bsd.ss = ss; - bsd.oss = oss; - error = sigaltstack(p, &bsd); - - if (!error && oss != NULL) { - lss.ss_sp = oss->ss_sp; - lss.ss_size = oss->ss_size; - lss.ss_flags = oss->ss_flags; - error = copyout(&lss, uap->uoss, sizeof(linux_stack_t)); - } - - return (error); -} diff --git a/sys/i386/linux/linux_socket.c b/sys/i386/linux/linux_socket.c deleted file mode 100644 index d2be9b9..0000000 --- a/sys/i386/linux/linux_socket.c +++ /dev/null @@ -1,874 +0,0 @@ -/*- - * 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. - * - * $FreeBSD$ - */ - -/* XXX we use functions that might not exist. */ -#include "opt_compat.h" - -#ifndef COMPAT_43 -#error "Unable to compile Linux-emulator due to missing COMPAT_43 option!" -#endif - -#include <sys/param.h> -#include <sys/proc.h> -#include <sys/systm.h> -#include <sys/sysproto.h> -#include <sys/fcntl.h> -#include <sys/socket.h> -#include <sys/uio.h> - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> - -#include <i386/linux/linux.h> -#include <i386/linux/linux_proto.h> -#include <i386/linux/linux_util.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; - case LINUX_IP_OPTIONS: - return IP_OPTIONS; - case LINUX_IP_MULTICAST_IF: - return IP_MULTICAST_IF; - case LINUX_IP_MULTICAST_TTL: - return IP_MULTICAST_TTL; - case LINUX_IP_MULTICAST_LOOP: - return IP_MULTICAST_LOOP; - case LINUX_IP_ADD_MEMBERSHIP: - return IP_ADD_MEMBERSHIP; - case LINUX_IP_DROP_MEMBERSHIP: - return IP_DROP_MEMBERSHIP; - case LINUX_IP_HDRINCL: - return IP_HDRINCL; - 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; - } -} - -/* Return 0 if IP_HDRINCL is set of the given socket, not 0 otherwise */ -static int -linux_check_hdrincl(struct proc *p, int s) -{ - struct getsockopt_args /* { - int s; - int level; - int name; - caddr_t val; - int *avalsize; - } */ bsd_args; - int error; - caddr_t sg, val, valsize; - int size_val = sizeof val; - int optval; - - sg = stackgap_init(); - val = stackgap_alloc(&sg, sizeof(int)); - valsize = stackgap_alloc(&sg, sizeof(int)); - - if ((error=copyout(&size_val, valsize, sizeof(size_val)))) - return error; - bsd_args.s = s; - bsd_args.level = IPPROTO_IP; - bsd_args.name = IP_HDRINCL; - bsd_args.val = val; - bsd_args.avalsize = (int *)valsize; - if ((error=getsockopt(p, &bsd_args))) - return error; - if ((error=copyin(val, &optval, sizeof(optval)))) - return error; - return optval == 0; -} - -/* - * Updated sendto() when IP_HDRINCL is set: - * tweak endian-dependent fields in the IP packet. - */ -static int -linux_sendto_hdrincl(struct proc *p, struct sendto_args *bsd_args) -{ -/* - * linux_ip_copysize defines how many bytes we should copy - * from the beginning of the IP packet before we customize it for BSD. - * It should include all the fields we modify (ip_len and ip_off) - * and be as small as possible to minimize copying overhead. - */ -#define linux_ip_copysize 8 - - caddr_t sg; - struct ip *packet; - struct msghdr *msg; - struct iovec *iov; - - int error; - struct sendmsg_args /* { - int s; - caddr_t msg; - int flags; - } */ sendmsg_args; - - /* Check the packet isn't too small before we mess with it */ - if (bsd_args->len < linux_ip_copysize) - return EINVAL; - - /* - * Tweaking the user buffer in place would be bad manners. - * We create a corrected IP header with just the needed length, - * then use an iovec to glue it to the rest of the user packet - * when calling sendmsg(). - */ - sg = stackgap_init(); - packet = (struct ip *)stackgap_alloc(&sg, linux_ip_copysize); - msg = (struct msghdr *)stackgap_alloc(&sg, sizeof(*msg)); - iov = (struct iovec *)stackgap_alloc(&sg, sizeof(*iov)*2); - - /* Make a copy of the beginning of the packet to be sent */ - if ((error = copyin(bsd_args->buf, (caddr_t)packet, linux_ip_copysize))) - return error; - - /* Convert fields from Linux to BSD raw IP socket format */ - packet->ip_len = bsd_args->len; - packet->ip_off = ntohs(packet->ip_off); - - /* Prepare the msghdr and iovec structures describing the new packet */ - msg->msg_name = bsd_args->to; - msg->msg_namelen = bsd_args->tolen; - msg->msg_iov = iov; - msg->msg_iovlen = 2; - msg->msg_control = NULL; - msg->msg_controllen = 0; - msg->msg_flags = 0; - iov[0].iov_base = (char *)packet; - iov[0].iov_len = linux_ip_copysize; - iov[1].iov_base = (char *)(bsd_args->buf) + linux_ip_copysize; - iov[1].iov_len = bsd_args->len - linux_ip_copysize; - - sendmsg_args.s = bsd_args->s; - sendmsg_args.msg = (caddr_t)msg; - sendmsg_args.flags = bsd_args->flags; - return sendmsg(p, &sendmsg_args); -} - -struct linux_socket_args { - int domain; - int type; - int protocol; -}; - -static int -linux_socket(struct proc *p, struct linux_socket_args *args) -{ - struct linux_socket_args linux_args; - struct socket_args /* { - int domain; - int type; - int protocol; - } */ bsd_args; - int error; - int retval_socket; - - 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; - - retval_socket = socket(p, &bsd_args); - if (bsd_args.type == SOCK_RAW - && (bsd_args.protocol == IPPROTO_RAW || bsd_args.protocol == 0) - && bsd_args.domain == AF_INET - && retval_socket >= 0) { - /* It's a raw IP socket: set the IP_HDRINCL option. */ - struct setsockopt_args /* { - int s; - int level; - int name; - caddr_t val; - int valsize; - } */ bsd_setsockopt_args; - caddr_t sg; - int *hdrincl; - - sg = stackgap_init(); - hdrincl = (int *)stackgap_alloc(&sg, sizeof(*hdrincl)); - *hdrincl = 1; - bsd_setsockopt_args.s = p->p_retval[0]; - bsd_setsockopt_args.level = IPPROTO_IP; - bsd_setsockopt_args.name = IP_HDRINCL; - bsd_setsockopt_args.val = (caddr_t)hdrincl; - bsd_setsockopt_args.valsize = sizeof(*hdrincl); - /* We ignore any error returned by setsockopt() */ - setsockopt(p, &bsd_setsockopt_args); - /* Copy back the return value from socket() */ - p->p_retval[0] = bsd_setsockopt_args.s; - } - return retval_socket; -} - -struct linux_bind_args { - int s; - struct sockaddr *name; - int namelen; -}; - -static int -linux_bind(struct proc *p, struct linux_bind_args *args) -{ - struct linux_bind_args linux_args; - struct bind_args /* { - 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); -} - -struct linux_connect_args { - int s; - struct sockaddr * name; - int namelen; -}; - -static int -linux_connect(struct proc *p, struct linux_connect_args *args) -{ - struct linux_connect_args linux_args; - struct connect_args /* { - 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; - error = connect(p, &bsd_args); - if (error == EISCONN) { - /* - * Linux doesn't return EISCONN the first time it occurs, - * when on a non-blocking socket. Instead it returns the - * error getsockopt(SOL_SOCKET, SO_ERROR) would return on BSD. - */ - struct fcntl_args /* { - int fd; - int cmd; - int arg; - } */ bsd_fcntl_args; - struct getsockopt_args /* { - int s; - int level; - int name; - caddr_t val; - int *avalsize; - } */ bsd_getsockopt_args; - void *status, *statusl; - int stat, statl = sizeof stat; - caddr_t sg; - - /* Check for non-blocking */ - bsd_fcntl_args.fd = linux_args.s; - bsd_fcntl_args.cmd = F_GETFL; - bsd_fcntl_args.arg = 0; - error = fcntl(p, &bsd_fcntl_args); - if (error == 0 && (p->p_retval[0] & O_NONBLOCK)) { - sg = stackgap_init(); - status = stackgap_alloc(&sg, sizeof stat); - statusl = stackgap_alloc(&sg, sizeof statusl); - - if ((error = copyout(&statl, statusl, sizeof statl))) - return error; - - bsd_getsockopt_args.s = linux_args.s; - bsd_getsockopt_args.level = SOL_SOCKET; - bsd_getsockopt_args.name = SO_ERROR; - bsd_getsockopt_args.val = status; - bsd_getsockopt_args.avalsize = statusl; - - error = getsockopt(p, &bsd_getsockopt_args); - if (error) - return error; - if ((error = copyin(status, &stat, sizeof stat))) - return error; - p->p_retval[0] = stat; - return 0; - } - } - return error; -} - -struct linux_listen_args { - int s; - int backlog; -}; - -static int -linux_listen(struct proc *p, struct linux_listen_args *args) -{ - struct linux_listen_args linux_args; - struct listen_args /* { - 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); -} - -struct linux_accept_args { - int s; - struct sockaddr *addr; - int *namelen; -}; - -static int -linux_accept(struct proc *p, struct linux_accept_args *args) -{ - struct linux_accept_args linux_args; - struct accept_args /* { - int s; - caddr_t name; - int *anamelen; - } */ bsd_args; - struct fcntl_args /* { - int fd; - int cmd; - long arg; - } */ f_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; - error = oaccept(p, &bsd_args); - if (error) - return (error); - - /* - * linux appears not to copy flags from the parent socket to the - * accepted one, so we must clear the flags in the new descriptor. - * Ignore any errors, because we already have an open fd. - */ - f_args.fd = p->p_retval[0]; - f_args.cmd = F_SETFL; - f_args.arg = 0; - (void)fcntl(p, &f_args); - p->p_retval[0] = f_args.fd; - return (0); -} - -struct linux_getsockname_args { - int s; - struct sockaddr *addr; - int *namelen; -}; - -static int -linux_getsockname(struct proc *p, struct linux_getsockname_args *args) -{ - struct linux_getsockname_args linux_args; - struct getsockname_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 ogetsockname(p, &bsd_args); -} - -struct linux_getpeername_args { - int s; - struct sockaddr *addr; - int *namelen; -}; - -static int -linux_getpeername(struct proc *p, struct linux_getpeername_args *args) -{ - struct linux_getpeername_args linux_args; - struct ogetpeername_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); -} - -struct linux_socketpair_args { - int domain; - int type; - int protocol; - int *rsv; -}; - -static int -linux_socketpair(struct proc *p, struct linux_socketpair_args *args) -{ - struct linux_socketpair_args linux_args; - struct socketpair_args /* { - 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); -} - -struct linux_send_args { - int s; - void *msg; - int len; - int flags; -}; - -static int -linux_send(struct proc *p, struct linux_send_args *args) -{ - struct linux_send_args linux_args; - struct osend_args /* { - 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); -} - -struct linux_recv_args { - int s; - void *msg; - int len; - int flags; -}; - -static int -linux_recv(struct proc *p, struct linux_recv_args *args) -{ - struct linux_recv_args linux_args; - struct orecv_args /* { - 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); -} - -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) -{ - struct linux_sendto_args linux_args; - struct sendto_args /* { - 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; - - if (linux_check_hdrincl(p, linux_args.s) == 0) - /* IP_HDRINCL set, tweak the packet before sending */ - return linux_sendto_hdrincl(p, &bsd_args); - - return sendto(p, &bsd_args); -} - -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) -{ - struct linux_recvfrom_args linux_args; - struct recvfrom_args /* { - 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); -} - -struct linux_shutdown_args { - int s; - int how; -}; - -static int -linux_shutdown(struct proc *p, struct linux_shutdown_args *args) -{ - struct linux_shutdown_args linux_args; - struct shutdown_args /* { - 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); -} - -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) -{ - struct linux_setsockopt_args linux_args; - struct setsockopt_args /* { - 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; - case IPPROTO_TCP: - /* Linux TCP option values match BSD's */ - name = 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); -} - -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) -{ - struct linux_getsockopt_args linux_args; - struct getsockopt_args /* { - 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; - case IPPROTO_TCP: - /* Linux TCP option values match BSD's */ - name = linux_args.optname; - break; - default: - return EINVAL; - } - if (name == -1) - return EINVAL; - bsd_args.name = name; - bsd_args.val = linux_args.optval; - bsd_args.avalsize = linux_args.optlen; - return getsockopt(p, &bsd_args); -} - -int -linux_socketcall(struct proc *p, struct linux_socketcall_args *args) -{ - switch (args->what) { - case LINUX_SOCKET: - return linux_socket(p, args->args); - case LINUX_BIND: - return linux_bind(p, args->args); - case LINUX_CONNECT: - return linux_connect(p, args->args); - case LINUX_LISTEN: - return linux_listen(p, args->args); - case LINUX_ACCEPT: - return linux_accept(p, args->args); - case LINUX_GETSOCKNAME: - return linux_getsockname(p, args->args); - case LINUX_GETPEERNAME: - return linux_getpeername(p, args->args); - case LINUX_SOCKETPAIR: - return linux_socketpair(p, args->args); - case LINUX_SEND: - return linux_send(p, args->args); - case LINUX_RECV: - return linux_recv(p, args->args); - case LINUX_SENDTO: - return linux_sendto(p, args->args); - case LINUX_RECVFROM: - return linux_recvfrom(p, args->args); - case LINUX_SHUTDOWN: - return linux_shutdown(p, args->args); - case LINUX_SETSOCKOPT: - return linux_setsockopt(p, args->args); - case LINUX_GETSOCKOPT: - return linux_getsockopt(p, args->args); - case LINUX_SENDMSG: - do { - int error; - int level; - caddr_t control; - struct { - int s; - const struct msghdr *msg; - int flags; - } *uap = args->args; - - error = copyin(&uap->msg->msg_control, - &control, sizeof(caddr_t)); - if (error) - return error; - if (control == NULL) - goto done; - error = copyin(&((struct cmsghdr *)control)->cmsg_level, - &level, sizeof(int)); - if (error) - return error; - if (level == 1) { - /* - * Linux thinks that SOL_SOCKET is 1; we know that it's really - * 0xffff, of course. - */ - level = SOL_SOCKET; - error = copyout(&level, &((struct cmsghdr *)control)-> - cmsg_level, sizeof(int)); - if (error) - return error; - } - done: - return sendmsg(p, args->args); - } while (0); - case LINUX_RECVMSG: - return recvmsg(p, args->args); - - default: - uprintf("LINUX: 'socket' typ=%d not implemented\n", args->what); - return ENOSYS; - } -} diff --git a/sys/i386/linux/linux_stats.c b/sys/i386/linux/linux_stats.c deleted file mode 100644 index 566a618..0000000 --- a/sys/i386/linux/linux_stats.c +++ /dev/null @@ -1,378 +0,0 @@ -/*- - * 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. - * - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/conf.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/systm.h> -#include <sys/vnode.h> - -#include <i386/linux/linux.h> -#include <i386/linux/linux_proto.h> -#include <i386/linux/linux_util.h> - - -struct linux_newstat { - u_short stat_dev; - u_short __pad1; - u_long stat_ino; - u_short stat_mode; - u_short stat_nlink; - u_short stat_uid; - u_short stat_gid; - u_short stat_rdev; - u_short __pad2; - u_long stat_size; - u_long stat_blksize; - u_long stat_blocks; - u_long stat_atime; - u_long __unused1; - u_long stat_mtime; - u_long __unused2; - u_long stat_ctime; - u_long __unused3; - u_long __unused4; - u_long __unused5; -}; - -struct linux_ustat -{ - int f_tfree; - u_long f_tinode; - char f_fname[6]; - char f_fpack[6]; -}; - -static int -newstat_copyout(struct stat *buf, void *ubuf) -{ - struct linux_newstat tbuf; - - tbuf.stat_dev = uminor(buf->st_dev) | (umajor(buf->st_dev) << 8); - 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) -{ - struct stat buf; - struct nameidata nd; - int error; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTEXIST(p, &sg, args->path); - -#ifdef DEBUG - printf("Linux-emul(%ld): newstat(%s, *)\n", (long)p->p_pid, - args->path); -#endif - - NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, - args->path, p); - error = namei(&nd); - if (error) - return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); - - error = vn_stat(nd.ni_vp, &buf, p); - vput(nd.ni_vp); - if (error) - return (error); - - return (newstat_copyout(&buf, args->buf)); -} - -/* - * Get file status; this version does not follow links. - */ -int -linux_newlstat(p, uap) - struct proc *p; - struct linux_newlstat_args *uap; -{ - int error; - struct vnode *vp; - struct stat sb; - struct nameidata nd; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTEXIST(p, &sg, uap->path); - -#ifdef DEBUG - printf("Linux-emul(%ld): newlstat(%s, *)\n", (long)p->p_pid, - uap->path); -#endif - - NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, - uap->path, p); - error = namei(&nd); - if (error) - return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); - - vp = nd.ni_vp; - error = vn_stat(vp, &sb, p); - vput(vp); - if (error) - return (error); - - return (newstat_copyout(&sb, uap->buf)); -} - -int -linux_newfstat(struct proc *p, struct linux_newfstat_args *args) -{ - struct filedesc *fdp; - struct file *fp; - struct stat buf; - int error; - - fdp = p->p_fd; - -#ifdef DEBUG - printf("Linux-emul(%ld): newfstat(%d, *)\n", (long)p->p_pid, args->fd); -#endif - - if ((unsigned)args->fd >= fdp->fd_nfiles || - (fp = fdp->fd_ofiles[args->fd]) == NULL) - return (EBADF); - - error = fo_stat(fp, &buf, p); - if (!error) - error = newstat_copyout(&buf, args->buf); - - return (error); -} - -struct linux_statfs_buf { - long ftype; - long fbsize; - long fblocks; - long fbfree; - long fbavail; - long ffiles; - long fffree; - linux_fsid_t ffsid; - long fnamelen; - long fspare[6]; -}; - -#ifndef VT_NWFS -#define VT_NWFS VT_TFS /* XXX - bug compatibility with sys/nwfs/nwfs_node.h */ -#endif - -#define LINUX_CODA_SUPER_MAGIC 0x73757245L -#define LINUX_EXT2_SUPER_MAGIC 0xEF53L -#define LINUX_HPFS_SUPER_MAGIC 0xf995e849L -#define LINUX_ISOFS_SUPER_MAGIC 0x9660L -#define LINUX_MSDOS_SUPER_MAGIC 0x4d44L -#define LINUX_NCP_SUPER_MAGIC 0x564cL -#define LINUX_NFS_SUPER_MAGIC 0x6969L -#define LINUX_NTFS_SUPER_MAGIC 0x5346544EL -#define LINUX_PROC_SUPER_MAGIC 0x9fa0L -#define LINUX_UFS_SUPER_MAGIC 0x00011954L /* XXX - UFS_MAGIC in Linux */ - -/* - * ext2fs uses the VT_UFS tag. A mounted ext2 filesystem will therefore - * be seen as an ufs/mfs filesystem. - */ -static long -bsd_to_linux_ftype(int tag) -{ - - switch (tag) { - case VT_CODA: - return (LINUX_CODA_SUPER_MAGIC); - case VT_HPFS: - return (LINUX_HPFS_SUPER_MAGIC); - case VT_ISOFS: - return (LINUX_ISOFS_SUPER_MAGIC); - case VT_MFS: - return (LINUX_UFS_SUPER_MAGIC); - case VT_MSDOSFS: - return (LINUX_MSDOS_SUPER_MAGIC); - case VT_NFS: - return (LINUX_NFS_SUPER_MAGIC); - case VT_NTFS: - return (LINUX_NTFS_SUPER_MAGIC); - case VT_NWFS: - return (LINUX_NCP_SUPER_MAGIC); - case VT_PROCFS: - return (LINUX_PROC_SUPER_MAGIC); - case VT_UFS: - return (LINUX_UFS_SUPER_MAGIC); - } - - return (0L); -} - -int -linux_statfs(struct proc *p, struct linux_statfs_args *args) -{ - struct mount *mp; - struct nameidata *ndp; - struct statfs *bsd_statfs; - struct nameidata nd; - struct linux_statfs_buf linux_statfs_buf; - int error; - caddr_t sg; - - sg = stackgap_init(); - CHECKALTEXIST(p, &sg, args->path); - -#ifdef DEBUG - printf("Linux-emul(%d): statfs(%s, *)\n", p->p_pid, args->path); -#endif - ndp = &nd; - NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args->path, curproc); - error = namei(ndp); - if (error) - return error; - NDFREE(ndp, NDF_ONLY_PNBUF); - mp = ndp->ni_vp->v_mount; - bsd_statfs = &mp->mnt_stat; - vrele(ndp->ni_vp); - error = VFS_STATFS(mp, bsd_statfs, p); - if (error) - return error; - bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; - linux_statfs_buf.ftype = bsd_to_linux_ftype(bsd_statfs->f_type); - linux_statfs_buf.fbsize = bsd_statfs->f_bsize; - linux_statfs_buf.fblocks = bsd_statfs->f_blocks; - linux_statfs_buf.fbfree = bsd_statfs->f_bfree; - linux_statfs_buf.fbavail = bsd_statfs->f_bavail; - linux_statfs_buf.fffree = bsd_statfs->f_ffree; - linux_statfs_buf.ffiles = bsd_statfs->f_files; - linux_statfs_buf.ffsid.val[0] = bsd_statfs->f_fsid.val[0]; - linux_statfs_buf.ffsid.val[1] = bsd_statfs->f_fsid.val[1]; - linux_statfs_buf.fnamelen = MAXNAMLEN; - return copyout((caddr_t)&linux_statfs_buf, (caddr_t)args->buf, - sizeof(struct linux_statfs_buf)); -} - -int -linux_fstatfs(struct proc *p, struct linux_fstatfs_args *args) -{ - struct file *fp; - struct mount *mp; - struct statfs *bsd_statfs; - struct linux_statfs_buf linux_statfs_buf; - int error; - -#ifdef DEBUG - printf("Linux-emul(%d): fstatfs(%d, *)\n", p->p_pid, args->fd); -#endif - error = getvnode(p->p_fd, args->fd, &fp); - if (error) - return error; - mp = ((struct vnode *)fp->f_data)->v_mount; - bsd_statfs = &mp->mnt_stat; - error = VFS_STATFS(mp, bsd_statfs, p); - if (error) - return error; - bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; - linux_statfs_buf.ftype = bsd_to_linux_ftype(bsd_statfs->f_type); - linux_statfs_buf.fbsize = bsd_statfs->f_bsize; - linux_statfs_buf.fblocks = bsd_statfs->f_blocks; - linux_statfs_buf.fbfree = bsd_statfs->f_bfree; - linux_statfs_buf.fbavail = bsd_statfs->f_bavail; - linux_statfs_buf.fffree = bsd_statfs->f_ffree; - linux_statfs_buf.ffiles = bsd_statfs->f_files; - linux_statfs_buf.ffsid.val[0] = bsd_statfs->f_fsid.val[0]; - linux_statfs_buf.ffsid.val[1] = bsd_statfs->f_fsid.val[1]; - linux_statfs_buf.fnamelen = MAXNAMLEN; - return copyout((caddr_t)&linux_statfs_buf, (caddr_t)args->buf, - sizeof(struct linux_statfs_buf)); -} - -int -linux_ustat(p, uap) - struct proc *p; - struct linux_ustat_args *uap; -{ - struct linux_ustat lu; - dev_t dev; - struct vnode *vp; - struct statfs *stat; - int error; - -#ifdef DEBUG - printf("Linux-emul(%ld): ustat(%d, *)\n", (long)p->p_pid, uap->dev); -#endif - - /* - * lu.f_fname and lu.f_fpack are not used. They are always zeroed. - * lu.f_tinode and lu.f_tfree are set from the device's super block. - */ - bzero(&lu, sizeof(lu)); - - /* - * XXX - Don't return an error if we can't find a vnode for the - * device. Our dev_t is 32-bits whereas Linux only has a 16-bits - * dev_t. The dev_t that is used now may as well be a truncated - * dev_t returned from previous syscalls. Just return a bzeroed - * ustat in that case. - */ - dev = makebdev(uap->dev >> 8, uap->dev & 0xFF); - if (vfinddev(dev, VBLK, &vp)) { - if (vp->v_mount == NULL) - return (EINVAL); - stat = &(vp->v_mount->mnt_stat); - error = VFS_STATFS(vp->v_mount, stat, p); - if (error) - return (error); - - lu.f_tfree = stat->f_bfree; - lu.f_tinode = stat->f_ffree; - } - - return (copyout(&lu, uap->ubuf, sizeof(lu))); -} diff --git a/sys/i386/linux/linux_util.c b/sys/i386/linux/linux_util.c deleted file mode 100644 index e0ea0cb..0000000 --- a/sys/i386/linux/linux_util.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 1994 Christos Zoulas - * Copyright (c) 1995 Frank van der Linden - * Copyright (c) 1995 Scott Bartram - * 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. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * from: svr4_util.c,v 1.5 1995/01/22 23:44:50 christos Exp - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/namei.h> -#include <sys/proc.h> -#include <sys/malloc.h> -#include <sys/vnode.h> - -#include <i386/linux/linux_util.h> - - -const char linux_emul_path[] = "/compat/linux"; - -/* - * Search an alternate path before passing pathname arguments on - * to system calls. Useful for keeping a seperate 'emulation tree'. - * - * If cflag is set, we check if an attempt can be made to create - * the named file, i.e. we check if the directory it should - * be in exists. - */ -int -linux_emul_find(p, sgp, prefix, path, pbuf, cflag) - struct proc *p; - caddr_t *sgp; /* Pointer to stackgap memory */ - const char *prefix; - char *path; - char **pbuf; - int cflag; -{ - struct nameidata nd; - struct nameidata ndroot; - struct vattr vat; - struct vattr vatroot; - int error; - char *ptr, *buf, *cp; - size_t sz, len; - - buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK); - *pbuf = path; - - for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++) - continue; - - sz = MAXPATHLEN - (ptr - buf); - - /* - * If sgp is not given then the path is already in kernel space - */ - if (sgp == NULL) - error = copystr(path, ptr, sz, &len); - else - error = copyinstr(path, ptr, sz, &len); - - if (error) { - free(buf, M_TEMP); - return error; - } - - if (*ptr != '/') { - free(buf, M_TEMP); - return EINVAL; - } - - /* - * We know that there is a / somewhere in this pathname. - * Search backwards for it, to find the file's parent dir - * to see if it exists in the alternate tree. If it does, - * and we want to create a file (cflag is set). We don't - * need to worry about the root comparison in this case. - */ - - if (cflag) { - for (cp = &ptr[len] - 1; *cp != '/'; cp--); - *cp = '\0'; - - NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p); - - if ((error = namei(&nd)) != 0) { - free(buf, M_TEMP); - return error; - } - - *cp = '/'; - } - else { - NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p); - - if ((error = namei(&nd)) != 0) { - free(buf, M_TEMP); - return error; - } - - /* - * We now compare the vnode of the linux_root to the one - * vnode asked. If they resolve to be the same, then we - * ignore the match so that the real root gets used. - * This avoids the problem of traversing "../.." to find the - * root directory and never finding it, because "/" resolves - * to the emulation root directory. This is expensive :-( - */ - NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, linux_emul_path, - p); - - if ((error = namei(&ndroot)) != 0) { - /* Cannot happen! */ - free(buf, M_TEMP); - NDFREE(&nd, NDF_ONLY_PNBUF); - vrele(nd.ni_vp); - return error; - } - - if ((error = VOP_GETATTR(nd.ni_vp, &vat, p->p_ucred, p)) != 0) { - goto bad; - } - - if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, p->p_ucred, p)) - != 0) { - goto bad; - } - - if (vat.va_fsid == vatroot.va_fsid && - vat.va_fileid == vatroot.va_fileid) { - error = ENOENT; - goto bad; - } - - } - if (sgp == NULL) - *pbuf = buf; - else { - sz = &ptr[len] - buf; - *pbuf = stackgap_alloc(sgp, sz + 1); - if (*pbuf != NULL) - error = copyout(buf, *pbuf, sz); - else - error = ENAMETOOLONG; - free(buf, M_TEMP); - } - - NDFREE(&nd, NDF_ONLY_PNBUF); - vrele(nd.ni_vp); - if (!cflag) { - NDFREE(&ndroot, NDF_ONLY_PNBUF); - vrele(ndroot.ni_vp); - } - return error; - -bad: - NDFREE(&ndroot, NDF_ONLY_PNBUF); - vrele(ndroot.ni_vp); - NDFREE(&nd, NDF_ONLY_PNBUF); - vrele(nd.ni_vp); - free(buf, M_TEMP); - return error; -} diff --git a/sys/i386/linux/linux_util.h b/sys/i386/linux/linux_util.h deleted file mode 100644 index 444c9a5..0000000 --- a/sys/i386/linux/linux_util.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 1994 Christos Zoulas - * Copyright (c) 1995 Frank van der Linden - * Copyright (c) 1995 Scott Bartram - * 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. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * from: svr4_util.h,v 1.5 1994/11/18 02:54:31 christos Exp - * from: linux_util.h,v 1.2 1995/03/05 23:23:50 fvdl Exp - * $FreeBSD$ - */ - -/* - * This file is pretty much the same as Christos' svr4_util.h - * (for now). - */ - -#ifndef _LINUX_UTIL_H_ -#define _LINUX_UTIL_H_ - -#include "opt_linux.h" - -#include <vm/vm.h> -#include <vm/vm_param.h> -#include <vm/pmap.h> -#include <machine/vmparam.h> -#include <sys/exec.h> -#include <sys/sysent.h> -#include <sys/cdefs.h> - -static __inline caddr_t stackgap_init(void); -static __inline void *stackgap_alloc(caddr_t *, size_t); - -#define szsigcode (*(curproc->p_sysent->sv_szsigcode)) - -static __inline caddr_t -stackgap_init() -{ - return (caddr_t)(PS_STRINGS - szsigcode - SPARE_USRSPACE); -} - -static __inline void * -stackgap_alloc(sgp, sz) - caddr_t *sgp; - size_t sz; -{ - void *p = (void *) *sgp; - - sz = ALIGN(sz); - if (*sgp + sz > (caddr_t)(PS_STRINGS - szsigcode)) - return NULL; - *sgp += sz; - return p; -} - -extern const char linux_emul_path[]; - -int linux_emul_find __P((struct proc *, caddr_t *, const char *, char *, - char **, int)); - -#define CHECKALT(p, sgp, path, i) \ - do { \ - int _error; \ - \ - _error = linux_emul_find(p, sgp, linux_emul_path, path, \ - &path, i); \ - if (_error == EFAULT) \ - return (_error); \ - } while (0) - -#define CHECKALTEXIST(p, sgp, path) CHECKALT(p, sgp, path, 0) -#define CHECKALTCREAT(p, sgp, path) CHECKALT(p, sgp, path, 1) - -#endif /* !_LINUX_UTIL_H_ */ |