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:
Marcel Moolenaar 2000-08-22 07:08:33 +00:00
parent 0ec24f5a8a
commit 3ed7f6a56f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=64931
13 changed files with 0 additions and 7605 deletions

View file

@ -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_ */

View file

@ -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

View file

@ -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_ */

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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)));
}

View file

@ -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;
}

View file

@ -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_ */