add chdir
[snitchaser:mainline.git] / src / arch / x86 / interp / syscalls / ioctl.c
1 /* 
2  * ioctl.c
3  * by WN @ Jul. 22, 2010
4  */
5
6 #include "syscall_handler.h"
7 #include <xasm/syscall.h>
8 #include <common/debug.h>
9
10 #include "ioctl.h"
11 #include "ioctl_tty.h"
12 #include "ioctl_blk.h"
13
14 #ifndef PRE_LIBRARY
15
16 #ifdef POST_LIBRARY
17 # define TTY_IOCTL post_tty_ioctl
18 # define BLK_IOCTL post_blk_ioctl
19 #else
20 # define TTY_IOCTL replay_tty_ioctl
21 # define BLK_IOCTL replay_blk_ioctl
22 #endif
23
24 static int
25 TTY_IOCTL(int fd, int cmd, int arg, struct pusha_regs * regs)
26 {
27         switch (cmd) {
28         case TCGETS:
29                 if (arg != 0)
30                         BUFFER((void*)arg, sizeof(struct termios));
31                 return 0;
32         case TIOCGWINSZ:
33                 if (arg != 0)
34                         BUFFER((void*)arg, sizeof(struct winsize));
35                 return 0;
36         case FIONREAD:
37                 if (arg != 0)
38                         BUFFER((void*)arg, sizeof(int));
39                 return 0;
40         case FIONBIO:
41                 return 0;
42         case TCGETA:
43                 if (arg != 0)
44                         BUFFER((void*)arg, sizeof(struct termio));
45                 return 0;
46         case TCSETA:
47                 return 0;
48         case FIOASYNC:
49                 return 0;
50         default:
51                 FATAL(LOG_SYSCALL, "doesn't know such tty ioctl: 0x%x\n", cmd);
52         }
53         return 0;
54 }
55
56 static int
57 BLK_IOCTL(int fd, int cmd, int arg, struct pusha_regs * regs)
58 {
59         if ((int)(regs->eax) < 0)
60                 return 0;
61
62         if (_IOC_DIR(cmd) == _IOC_READ) {
63                 assert(arg != 0);
64                 BUFFER((void*)arg, _IOC_SIZE(cmd));
65         }
66         return 0;
67 }
68
69
70 DEF_HANDLER(ioctl)
71 {
72         TRACE(LOG_SYSCALL, "ioctl\n");
73
74         int fd = regs->ebx;
75         int cmd = regs->ecx;
76         int arg = regs->edx;
77
78         switch (_IOC_TYPE(cmd)) {
79         case 'T':
80                 return TTY_IOCTL(fd, cmd, arg, regs);
81         case 0x12:
82                 return BLK_IOCTL(fd, cmd, arg, regs);
83         default:
84                 FATAL(LOG_SYSCALL, "no such ioctl command: 0x%x\n", cmd);
85         }
86 }
87 #endif
88
89 // vim:ts=4:sw=4
90