e8cf82a8f21948ca8124772fa43915947153bb22
[svn42.git] / termios_mips.go
1 // +build linux,arm
2
3
4 package termios
5
6 import (
7     "os";
8     "syscall";
9     "unsafe"
10     "errors"
11 )
12
13 // termios types
14 type cc_t byte
15 type speed_t uint32
16 type tcflag_t uint32
17
18 // termios constants
19 const (
20     IGNBRK = tcflag_t (0000001)
21     BRKINT = tcflag_t (0000002)
22     syscall.IGNPAR = tcflag_t (0000004)
23     syscall.PARMRK = tcflag_t (0000010)
24     syscall.INLCR = tcflag_t (0000100)
25     syscall.ECHONL = tcflag_t (0000100)
26     syscall.IGNCR = tcflag_t (0000200)
27     syscall.ICRNL = tcflag_t (0000400)
28     syscall.INPCK = tcflag_t (0000020)
29     syscall.ISTRIP = tcflag_t (0000040)
30     syscall.IXON = tcflag_t (0002000)
31     syscall.OPOST = tcflag_t (0000001)
32     syscall.CS8 = tcflag_t (0000060)
33     syscall.ECHO = tcflag_t (0000010)
34     syscall.ICANON = tcflag_t (0000002)
35     syscall.IEXTEN = tcflag_t (0100000)
36     syscall.ISIG = tcflag_t (0000001)
37     syscall.VTIME = tcflag_t (5)
38     syscall.VMIN = tcflag_t (6)
39     syscall.CBAUD = tcflag_t (0010017)
40     syscall..CBAUDEX = tcflag_t (0010000)
41 )
42
43 const (
44     B0 = speed_t(0000000)         /* hang up */
45     B50 = speed_t(0000001)
46     B75 = speed_t(0000002)
47     B110 = speed_t(0000003)
48     B134 = speed_t(0000004)
49     B150 = speed_t(0000005)
50     B200 = speed_t(0000006)
51     B300 = speed_t(0000007)
52     B600 = speed_t(0000010)
53     B1200 = speed_t(0000011)
54     B1800 = speed_t(0000012)
55     B2400 = speed_t(0000013)
56     B4800 = speed_t(0000014)
57     B9600 = speed_t(0000015)
58     B19200 = speed_t(0000016)
59     B38400 = speed_t(0000017)
60     B57600 = speed_t(0010001)
61     B115200 = speed_t(0010002)
62     B230400 = speed_t(0010003)
63     B460800 = speed_t(0010004)
64     B500000 = speed_t(0010005)
65     B576000 = speed_t(0010006)
66     B921600 = speed_t(0010007)
67     B1000000 = speed_t(0010010)
68     B1152000 = speed_t(0010011)
69     B1500000 = speed_t(0010012)
70     B2000000 = speed_t(0010013)
71     B2500000 = speed_t(0010014)
72     B3000000 = speed_t(0010015)
73     B3500000 = speed_t(0010016)
74     B4000000 = speed_t(0010017)
75 )
76
77 //note that struct termios and struct __kernel_termios have DIFFERENT size and layout !!!
78 const NCCS = 23  //23 on mips, 19 on alpha (also line and cc reversed), 19 on powerpc (also line and cc reversed), 17 on sparc, 
79 type termios struct {
80     c_iflag, c_oflag, c_cflag, c_lflag  tcflag_t
81     c_line  cc_t
82     c_cc    [NCCS]cc_t
83     c_ispeed, c_ospeed  speed_t
84 }
85
86 // ioctl constants
87 const (
88     TCGETS = 0x5401
89     TCSETS = 0x5402
90 )
91
92 func getTermios(ttyfd uintptr, dst *termios) error {
93     r1, _, errno := syscall. (syscall.SYS_IOCTL,
94                                      uintptr (ttyfd), uintptr (TCGETS),
95                                      uintptr (unsafe.Pointer (dst)));
96
97     if err := os.NewSyscallError ("SYS_IOCTL", errno); errno!=0 && err != nil {
98         return err
99     }
100
101     if r1 != 0 {
102     //    return errors.New("Error")
103     }
104     return nil
105 }
106
107 func setTermios(ttyfd uintptr, src *termios) error {
108     r1, _, errno := syscall. (syscall.SYS_IOCTL,
109                                      uintptr (ttyfd), uintptr (TCSETS),
110                                      uintptr (unsafe.Pointer (src)));
111
112     if err := os.NewSyscallError ("SYS_IOCTL", errno); errno!=0 &&err != nil {
113         return err
114     }
115
116     if r1 != 0 {
117         return errors.New ("Error during ioctl tcsets syscall")
118     }
119     return nil
120 }
121
122 func SetRawFd(fd uintptr) (error) {
123     var orig_termios termios;
124     if err := getTermios (fd, &orig_termios); err != nil { return err}
125
126     orig_termios.c_iflag &= ^(syscall.IGNBRK|syscall.BRKINT|syscall.PARMRK|syscall.ISTRIP|syscall.INLCR|syscall.IGNCR|syscall.ICRNL|syscall.IXON);
127     orig_termios.c_oflag &= ^(syscall.OPOST);
128     orig_termios.c_lflag &= ^(syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.IEXTEN | syscall.ISIG);
129     orig_termios.c_cflag |= (syscall.CS8);
130
131     orig_termios.c_cc[syscall.VMIN] = 1;
132     orig_termios.c_cc[syscall.VTIME] = 0;
133
134     return setTermios(fd, &orig_termios)
135 }
136
137 func SetRawFile(f *os.File) (error) {
138     return SetRawFd(f.Fd())
139 }
140
141 func SetSpeedFd(fd uintptr, speed speed_t) (err error) {
142     var orig_termios termios;
143     if err = getTermios (fd, &orig_termios); err != nil { return }
144     
145     orig_termios.c_ispeed = speed
146     orig_termios.c_ospeed = speed
147     //~ //input baudrate == output baudrate and we ignore special case B0
148     //~ orig_termios.c_cflag &= ^(syscall.CBAUD | syscall..CBAUDEX)
149     //~ orig_termios.c_cflag |= speed
150     if err = setTermios(fd, &orig_termios); err != nil { return }
151     if err = getTermios (fd, &orig_termios); err != nil { return }
152     if orig_termios.c_ispeed != speed || orig_termios.c_ospeed != speed {
153         err = errors.New("Failed to set speed")
154     }
155     //~ if err = getTermios (fd, &orig_termios); err != nil { return }
156     //~ if orig_termios.c_cflag & (syscall.CBAUD | syscall.CBAUDEX) != speed {
157         //~ err = errors.New("Failed to set speed")
158     //~ }
159     return
160 }
161
162 func SetSpeedFile(f *os.File, speed speed_t) (error) {
163     return SetSpeedFd(f.Fd(), speed)
164 }