1 /*
2  * Copyright (C) 2006 Adam Kropelin
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of version 2 of the GNU General
6  * Public License as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public
14  * License along with this program; if not, write to the Free
15  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16  * MA 02110-1335, USA.
17  */
18 
19 #include <errno.h>
20 #include <io.h>
21 #include <sys/termios.h>
22 #include "winapi.h"
23 
24 /* Convert POSIX baud constants to Win32 constants */
winbaud(int baud)25 static DWORD winbaud(int baud)
26 {
27    switch(baud) {
28    case B110:
29       return CBR_110;
30    case B300:
31       return CBR_300;
32    case B600:
33       return CBR_600;
34    case B1200:
35       return CBR_1200;
36    case B2400:
37    default:
38       return CBR_2400;
39    case B4800:
40       return CBR_4800;
41    case B9600:
42       return CBR_9600;
43    case B19200:
44       return CBR_19200;
45    case B38400:
46       return CBR_38400;
47    case B57600:
48       return CBR_57600;
49    case B115200:
50       return CBR_115200;
51    case B128000:
52       return CBR_128000;
53    case B256000:
54       return CBR_256000;
55    }
56 }
57 
58 /* Convert POSIX bytesize constants to Win32 constants */
winsize(int size)59 static BYTE winsize(int size)
60 {
61    switch(size) {
62    case CS5:
63       return 5;
64    case CS6:
65       return 6;
66    case CS7:
67       return 7;
68    case CS8:
69    default:
70       return 8;
71    }
72 }
73 
tcsetattr(int fd,int optional_actions,const struct termios * in)74 int tcsetattr (int fd, int optional_actions, const struct termios *in)
75 {
76    DCB dcb;
77    dcb.DCBlength = sizeof(DCB);
78 
79    HANDLE h = (HANDLE)_get_osfhandle(fd);
80    if (h == 0) {
81       errno = EBADF;
82       return -1;
83    }
84 
85    GetCommState(h, &dcb);
86 
87    dcb.fBinary = 1;
88    dcb.BaudRate = winbaud(in->c_cflag & CBAUD);
89    dcb.ByteSize = winsize(in->c_cflag & CSIZE);
90    dcb.StopBits = in->c_cflag & CSTOPB ? TWOSTOPBITS : ONESTOPBIT;
91 
92    if (in->c_cflag & PARENB) {
93       dcb.fParity = 1;
94       dcb.Parity = in->c_cflag & PARODD ? ODDPARITY : EVENPARITY;
95    } else {
96       dcb.fParity = 0;
97       dcb.Parity = NOPARITY;
98    }
99 
100    if (in->c_cflag & CLOCAL) {
101       dcb.fOutxCtsFlow = 0;
102       dcb.fOutxDsrFlow = 0;
103       dcb.fDsrSensitivity = 0;
104    }
105 
106    dcb.fOutX = !!(in->c_iflag & IXON);
107    dcb.fInX = !!(in->c_iflag & IXOFF);
108 
109    SetCommState(h, &dcb);
110 
111    /* If caller wants a read() timeout, set that up */
112    if (in->c_cc[VMIN] == 0 && in->c_cc[VTIME] != 0) {
113       COMMTIMEOUTS ct;
114       ct.ReadIntervalTimeout = MAXDWORD;
115       ct.ReadTotalTimeoutMultiplier = MAXDWORD;
116       ct.ReadTotalTimeoutConstant = in->c_cc[VTIME] * 100;
117       ct.WriteTotalTimeoutMultiplier = 0;
118       ct.WriteTotalTimeoutConstant = 0;
119       SetCommTimeouts(h, &ct);
120    }
121 
122    return 0;
123 }
124