fix presence bug
[svn42.git] / go / termios / termios_x86.go
1 // +build linux,386 linux,amd64
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     IGNPAR = tcflag_t (0000004)
23     PARMRK = tcflag_t (0000010)
24     INLCR = tcflag_t (0000100)
25     ECHONL = tcflag_t (0000100)
26     IGNCR = tcflag_t (0000200)
27     ICRNL = tcflag_t (0000400)
28     INPCK = tcflag_t (0000020)
29     ISTRIP = tcflag_t (0000040)
30     IXON = tcflag_t (0002000)
31     OPOST = tcflag_t (0000001)
32     CS8 = tcflag_t (0000060)
33     ECHO = tcflag_t (0000010)
34     ICANON = tcflag_t (0000002)
35     IEXTEN = tcflag_t (0100000)
36     ISIG = tcflag_t (0000001)
37     VTIME = tcflag_t (5)
38     VMIN = tcflag_t (6)
39     CBAUD = tcflag_t (0010017)
40     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 = 19  //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  //unused in kernel on x86 apparently
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 (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 (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 &= ^(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
127     orig_termios.c_oflag &= ^(OPOST);
128     orig_termios.c_lflag &= ^(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
129     orig_termios.c_cflag |= (CS8);
130
131     orig_termios.c_cc[VMIN] = 1;
132     orig_termios.c_cc[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 &= ^(CBAUD | CBAUDEX)
149     orig_termios.c_cflag |= tcflag_t(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 & (CBAUD | CBAUDEX) != tcflag_t(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 }