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.
This commit is contained in:
parent
0ec24f5a8a
commit
3ed7f6a56f
@ -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_ */
|
@ -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);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -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_ */
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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_ */
|
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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)));
|
||||
}
|
@ -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;
|
||||
}
|
@ -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_ */
|
Loading…
Reference in New Issue
Block a user