123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- /* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
- /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
- /* Copyright (C) 2014 OSCAR lab, Stony Brook University
- This file is part of Graphene Library OS.
- Graphene Library OS is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
- Graphene Library OS is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
- /*
- * shim_ioctl.c
- *
- * Implementation of system call "ioctl".
- */
- #include <shim_internal.h>
- #include <shim_table.h>
- #include <shim_thread.h>
- #include <shim_handle.h>
- #include <shim_fs.h>
- #include <pal.h>
- #include <pal_error.h>
- #include <asm/unistd.h>
- #include <errno.h>
- #include <asm/ioctl.h>
- #include <asm/ioctls.h>
- #include <asm/termios.h>
- #include <asm/termbits.h>
- #include <linux/fd.h>
- #include <linux/sockios.h>
- #define TERM_DEFAULT_IFLAG (ICRNL|IUTF8)
- #define TERM_DEFAULT_OFLAG (OPOST|ONLCR)
- #define TERM_DEFAULT_CFLAG (B38400|CS8|CREAD)
- #define TERM_DEFAULT_LFLAG (ICANON|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE|IEXTEN)
- static int ioctl_termios (struct shim_handle * hdl, unsigned int cmd,
- unsigned long arg)
- {
- if (hdl->type != TYPE_FILE ||
- hdl->info.file.type != FILE_TTY)
- return -ENOTTY;
- if (!arg)
- return -EINVAL;
- switch(cmd) {
- /* <include/asm/termios.h> */
- case TIOCGPGRP:
- *(int *) arg = get_cur_thread()->pgid;
- return 0;
- case TIOCSPGRP:
- return -EINVAL;
- case TCGETS: {
- #if 0
- struct termios * termios = (struct termios *) arg;
- termios->c_iflag = TERM_DEFAULT_IFLAG;
- termios->c_oflag = TERM_DEFAULT_OFLAG;
- termios->c_cflag = TERM_DEFAULT_CFLAG;
- termios->c_lflag = TERM_DEFAULT_LFLAG;
- return 0;
- #endif
- return -EINVAL;
- }
- case TCSETS:
- case TCSETSW:
- case TCSETSF:
- return -EINVAL;
- /* 0x00005405 TCGETA struct termio * */
- case TCGETA:
- /* 0x00005406 TCSETA const struct termio * */
- case TCSETA:
- /* 0x00005407 TCSETAW const struct termio * */
- case TCSETAW:
- /* 0x00005408 TCSETAF const struct termio * */
- case TCSETAF:
- /* 0x00005409 TCSBRK int */
- case TCSBRK:
- /* 0x0000540A TCXONC int */
- case TCXONC:
- /* 0x0000540B TCFLSH int */
- case TCFLSH:
- /* 0x0000540C TIOCEXCL void */
- case TIOCEXCL:
- /* 0x0000540D TIOCNXCL void */
- case TIOCNXCL:
- /* 0x0000540E TIOCSCTTY int */
- case TIOCSCTTY:
- /* 0x0000540F TIOCGPGRP pid_t * */
- case TIOCOUTQ:
- /* 0x00005412 TIOCSTI const char * */
- case TIOCSTI:
- /* 0x00005413 TIOCGWINSZ struct winsize * */
- case TIOCGWINSZ:
- /* 0x00005415 TIOCMGET int * */
- case TIOCMGET:
- /* 0x00005416 TIOCMBIS const int * */
- case TIOCMBIS:
- /* 0x00005417 TIOCMBIC const int * */
- case TIOCMBIC:
- /* 0x00005418 TIOCMSET const int * */
- case TIOCMSET:
- /* 0x00005419 TIOCGSOFTCAR int * */
- case TIOCGSOFTCAR:
- /* 0x0000541A TIOCSSOFTCAR const int * */
- case TIOCSSOFTCAR:
- /* 0x0000541B FIONREAD int / TIOCINQ int * */
- case TIOCINQ:
- /* 0x0000541C TIOCLINUX const char * */
- case TIOCLINUX:
- /* 0x0000541D TIOCCONS void */
- case TIOCCONS:
- /* 0x0000541E TIOCGSERIAL struct serial_struct * */
- case TIOCGSERIAL:
- /* 0x0000541F TIOCSSERIAL const struct serial_struct * */
- case TIOCSSERIAL:
- /* 0x00005420 TIOCPKT const int * */
- case TIOCPKT:
- /* 0x00005421 FIONBIO const int * */
- case FIONBIO:
- /* 0x00005422 TIOCNOTTY void */
- case TIOCNOTTY:
- /* 0x00005423 TIOCSETD const int * */
- case TIOCSETD:
- /* 0x00005424 TIOCGETD int * */
- case TIOCGETD:
- /* 0x00005425 TCSBRKP int */
- case TCSBRKP:
- /* 0x00005450 FIONCLEX void */
- case FIONCLEX:
- /* 0x00005451 FIOCLEX void */
- case FIOCLEX:
- /* 0x00005452 FIOASYNC const int * */
- case FIOASYNC:
- /* 0x00005453 TIOCSERCONFIG void */
- case TIOCSERCONFIG:
- /* 0x00005454 TIOCSERGWILD int * */
- case TIOCSERGWILD:
- /* 0x00005455 TIOCSERSWILD const int * */
- case TIOCSERSWILD:
- /* 0x00005456 TIOCGLCKTRMIOS struct termios * */
- case TIOCGLCKTRMIOS:
- /* 0x00005457 TIOCSLCKTRMIOS const struct termios * */
- case TIOCSLCKTRMIOS:
- /* 0x00005458 TIOCSERGSTRUCT struct async_struct * */
- case TIOCSERGSTRUCT:
- /* 0x00005459 TIOCSERGETLSR int * */
- case TIOCSERGETLSR:
- /* 0x0000545A TIOCSERGETMULTI struct serial_multiport_struct * */
- case TIOCSERGETMULTI:
- /* 0x0000545B TIOCSERSETMULTI const struct serial_multiport_struct * */
- case TIOCSERSETMULTI:
- default:
- goto passthrough;
- }
- passthrough:
- return -EAGAIN;
- }
- static int ioctl_fd (struct shim_handle * hdl, unsigned int cmd,
- unsigned long arg)
- {
- switch(cmd) {
- /* <include/linux/fd.h> */
- /* 0x00000000 FDCLRPRM void */
- case FDCLRPRM:
- /* 0x00000001 FDSETPRM const struct floppy_struct * */
- case FDSETPRM:
- /* 0x00000002 FDDEFPRM const struct floppy_struct * */
- case FDDEFPRM:
- /* 0x00000003 FDGETPRM struct floppy_struct * */
- case FDGETPRM:
- /* 0x00000004 FDMSGON void */
- case FDMSGON:
- /* 0x00000005 FDMSGOFF void */
- case FDMSGOFF:
- /* 0x00000006 FDFMTBEG void */
- case FDFMTBEG:
- /* 0x00000007 FDFMTTRK const struct format_descr * */
- case FDFMTTRK:
- /* 0x00000008 FDFMTEND void */
- case FDFMTEND:
- /* 0x0000000A FDSETEMSGTRESH int */
- case FDSETEMSGTRESH:
- /* 0x0000000B FDFLUSH void */
- case FDFLUSH:
- /* 0x0000000C FDSETMAXERRS const struct floppy_max_errors * */
- case FDSETMAXERRS:
- /* 0x0000000E FDGETMAXERRS struct floppy_max_errors * */
- case FDGETMAXERRS:
- /* 0x00000010 FDGETDRVTYP struct { char [16]; } * */
- case FDGETDRVTYP:
- /* 0x00000014 FDSETDRVPRM const struct floppy_drive_params * */
- case FDSETDRVPRM:
- /* 0x00000015 FDGETDRVPRM struct floppy_drive_params * */
- case FDGETDRVPRM:
- /* 0x00000016 FDGETDRVSTAT struct floppy_drive_struct * */
- case FDGETDRVSTAT:
- /* 0x00000017 FDPOLLDRVSTAT struct floppy_drive_struct * */
- case FDPOLLDRVSTAT:
- /* 0x00000018 FDRESET int */
- case FDRESET:
- /* 0x00000019 FDGETFDCSTAT struct floppy_fdc_state * */
- case FDGETFDCSTAT:
- /* 0x0000001B FDWERRORCLR void */
- case FDWERRORCLR:
- /* 0x0000001C FDWERRORGET struct floppy_write_errors * */
- case FDWERRORGET:
- /* 0x0000001E FDRAWCMD struct floppy_raw_cmd *floppy_raw_cmd */
- case FDRAWCMD:
- /* 0x00000028 FDTWADDLE void */
- case FDTWADDLE:
- default:
- goto passthrough;
- }
- passthrough:
- return -EAGAIN;
- }
- static int ioctl_netdevice (struct shim_handle * hdl, unsigned int cmd,
- unsigned long arg)
- {
- if (hdl->type != TYPE_SOCK)
- return -ENOTSOCK;
- struct shim_sock_handle * sock = &hdl->info.sock;
- if (sock->sock_state == SOCK_CREATED) {
- if (sock->sock_type == SOCK_STREAM)
- return -ENOTCONN;
- }
- switch(cmd) {
- /* Socket configuration controls. */
- case SIOCGIFNAME: /* 0x8910 get iface name */
- case SIOCSIFLINK: /* 0x8911 set iface channel */
- case SIOCGIFCONF: /* 0x8912 get iface list */
- case SIOCGIFFLAGS: /* 0x8913 get flags */
- case SIOCSIFFLAGS: /* 0x8914 set flags */
- case SIOCGIFADDR: /* 0x8915 get PA address */
- case SIOCSIFADDR: /* 0x8916 set PA address */
- case SIOCGIFDSTADDR: /* 0x8917 get remote PA address */
- case SIOCSIFDSTADDR: /* 0x8918 set remote PA address */
- case SIOCGIFBRDADDR: /* 0x8919 get broadcast PA address */
- case SIOCSIFBRDADDR: /* 0x891a set broadcast PA address */
- case SIOCGIFNETMASK: /* 0x891b get network PA mask */
- case SIOCSIFNETMASK: /* 0x891c set network PA mask */
- case SIOCGIFMETRIC: /* 0x891d get metric */
- case SIOCSIFMETRIC: /* 0x891e set metric */
- case SIOCGIFMEM: /* 0x891f get memory address (BSD) */
- case SIOCSIFMEM: /* 0x8920 set memory address (BSD) */
- case SIOCGIFMTU: /* 0x8921 get MTU size */
- case SIOCSIFMTU: /* 0x8922 set MTU size */
- case SIOCSIFNAME: /* 0x8923 set interface name */
- case SIOCSIFHWADDR: /* 0x8924 set hardware address */
- case SIOCGIFENCAP: /* 0x8925 get/set encapsulations */
- case SIOCSIFENCAP: /* 0x8926 */
- case SIOCGIFHWADDR: /* 0x8927 Get hardware address */
- case SIOCGIFSLAVE: /* 0x8929 Driver slaving support */
- case SIOCSIFSLAVE: /* 0x8930 */
- case SIOCADDMULTI: /* 0x8931 Multicast address lists */
- case SIOCDELMULTI: /* 0x8932 */
- case SIOCGIFINDEX: /* 0x8933 name -> if_index mapping */
- /* SIOGIFINDEX = SIOCGIFINDEX misprint compatibility :-) */
- case SIOCSIFPFLAGS: /* 0x8934 set/get extended flags set */
- case SIOCGIFPFLAGS: /* 0x8935 */
- case SIOCDIFADDR: /* 0x8936 delete PA address */
- case SIOCSIFHWBROADCAST: /* 0x8937 set hardware broadcast addr */
- case SIOCGIFCOUNT: /* 0x8938 get number of devices */
- case SIOCGIFBR: /* 0x8940 Bridging support */
- case SIOCSIFBR: /* 0x8941 Set bridging options */
- case SIOCGIFTXQLEN: /* 0x8942 Get the tx queue length */
- case SIOCSIFTXQLEN: /* 0x8943 Set the tx queue length */
- default:
- goto passthrough;
- }
- passthrough:
- return -EAGAIN;
- }
- int shim_do_ioctl (int fd, int cmd, unsigned long arg)
- {
- struct shim_handle * hdl = get_fd_handle(fd, NULL, NULL);
- if (!hdl)
- return -EBADF;
- int ret = -EAGAIN;
- switch(cmd) {
- /* <include/asm/termios.h> */
- case TCGETS:
- case TCSETS:
- case TCSETSW:
- case TCSETSF:
- case TCGETA:
- case TCSETA:
- case TCSETAW:
- case TCSETAF:
- case TCSBRK:
- case TCXONC:
- case TCFLSH:
- case TIOCEXCL:
- case TIOCNXCL:
- case TIOCSCTTY:
- case TIOCGPGRP:
- case TIOCSPGRP:
- case TIOCOUTQ:
- case TIOCSTI:
- case TIOCGWINSZ:
- case TIOCMGET:
- case TIOCMBIS:
- case TIOCMBIC:
- case TIOCMSET:
- case TIOCGSOFTCAR:
- case TIOCSSOFTCAR:
- /* case TIOCINQ = FIONREAD */
- case TIOCLINUX:
- case TIOCCONS:
- case TIOCGSERIAL:
- case TIOCSSERIAL:
- case TIOCPKT:
- case FIONBIO:
- case TIOCNOTTY:
- case TIOCSETD:
- case TIOCGETD:
- case TCSBRKP:
- case FIONCLEX:
- case FIOCLEX:
- case FIOASYNC:
- case TIOCSERCONFIG:
- case TIOCSERGWILD:
- case TIOCSERSWILD:
- case TIOCGLCKTRMIOS:
- case TIOCSLCKTRMIOS:
- case TIOCSERGSTRUCT:
- case TIOCSERGETLSR:
- case TIOCSERGETMULTI:
- case TIOCSERSETMULTI:
- ret = ioctl_termios(hdl, cmd, arg);
- break;
- case FDCLRPRM:
- case FDSETPRM:
- case FDDEFPRM:
- case FDGETPRM:
- case FDMSGON:
- case FDMSGOFF:
- case FDFMTBEG:
- case FDFMTTRK:
- case FDFMTEND:
- case FDSETEMSGTRESH:
- case FDFLUSH:
- case FDSETMAXERRS:
- case FDGETMAXERRS:
- case FDGETDRVTYP:
- case FDSETDRVPRM:
- case FDGETDRVPRM:
- case FDGETDRVSTAT:
- case FDPOLLDRVSTAT:
- case FDRESET:
- case FDGETFDCSTAT:
- case FDWERRORCLR:
- case FDWERRORGET:
- case FDRAWCMD:
- case FDTWADDLE:
- ret = ioctl_fd(hdl, cmd, arg);
- break;
- case FIONREAD: {
- struct shim_mount * fs = hdl->fs;
- int size = 0;
- int offset = 0;
- if (!fs || !fs->fs_ops) {
- ret = -EACCES;
- break;
- }
- if (fs->fs_ops->hstat) {
- struct stat stat;
- ret = fs->fs_ops->hstat(hdl, &stat);
- if (ret < 0)
- break;
- size = stat.st_size;
- goto done_fioread;
- }
- if (hdl->pal_handle) {
- PAL_STREAM_ATTR attr;
- if (!DkStreamAttributesQuerybyHandle(hdl->pal_handle, &attr)) {
- ret = -PAL_ERRNO;
- break;
- }
- size = attr.size;
- goto done_fioread;
- }
- done_fioread:
- if (fs->fs_ops->seek) {
- ret = fs->fs_ops->seek(hdl, 0, SEEK_CUR);
- if (ret < 0)
- break;
- offset = ret;
- }
- *(int *) arg = size - offset;
- ret = 0;
- break;
- }
- /* Socket configuration controls. */
- case SIOCGIFNAME: /* 0x8910 get iface name */
- case SIOCSIFLINK: /* 0x8911 set iface channel */
- case SIOCGIFCONF: /* 0x8912 get iface list */
- case SIOCGIFFLAGS: /* 0x8913 get flags */
- case SIOCSIFFLAGS: /* 0x8914 set flags */
- case SIOCGIFADDR: /* 0x8915 get PA address */
- case SIOCSIFADDR: /* 0x8916 set PA address */
- case SIOCGIFDSTADDR: /* 0x8917 get remote PA address */
- case SIOCSIFDSTADDR: /* 0x8918 set remote PA address */
- case SIOCGIFBRDADDR: /* 0x8919 get broadcast PA address */
- case SIOCSIFBRDADDR: /* 0x891a set broadcast PA address */
- case SIOCGIFNETMASK: /* 0x891b get network PA mask */
- case SIOCSIFNETMASK: /* 0x891c set network PA mask */
- case SIOCGIFMETRIC: /* 0x891d get metric */
- case SIOCSIFMETRIC: /* 0x891e set metric */
- case SIOCGIFMEM: /* 0x891f get memory address (BSD) */
- case SIOCSIFMEM: /* 0x8920 set memory address (BSD) */
- case SIOCGIFMTU: /* 0x8921 get MTU size */
- case SIOCSIFMTU: /* 0x8922 set MTU size */
- case SIOCSIFNAME: /* 0x8923 set interface name */
- case SIOCSIFHWADDR: /* 0x8924 set hardware address */
- case SIOCGIFENCAP: /* 0x8925 get/set encapsulations */
- case SIOCSIFENCAP: /* 0x8926 */
- case SIOCGIFHWADDR: /* 0x8927 Get hardware address */
- case SIOCGIFSLAVE: /* 0x8929 Driver slaving support */
- case SIOCSIFSLAVE: /* 0x8930 */
- case SIOCADDMULTI: /* 0x8931 Multicast address lists */
- case SIOCDELMULTI: /* 0x8932 */
- case SIOCGIFINDEX: /* 0x8933 name -> if_index mapping */
- /* SIOGIFINDEX = SIOCGIFINDEX misprint compatibility :-) */
- case SIOCSIFPFLAGS: /* 0x8934 set/get extended flags set */
- case SIOCGIFPFLAGS: /* 0x8935 */
- case SIOCDIFADDR: /* 0x8936 delete PA address */
- case SIOCSIFHWBROADCAST: /* 0x8937 set hardware broadcast addr */
- case SIOCGIFCOUNT: /* 0x8938 get number of devices */
- case SIOCGIFBR: /* 0x8940 Bridging support */
- case SIOCSIFBR: /* 0x8941 Set bridging options */
- case SIOCGIFTXQLEN: /* 0x8942 Get the tx queue length */
- case SIOCSIFTXQLEN: /* 0x8943 Set the tx queue length */
- ret = ioctl_netdevice(hdl, cmd, arg);
- break;
- default:
- ret = -ENOSYS;
- break;
- }
- put_handle(hdl);
- return ret;
- }
|