OSDN Git Service

* path.cc (conv_path_list): Take cygwin_conv_path_t as third parameter.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / termios.cc
1 /* termios.cc: termios for WIN32.
2
3    Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
4    2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
5
6    Written by Doug Evans and Steve Chamberlain of Cygnus Support
7    dje@cygnus.com, sac@cygnus.com
8
9 This file is part of Cygwin.
10
11 This software is a copyrighted work licensed under the terms of the
12 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
13 details. */
14
15 #include "winsup.h"
16 #include "cygwin/version.h"
17 #include <stdlib.h>
18 #include "cygerrno.h"
19 #include "security.h"
20 #include "path.h"
21 #include "fhandler.h"
22 #include "dtable.h"
23 #include "cygheap.h"
24 #include "perprocess.h"
25 #include "cygtls.h"
26
27 /* tcsendbreak: POSIX 7.2.2.1 */
28 extern "C" int
29 tcsendbreak (int fd, int duration)
30 {
31   int res = -1;
32
33   cygheap_fdget cfd (fd);
34   if (cfd < 0)
35     goto out;
36
37   if (!cfd->is_tty ())
38     set_errno (ENOTTY);
39   else if ((res = cfd->bg_check (-SIGTTOU)) > bg_eof)
40     res = cfd->tcsendbreak (duration);
41
42 out:
43   syscall_printf ("%d = tcsendbreak (%d, %d)", res, fd, duration);
44   return res;
45 }
46
47 /* tcdrain: POSIX 7.2.2.1 */
48 extern "C" int
49 tcdrain (int fd)
50 {
51   pthread_testcancel ();
52
53   int res = -1;
54
55   termios_printf ("tcdrain");
56
57   cygheap_fdget cfd (fd);
58   if (cfd < 0)
59     goto out;
60
61   if (!cfd->is_tty ())
62     set_errno (ENOTTY);
63   else if ((res = cfd->bg_check (-SIGTTOU)) > bg_eof)
64     res = cfd->tcdrain ();
65
66 out:
67   syscall_printf ("%d = tcdrain (%d)", res, fd);
68   return res;
69 }
70
71 /* tcflush: POSIX 7.2.2.1 */
72 extern "C" int
73 tcflush (int fd, int queue)
74 {
75   int res = -1;
76
77   cygheap_fdget cfd (fd);
78   if (cfd < 0)
79     goto out;
80
81   if (!cfd->is_tty ())
82     set_errno (ENOTTY);
83   else if (queue != TCIFLUSH && queue != TCOFLUSH && queue != TCIOFLUSH)
84       set_errno (EINVAL);
85   else if ((res = cfd->bg_check (-SIGTTOU)) > bg_eof)
86     res = cfd->tcflush (queue);
87
88 out:
89   termios_printf ("%d = tcflush (%d, %d)", res, fd, queue);
90   return res;
91 }
92
93 /* tcflow: POSIX 7.2.2.1 */
94 extern "C" int
95 tcflow (int fd, int action)
96 {
97   int res = -1;
98
99   cygheap_fdget cfd (fd);
100   if (cfd < 0)
101     goto out;
102
103   if (!cfd->is_tty ())
104     set_errno (ENOTTY);
105   else if ((res = cfd->bg_check (-SIGTTOU)) > bg_eof)
106     res = cfd->tcflow (action);
107
108 out:
109   syscall_printf ("%d = tcflow (%d, %d)", res, fd, action);
110   return res;
111 }
112
113 /* tcsetattr: POSIX96 7.2.1.1 */
114 extern "C" int
115 tcsetattr (int fd, int a, const struct termios *t)
116 {
117   int res;
118   t = __tonew_termios (t);
119   int e = get_errno ();
120
121   while (1)
122     {
123       res = -1;
124       cygheap_fdget cfd (fd);
125       if (cfd < 0)
126         {
127           e = get_errno ();
128           break;
129         }
130
131       if (!cfd->is_tty ())
132         {
133           e = ENOTTY;
134           break;
135         }
136
137       res = cfd->bg_check (-SIGTTOU);
138
139       switch (res)
140         {
141         case bg_eof:
142           e = get_errno ();
143           break;
144         case bg_ok:
145           if (cfd.isopen ())
146             res = cfd->tcsetattr (a, t);
147           e = get_errno ();
148           break;
149         case bg_signalled:
150           if (_my_tls.call_signal_handler ())
151             continue;
152           res = -1;
153           /* fall through intentionally */
154         default:
155           e = get_errno ();
156           break;
157         }
158       break;
159     }
160
161   set_errno (e);
162   termios_printf ("iflag %p, oflag %p, cflag %p, lflag %p, VMIN %d, VTIME %d",
163         t->c_iflag, t->c_oflag, t->c_cflag, t->c_lflag, t->c_cc[VMIN],
164         t->c_cc[VTIME]);
165   termios_printf ("%d = tcsetattr (%d, %d, %x)", res, fd, a, t);
166   return res;
167 }
168
169 /* tcgetattr: POSIX 7.2.1.1 */
170 extern "C" int
171 tcgetattr (int fd, struct termios *in_t)
172 {
173   int res = -1;
174   struct termios *t = __makenew_termios (in_t);
175
176   cygheap_fdget cfd (fd);
177   if (cfd < 0)
178     /* saw an error */;
179   else if (!cfd->is_tty ())
180     set_errno (ENOTTY);
181   else if ((res = cfd->tcgetattr (t)) == 0)
182     __toapp_termios (in_t, t);
183
184   if (res)
185     termios_printf ("%d = tcgetattr (%d, %p)", res, fd, in_t);
186   else
187     termios_printf ("iflag %x, oflag %x, cflag %x, lflag %x, VMIN %d, VTIME %d",
188           t->c_iflag, t->c_oflag, t->c_cflag, t->c_lflag, t->c_cc[VMIN],
189           t->c_cc[VTIME]);
190
191   return res;
192 }
193
194 /* tcgetpgrp: POSIX 7.2.3.1 */
195 extern "C" int
196 tcgetpgrp (int fd)
197 {
198   int res;
199
200   cygheap_fdget cfd (fd);
201   if (cfd < 0)
202     res = -1;
203   else
204     res = cfd->tcgetpgrp ();
205
206   termios_printf ("%d = tcgetpgrp (%d)", res, fd);
207   return res;
208 }
209
210 extern "C" int
211 tcgetsid (int fd)
212 {
213   int res;
214
215   cygheap_fdget cfd (fd);
216   if (cfd < 0)
217     res = -1;
218   else
219     res = cfd->tcgetsid ();
220
221   termios_printf ("%d = tcgetsid (%d)", res, fd);
222   return res;
223 }
224
225 /* tcsetpgrp: POSIX 7.2.4.1 */
226 extern "C" int
227 tcsetpgrp (int fd, pid_t pgid)
228 {
229   int res = -1;
230
231   cygheap_fdget cfd (fd);
232   if (cfd < 0)
233     /* saw an error */;
234   else if (!cfd->is_tty ())
235     set_errno (ENOTTY);
236   else
237     res = cfd->tcsetpgrp (pgid);
238
239   termios_printf ("%d = tcsetpgrp (%d, %d)", res, fd, pgid);
240   return res;
241 }
242
243 /* NIST PCTS requires not macro-only implementation */
244 #undef cfgetospeed
245 #undef cfgetispeed
246 #undef cfsetospeed
247 #undef cfsetispeed
248
249 /* cfgetospeed: POSIX96 7.1.3.1 */
250 extern "C" speed_t
251 cfgetospeed (const struct termios *tp)
252 {
253   return __tonew_termios (tp)->c_ospeed;
254 }
255
256 /* cfgetispeed: POSIX96 7.1.3.1 */
257 extern "C" speed_t
258 cfgetispeed (const struct termios *tp)
259 {
260   return __tonew_termios (tp)->c_ispeed;
261 }
262
263 static inline int
264 setspeed (speed_t &set_speed, speed_t from_speed)
265 {
266   int res;
267   switch (from_speed)
268     {
269     case B0:
270     case B50:
271     case B75:
272     case B110:
273     case B134:
274     case B150:
275     case B200:
276     case B300:
277     case B600:
278     case B1200:
279     case B1800:
280     case B2400:
281     case B4800:
282     case B9600:
283     case B19200:
284     case B38400:
285     case B57600:
286     case B115200:
287     case B128000:
288     case B230400:
289     case B256000:
290     case B460800:
291     case B500000:
292     case B576000:
293     case B921600:
294     case B1000000:
295     case B1152000:
296     case B1500000:
297     case B2000000:
298     case B2500000:
299     case B3000000:
300       set_speed = from_speed;
301       res = 0;
302       break;
303     default:
304       set_errno (EINVAL);
305       res = -1;
306       break;
307     }
308   return res;
309 }
310
311 /* cfsetospeed: POSIX96 7.1.3.1 */
312 extern "C" int
313 cfsetospeed (struct termios *in_tp, speed_t speed)
314 {
315   struct termios *tp = __tonew_termios (in_tp);
316   int res = setspeed (tp->c_ospeed, speed);
317   __toapp_termios (in_tp, tp);
318   return res;
319 }
320
321 /* cfsetispeed: POSIX96 7.1.3.1 */
322 extern "C" int
323 cfsetispeed (struct termios *in_tp, speed_t speed)
324 {
325   struct termios *tp = __tonew_termios (in_tp);
326   int res = setspeed (tp->c_ispeed, speed);
327   __toapp_termios (in_tp, tp);
328   return res;
329 }
330
331 extern "C" void
332 cfmakeraw(struct termios *tp)
333 {
334   tp->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
335                  | INLCR | IGNCR | ICRNL | IXON);
336   tp->c_oflag &= ~OPOST;
337   tp->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
338   tp->c_cflag &= ~(CSIZE | PARENB);
339   tp->c_cflag |= CS8;
340 }