Merge branch 'master' of git://git.ucc.asn.au/tpg/acess2
[tpg/acess2.git] / Usermode / Libraries / libposix.so_src / termios.c
1 /*
2  * Acess2 POSIX Emulation
3  * - By John Hodge (thePowersGang)
4  *
5  * termios.c
6  * - Terminal Control
7  */
8 #include <termios.h>
9 #include <errno.h>
10 #include <string.h>
11 #include <acess/sys.h>
12 #include <acess/devices/pty.h>
13
14 // === CODE ===
15 speed_t cfgetospeed(const struct termios *termios_p)
16 {
17         return termios_p->c_oflag & CBAUD;
18 }
19
20 int tcgetattr(int fd, struct termios *termios_p)
21 {
22         if( fd == -1 ) {
23                 errno = EBADF;
24                 return -1;
25         }
26         
27         // Double-check `fd` describes a terminal
28         if( _SysIOCtl(fd, DRV_IOCTL_TYPE, NULL) != DRV_TYPE_TERMINAL ) {
29                 errno = EINVAL;
30                 return -1;
31         }
32         
33         // Fill defaults
34         memset(termios_p, 0, sizeof(struct termios));
35
36         // Query kernel for other params
37         struct ptymode  mode;
38         _SysIOCtl(fd, PTY_IOCTL_GETMODE, &mode);
39
40         if( (mode.OutputMode & PTYOMODE_BUFFMT) != PTYBUFFMT_TEXT ) {
41                 _SysDebug("Call to tcgetattr when terminal is not in text mode");
42                 return -1;
43         }
44
45         if(mode.InputMode & PTYIMODE_CANON)
46                 termios_p->c_lflag |= ICANON|ECHOE|ECHOK;
47         if(mode.InputMode & PTYIMODE_ECHO)
48                 termios_p->c_lflag |= ECHO;
49         // TODO: The more subtle flags
50
51         return 0;
52 }
53
54 int tcsetattr(int fd, int optional_actions, const struct termios *termios_p)
55 {
56         _SysDebug("tcsetattr(%i, 0%o, %p)", fd, optional_actions, termios_p);
57
58         if( fd == -1 ) {
59                 errno = EBADF;
60                 return -1;
61         }
62
63         if( !termios_p || (optional_actions & ~(7)) ) {
64                 errno = EINVAL;
65                 return -1;
66         }
67         _SysDebug("*termios_p = {%x,%x,%x,%x}",
68                 termios_p->c_iflag, termios_p->c_oflag, termios_p->c_cflag, termios_p->c_lflag);
69         
70         // Double-check `fd` describes a terminal
71         if( _SysIOCtl(fd, DRV_IOCTL_TYPE, NULL) != DRV_TYPE_TERMINAL ) {
72                 errno = EINVAL;
73                 return -1;
74         }
75
76         struct ptymode  mode = {0,0};
77         
78         if(termios_p->c_lflag & ICANON)
79                 mode.InputMode |= PTYIMODE_CANON;
80         if(termios_p->c_lflag & ECHO)
81                 mode.InputMode |= PTYIMODE_ECHO;
82
83         _SysIOCtl(fd, PTY_IOCTL_SETMODE, &mode);
84
85         return 0;
86 }
87

UCC git Repository :: git.ucc.asn.au