2 * DEC 93 Erik Bos <erik@xs4all.nl>
4 * Copyright 1996 Marcus Meissner
5 * FIXME: use HFILEs instead of unixfds
6 * the win32 functions here get HFILEs already.
8 * May 26, 1997. Fixes and comments by Rick Richardson <rick@dgii.com> [RER]
9 * - ptr->fd wasn't getting cleared on close.
10 * - GetCommEventMask() and GetCommError() didn't do much of anything.
11 * IMHO, they are still wrong, but they at least implement the RXCHAR
12 * event and return I/O queue sizes, which makes the app I'm interested
13 * in (analog devices EZKIT DSP development system) work.
24 #if defined(__NetBSD__) || defined(__FreeBSD__)
25 #include <sys/filio.h>
27 #include <sys/ioctl.h>
39 #define TIOCINQ FIONREAD
43 * [RER] These are globals are wrong. They should be in DosDeviceStruct
44 * on a per port basis.
46 int commerror
= 0, eventmask
= 0;
48 struct DosDeviceStruct COM
[MAX_PORTS
];
49 struct DosDeviceStruct LPT
[MAX_PORTS
];
54 char option
[10], temp
[256], *btemp
;
57 for (x
=0; x
!=MAX_PORTS
; x
++) {
58 strcpy(option
,"COMx");
62 PROFILE_GetWineIniString( "serialports", option
, "*",
64 if (!strcmp(temp
, "*") || *temp
== '\0')
65 COM
[x
].devicename
= NULL
;
67 btemp
= strchr(temp
,',');
70 COM
[x
].baudrate
= atoi(btemp
);
75 if (!S_ISCHR(st
.st_mode
))
76 fprintf(stderr
,"comm: can't use `%s' as %s !\n", temp
, option
);
78 if ((COM
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
79 fprintf(stderr
,"comm: can't malloc for device info!\n");
82 strcpy(COM
[x
].devicename
, temp
);
85 "Comm_Init: %s = %s\n", option
, COM
[x
].devicename
);
88 strcpy(option
, "LPTx");
92 PROFILE_GetWineIniString( "parallelports", option
, "*",
94 if (!strcmp(temp
, "*") || *temp
== '\0')
95 LPT
[x
].devicename
= NULL
;
98 if (!S_ISCHR(st
.st_mode
))
99 fprintf(stderr
,"comm: can't use `%s' as %s !\n", temp
, option
);
101 if ((LPT
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
102 fprintf(stderr
,"comm: can't malloc for device info!\n");
105 strcpy(LPT
[x
].devicename
, temp
);
108 "Comm_Init: %s = %s\n", option
, LPT
[x
].devicename
);
115 struct DosDeviceStruct
*GetDeviceStruct(int fd
)
119 for (x
=0; x
!=MAX_PORTS
; x
++) {
129 int ValidCOMPort(int x
)
131 return(x
< MAX_PORTS
? (int) COM
[x
].devicename
: 0);
134 int ValidLPTPort(int x
)
136 return(x
< MAX_PORTS
? (int) LPT
[x
].devicename
: 0);
141 dprintf_comm(stddeb
, "WinError: errno = %d\n", errno
);
148 /**************************************************************************
149 * BuildCommDCB (USER.213)
151 BOOL16
BuildCommDCB16(LPCSTR device
, LPDCB16 lpdcb
)
153 /* "COM1:9600,n,8,1" */
156 char *ptr
, temp
[256];
159 "BuildCommDCB: (%s), ptr %p\n", device
, lpdcb
);
162 if (!lstrncmpi32A(device
,"COM",3)) {
163 port
= device
[3] - '0';
167 fprintf(stderr
, "comm: BUG ! COM0 can't exists!.\n");
168 commerror
= IE_BADID
;
171 if (!ValidCOMPort(port
)) {
172 commerror
= IE_BADID
;
177 OpenComm(device
, 0, 0);
179 lpdcb
->Id
= COM
[port
].fd
;
184 if (*(device
+4) != ':')
187 strcpy(temp
,device
+5);
188 ptr
= strtok(temp
, ", ");
190 if (COM
[port
].baudrate
> 0)
191 lpdcb
->BaudRate
= COM
[port
].baudrate
;
193 lpdcb
->BaudRate
= atoi(ptr
);
194 dprintf_comm(stddeb
,"BuildCommDCB: baudrate (%d)\n", lpdcb
->BaudRate
);
196 ptr
= strtok(NULL
, ", ");
198 *ptr
= toupper(*ptr
);
200 dprintf_comm(stddeb
,"BuildCommDCB: parity (%c)\n", *ptr
);
204 lpdcb
->Parity
= NOPARITY
;
208 lpdcb
->Parity
= EVENPARITY
;
211 lpdcb
->Parity
= MARKPARITY
;
214 lpdcb
->Parity
= ODDPARITY
;
217 fprintf(stderr
,"comm: unknown parity `%c'!\n", *ptr
);
221 ptr
= strtok(NULL
, ", ");
222 dprintf_comm(stddeb
, "BuildCommDCB: charsize (%c)\n", *ptr
);
223 lpdcb
->ByteSize
= *ptr
- '0';
225 ptr
= strtok(NULL
, ", ");
226 dprintf_comm(stddeb
, "BuildCommDCB: stopbits (%c)\n", *ptr
);
229 lpdcb
->StopBits
= ONESTOPBIT
;
232 lpdcb
->StopBits
= TWOSTOPBITS
;
235 fprintf(stderr
,"comm: unknown # of stopbits `%c'!\n", *ptr
);
243 /**************************************************************************
244 * BuildCommDCBA (KERNEL32.14)
246 BOOL32
BuildCommDCB32A(LPCSTR device
,LPDCB32 lpdcb
) {
247 return BuildCommDCBAndTimeouts32A(device
,lpdcb
,NULL
);
250 /**************************************************************************
251 * BuildCommDCBAndTimeoutsA (KERNEL32.15)
253 BOOL32
BuildCommDCBAndTimeouts32A(LPCSTR device
, LPDCB32 lpdcb
,LPCOMMTIMEOUTS lptimeouts
) {
257 dprintf_comm(stddeb
,"BuildCommDCBAndTimeouts32A(%s,%p,%p)\n",device
,lpdcb
,lptimeouts
);
260 if (!lstrncmpi32A(device
,"COM",3)) {
263 fprintf(stderr
,"comm:BUG! COM0 can't exists!.\n");
266 if (!ValidCOMPort(port
))
268 if (*(device
+4)!=':')
270 temp
=(LPSTR
)(device
+5);
273 lpdcb
->DCBlength
= sizeof(DCB32
);
274 if (strchr(temp
,',')) { /* old style */
277 char last
=temp
[strlen(temp
)-1];
279 ret
=BuildCommDCB16(device
,&dcb16
);
282 lpdcb
->BaudRate
= dcb16
.BaudRate
;
283 lpdcb
->ByteSize
= dcb16
.ByteSize
;
284 lpdcb
->fBinary
= dcb16
.fBinary
;
285 lpdcb
->Parity
= dcb16
.Parity
;
286 lpdcb
->fParity
= dcb16
.fParity
;
287 lpdcb
->fNull
= dcb16
.fNull
;
288 lpdcb
->StopBits
= dcb16
.StopBits
;
292 lpdcb
->fOutxCtsFlow
= FALSE
;
293 lpdcb
->fOutxDsrFlow
= FALSE
;
294 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
295 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
296 } else if (last
=='p') {
298 lpdcb
->fOutX
= FALSE
;
299 lpdcb
->fOutxCtsFlow
= TRUE
;
300 lpdcb
->fOutxDsrFlow
= TRUE
;
301 lpdcb
->fDtrControl
= DTR_CONTROL_HANDSHAKE
;
302 lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
;
305 lpdcb
->fOutX
= FALSE
;
306 lpdcb
->fOutxCtsFlow
= FALSE
;
307 lpdcb
->fOutxDsrFlow
= FALSE
;
308 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
309 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
311 lpdcb
->XonChar
= dcb16
.XonChar
;
312 lpdcb
->XoffChar
= dcb16
.XoffChar
;
313 lpdcb
->ErrorChar
= dcb16
.PeChar
;
314 lpdcb
->fErrorChar
= dcb16
.fPeChar
;
315 lpdcb
->EofChar
= dcb16
.EofChar
;
316 lpdcb
->EvtChar
= dcb16
.EvtChar
;
317 lpdcb
->XonLim
= dcb16
.XonLim
;
318 lpdcb
->XoffLim
= dcb16
.XoffLim
;
321 ptr
=strtok(temp
," ");
326 if (!strncmp("baud=",ptr
,5)) {
327 if (!sscanf(ptr
+5,"%ld",&x
))
328 fprintf(stderr
,"BuildCommDCB32A:Couldn't parse %s\n",ptr
);
332 if (!strncmp("stop=",ptr
,5)) {
333 if (!sscanf(ptr
+5,"%ld",&x
))
334 fprintf(stderr
,"BuildCommDCB32A:Couldn't parse %s\n",ptr
);
338 if (!strncmp("data=",ptr
,5)) {
339 if (!sscanf(ptr
+5,"%ld",&x
))
340 fprintf(stderr
,"BuildCommDCB32A:Couldn't parse %s\n",ptr
);
344 if (!strncmp("parity=",ptr
,7)) {
345 lpdcb
->fParity
= TRUE
;
348 lpdcb
->fParity
= FALSE
;
349 lpdcb
->Parity
= NOPARITY
;
352 lpdcb
->Parity
= EVENPARITY
;
355 lpdcb
->Parity
= ODDPARITY
;
358 lpdcb
->Parity
= MARKPARITY
;
364 fprintf(stderr
,"BuildCommDCB32A: Unhandled specifier '%s', please report.\n",ptr
);
365 ptr
=strtok(NULL
," ");
367 if (lpdcb
->BaudRate
==110)
372 /**************************************************************************
373 * BuildCommDCBAndTimeoutsW (KERNEL32.16)
375 BOOL32
BuildCommDCBAndTimeouts32W(
376 LPCWSTR devid
,LPDCB32 lpdcb
,LPCOMMTIMEOUTS lptimeouts
381 dprintf_comm(stddeb
,"BuildCommDCBAndTimeouts32W(%p,%p,%p)\n",devid
,lpdcb
,lptimeouts
);
382 devidA
= HEAP_strdupWtoA( GetProcessHeap(), 0, devid
);
383 ret
=BuildCommDCBAndTimeouts32A(devidA
,lpdcb
,lptimeouts
);
384 HeapFree( GetProcessHeap(), 0, devidA
);
388 /**************************************************************************
389 * BuildCommDCBW (KERNEL32.17)
391 BOOL32
BuildCommDCB32W(LPCWSTR devid
,LPDCB32 lpdcb
) {
392 return BuildCommDCBAndTimeouts32W(devid
,lpdcb
,NULL
);
395 /*****************************************************************************
396 * OpenComm (USER.200)
398 INT16
OpenComm(LPCSTR device
,UINT16 cbInQueue
,UINT16 cbOutQueue
)
403 "OpenComm: %s, %d, %d\n", device
, cbInQueue
, cbOutQueue
);
406 if (!lstrncmpi32A(device
,"COM",3)) {
407 port
= device
[3] - '0';
410 fprintf(stderr
, "comm: BUG ! COM0 doesn't exists!.\n");
411 commerror
= IE_BADID
;
415 "OpenComm: %s = %s\n", device
, COM
[port
].devicename
);
417 if (!ValidCOMPort(port
)) {
418 commerror
= IE_BADID
;
425 fd
= open(COM
[port
].devicename
, O_RDWR
| O_NONBLOCK
);
427 commerror
= WinError();
435 if (!lstrncmpi32A(device
,"LPT",3)) {
436 port
= device
[3] - '0';
438 if (!ValidLPTPort(port
)) {
439 commerror
= IE_BADID
;
447 fd
= open(LPT
[port
].devicename
, O_RDWR
| O_NONBLOCK
, 0);
449 commerror
= WinError();
459 /*****************************************************************************
460 * CloseComm (USER.207)
462 INT16
CloseComm(INT16 fd
)
464 struct DosDeviceStruct
*ptr
;
466 dprintf_comm(stddeb
,"CloseComm: fd %d\n", fd
);
467 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
468 commerror
= IE_BADID
;
472 ptr
->fd
= 0; /* [RER] Really, -1 would be a better value */
474 if (close(fd
) == -1) {
475 commerror
= WinError();
483 /*****************************************************************************
484 * SetCommBreak (USER.210)
486 INT16
SetCommBreak16(INT16 fd
)
488 struct DosDeviceStruct
*ptr
;
490 dprintf_comm(stddeb
,"SetCommBreak: fd: %d\n", fd
);
491 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
492 commerror
= IE_BADID
;
501 /*****************************************************************************
502 * SetCommBreak (KERNEL32.449)
504 BOOL32
SetCommBreak32(INT32 fd
)
507 struct DosDeviceStruct
*ptr
;
509 dprintf_comm(stddeb
,"SetCommBreak: fd: %d\n", fd
);
510 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
511 commerror
= IE_BADID
;
520 /*****************************************************************************
521 * ClearCommBreak (USER.211)
523 INT16
ClearCommBreak16(INT16 fd
)
525 struct DosDeviceStruct
*ptr
;
527 dprintf_comm(stddeb
,"ClearCommBreak: fd: %d\n", fd
);
528 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
529 commerror
= IE_BADID
;
538 /*****************************************************************************
539 * ClearCommBreak (KERNEL32.20)
541 BOOL32
ClearCommBreak32(INT32 fd
)
543 struct DosDeviceStruct
*ptr
;
545 dprintf_comm(stddeb
,"ClearCommBreak: fd: %d\n", fd
);
546 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
547 commerror
= IE_BADID
;
556 /*****************************************************************************
557 * EscapeCommFunction (USER.214)
559 LONG
EscapeCommFunction16(UINT16 fd
,UINT16 nFunction
)
564 dprintf_comm(stddeb
,"EscapeCommFunction fd: %d, function: %d\n", fd
, nFunction
);
565 if (tcgetattr(fd
,&port
) == -1) {
566 commerror
=WinError();
575 for (max
= MAX_PORTS
;!COM
[max
].devicename
;max
--)
581 for (max
= MAX_PORTS
;!LPT
[max
].devicename
;max
--)
588 port
.c_cflag
&= TIOCM_DTR
;
594 port
.c_cflag
&= TIOCM_RTS
;
600 port
.c_cflag
|= CRTSCTS
;
604 port
.c_cflag
|= CRTSCTS
;
609 port
.c_iflag
|= IXOFF
;
613 port
.c_iflag
|= IXON
;
618 "EscapeCommFunction fd: %d, unknown function: %d\n",
623 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
624 commerror
= WinError();
632 /*****************************************************************************
633 * EscapeCommFunction (KERNEL32.214)
635 BOOL32
EscapeCommFunction32(INT32 fd
,UINT32 nFunction
)
638 struct DosDeviceStruct
*ptr
;
640 dprintf_comm(stddeb
,"EscapeCommFunction fd: %d, function: %d\n", fd
, nFunction
);
641 if (tcgetattr(fd
,&port
) == -1) {
642 commerror
=WinError();
645 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
646 commerror
= IE_BADID
;
656 port
.c_cflag
&= TIOCM_DTR
;
662 port
.c_cflag
&= TIOCM_RTS
;
668 port
.c_cflag
|= CRTSCTS
;
672 port
.c_cflag
|= CRTSCTS
;
677 port
.c_iflag
|= IXOFF
;
681 port
.c_iflag
|= IXON
;
691 "EscapeCommFunction32 fd: %d, unknown function: %d\n",
696 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
697 commerror
= WinError();
705 /*****************************************************************************
706 * FlushComm (USER.215)
708 INT16
FlushComm(INT16 fd
,INT16 fnQueue
)
712 dprintf_comm(stddeb
,"FlushComm fd: %d, queue: %d\n", fd
, fnQueue
);
714 case 0: queue
= TCOFLUSH
;
716 case 1: queue
= TCIFLUSH
;
718 default:fprintf(stderr
,
719 "FlushComm fd: %d, UNKNOWN queue: %d\n",
723 if (tcflush(fd
, fnQueue
)) {
724 commerror
= WinError();
732 /*****************************************************************************
733 * GetCommError (USER.203)
735 INT16
GetCommError(INT16 fd
,LPCOMSTAT lpStat
)
743 rc
= ioctl(fd
, TIOCOUTQ
, &cnt
);
744 lpStat
->cbOutQue
= cnt
;
746 rc
= ioctl(fd
, TIOCINQ
, &cnt
);
747 lpStat
->cbInQue
= cnt
;
750 "GetCommError: fd %d, error %d, lpStat %d %d %d\n",
752 lpStat
->status
, lpStat
->cbInQue
, lpStat
->cbOutQue
);
754 * [RER] I have no idea what the following is trying to accomplish.
755 * [RER] It is certainly not what the reference manual suggests.
757 temperror
= commerror
;
762 /*****************************************************************************
763 * ClearCommError (KERNEL32.21)
765 BOOL32
ClearCommError(INT32 fd
,LPDWORD errors
,LPCOMSTAT lpStat
)
770 "ClearCommError: fd %d (current error %d)\n", fd
, commerror
);
771 temperror
= commerror
;
776 /*****************************************************************************
777 * SetCommEventMask (USER.208)
779 UINT16
*SetCommEventMask(INT16 fd
,UINT16 fuEvtMask
)
781 dprintf_comm(stddeb
,"SetCommEventMask:fd %d,mask %d\n",fd
,fuEvtMask
);
782 eventmask
|= fuEvtMask
;
783 return (UINT16
*)&eventmask
; /* FIXME, should be SEGPTR */
786 /*****************************************************************************
787 * GetCommEventMask (USER.209)
789 UINT16
GetCommEventMask(INT16 fd
,UINT16 fnEvtClear
)
794 "GetCommEventMask: fd %d, mask %d\n", fd
, fnEvtClear
);
797 * Determine if any characters are available
799 if (fnEvtClear
& EV_RXCHAR
)
804 rc
= ioctl(fd
, TIOCINQ
, &cnt
);
805 if (cnt
) events
|= EV_RXCHAR
;
808 "GetCommEventMask: rxchar %ld\n", cnt
);
812 * There are other events that need to be checked for
817 "GetCommEventMask: return events %d\n", events
);
821 * [RER] The following was gibberish
824 tempmask
= eventmask
;
825 eventmask
&= ~fnEvtClear
;
830 /*****************************************************************************
831 * GetCommMask (KERNEL32.156)
833 BOOL32
GetCommMask(INT32 fd
,LPDWORD evtmask
)
836 "GetCommMask: fd %d, mask %p\n", fd
, evtmask
);
837 *evtmask
= eventmask
;
841 /*****************************************************************************
842 * SetCommMask (KERNEL32.451)
844 BOOL32
SetCommMask(INT32 fd
,DWORD evtmask
)
847 "SetCommMask: fd %d, mask %lx\n", fd
, evtmask
);
852 /*****************************************************************************
853 * SetCommState16 (USER.201)
855 INT16
SetCommState16(LPDCB16 lpdcb
)
858 struct DosDeviceStruct
*ptr
;
861 "SetCommState: fd %d, ptr %p\n", lpdcb
->Id
, lpdcb
);
862 if (tcgetattr(lpdcb
->Id
, &port
) == -1) {
863 commerror
= WinError();
868 port
.c_cc
[VTIME
] = 1;
871 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
873 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
875 port
.c_iflag
|= (IGNBRK
);
877 port
.c_oflag
&= ~(OPOST
);
879 port
.c_cflag
&= ~(HUPCL
);
880 port
.c_cflag
|= CLOCAL
| CREAD
;
882 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
883 port
.c_lflag
|= NOFLSH
;
885 if ((ptr
= GetDeviceStruct(lpdcb
->Id
)) == NULL
) {
886 commerror
= IE_BADID
;
889 if (ptr
->baudrate
> 0)
890 lpdcb
->BaudRate
= ptr
->baudrate
;
891 dprintf_comm(stddeb
,"SetCommState: baudrate %d\n",lpdcb
->BaudRate
);
893 port
.c_cflag
&= ~CBAUD
;
894 switch (lpdcb
->BaudRate
) {
897 port
.c_cflag
|= B110
;
901 port
.c_cflag
|= B300
;
905 port
.c_cflag
|= B600
;
909 port
.c_cflag
|= B1200
;
913 port
.c_cflag
|= B2400
;
917 port
.c_cflag
|= B4800
;
921 port
.c_cflag
|= B9600
;
925 port
.c_cflag
|= B19200
;
929 port
.c_cflag
|= B38400
;
932 commerror
= IE_BAUDRATE
;
935 #elif !defined(__EMX__)
936 switch (lpdcb
->BaudRate
) {
939 port
.c_ospeed
= B110
;
943 port
.c_ospeed
= B300
;
947 port
.c_ospeed
= B600
;
951 port
.c_ospeed
= B1200
;
955 port
.c_ospeed
= B2400
;
959 port
.c_ospeed
= B4800
;
963 port
.c_ospeed
= B9600
;
967 port
.c_ospeed
= B19200
;
971 port
.c_ospeed
= B38400
;
974 commerror
= IE_BAUDRATE
;
977 port
.c_ispeed
= port
.c_ospeed
;
979 dprintf_comm(stddeb
,"SetCommState: bytesize %d\n",lpdcb
->ByteSize
);
980 port
.c_cflag
&= ~CSIZE
;
981 switch (lpdcb
->ByteSize
) {
995 commerror
= IE_BYTESIZE
;
999 dprintf_comm(stddeb
,"SetCommState: parity %d\n",lpdcb
->Parity
);
1000 port
.c_cflag
&= ~(PARENB
| PARODD
);
1002 switch (lpdcb
->Parity
) {
1004 port
.c_iflag
&= ~INPCK
;
1007 port
.c_cflag
|= (PARENB
| PARODD
);
1008 port
.c_iflag
|= INPCK
;
1011 port
.c_cflag
|= PARENB
;
1012 port
.c_iflag
|= INPCK
;
1015 commerror
= IE_BYTESIZE
;
1020 dprintf_comm(stddeb
,"SetCommState: stopbits %d\n",lpdcb
->StopBits
);
1021 switch (lpdcb
->StopBits
) {
1023 port
.c_cflag
&= ~CSTOPB
;
1026 port
.c_cflag
|= CSTOPB
;
1029 commerror
= IE_BYTESIZE
;
1034 if (lpdcb
->fDtrflow
|| lpdcb
->fRtsflow
|| lpdcb
->fOutxCtsFlow
)
1035 port
.c_cflag
|= CRTSCTS
;
1037 if (lpdcb
->fDtrDisable
)
1038 port
.c_cflag
&= ~CRTSCTS
;
1041 port
.c_iflag
|= IXON
;
1043 port
.c_iflag
|= IXOFF
;
1045 if (tcsetattr(lpdcb
->Id
, TCSADRAIN
, &port
) == -1) {
1046 commerror
= WinError();
1054 /*****************************************************************************
1055 * SetCommState32 (KERNEL32.452)
1057 BOOL32
SetCommState32(INT32 fd
,LPDCB32 lpdcb
)
1059 struct termios port
;
1060 struct DosDeviceStruct
*ptr
;
1062 dprintf_comm(stddeb
,"SetCommState: fd %d, ptr %p\n",fd
,lpdcb
);
1063 if (tcgetattr(fd
,&port
) == -1) {
1064 commerror
= WinError();
1068 port
.c_cc
[VMIN
] = 0;
1069 port
.c_cc
[VTIME
] = 1;
1072 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
1074 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
1076 port
.c_iflag
|= (IGNBRK
);
1078 port
.c_oflag
&= ~(OPOST
);
1080 port
.c_cflag
&= ~(HUPCL
);
1081 port
.c_cflag
|= CLOCAL
| CREAD
;
1083 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
1084 port
.c_lflag
|= NOFLSH
;
1086 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1087 commerror
= IE_BADID
;
1090 if (ptr
->baudrate
> 0)
1091 lpdcb
->BaudRate
= ptr
->baudrate
;
1092 dprintf_comm(stddeb
,"SetCommState: baudrate %ld\n",lpdcb
->BaudRate
);
1094 port
.c_cflag
&= ~CBAUD
;
1095 switch (lpdcb
->BaudRate
) {
1098 port
.c_cflag
|= B110
;
1102 port
.c_cflag
|= B300
;
1106 port
.c_cflag
|= B600
;
1110 port
.c_cflag
|= B1200
;
1114 port
.c_cflag
|= B2400
;
1118 port
.c_cflag
|= B4800
;
1122 port
.c_cflag
|= B9600
;
1126 port
.c_cflag
|= B19200
;
1130 port
.c_cflag
|= B38400
;
1133 commerror
= IE_BAUDRATE
;
1136 #elif !defined(__EMX__)
1137 switch (lpdcb
->BaudRate
) {
1140 port
.c_ospeed
= B110
;
1144 port
.c_ospeed
= B300
;
1148 port
.c_ospeed
= B600
;
1152 port
.c_ospeed
= B1200
;
1156 port
.c_ospeed
= B2400
;
1160 port
.c_ospeed
= B4800
;
1164 port
.c_ospeed
= B9600
;
1168 port
.c_ospeed
= B19200
;
1172 port
.c_ospeed
= B38400
;
1175 commerror
= IE_BAUDRATE
;
1178 port
.c_ispeed
= port
.c_ospeed
;
1180 dprintf_comm(stddeb
,"SetCommState: bytesize %d\n",lpdcb
->ByteSize
);
1181 port
.c_cflag
&= ~CSIZE
;
1182 switch (lpdcb
->ByteSize
) {
1184 port
.c_cflag
|= CS5
;
1187 port
.c_cflag
|= CS6
;
1190 port
.c_cflag
|= CS7
;
1193 port
.c_cflag
|= CS8
;
1196 commerror
= IE_BYTESIZE
;
1200 dprintf_comm(stddeb
,"SetCommState: parity %d\n",lpdcb
->Parity
);
1201 port
.c_cflag
&= ~(PARENB
| PARODD
);
1203 switch (lpdcb
->Parity
) {
1205 port
.c_iflag
&= ~INPCK
;
1208 port
.c_cflag
|= (PARENB
| PARODD
);
1209 port
.c_iflag
|= INPCK
;
1212 port
.c_cflag
|= PARENB
;
1213 port
.c_iflag
|= INPCK
;
1216 commerror
= IE_BYTESIZE
;
1221 dprintf_comm(stddeb
,"SetCommState: stopbits %d\n",lpdcb
->StopBits
);
1222 switch (lpdcb
->StopBits
) {
1224 port
.c_cflag
&= ~CSTOPB
;
1227 port
.c_cflag
|= CSTOPB
;
1230 commerror
= IE_BYTESIZE
;
1234 if ( lpdcb
->fOutxCtsFlow
||
1235 lpdcb
->fDtrControl
== DTR_CONTROL_ENABLE
||
1236 lpdcb
->fRtsControl
== RTS_CONTROL_ENABLE
1238 port
.c_cflag
|= CRTSCTS
;
1239 if (lpdcb
->fDtrControl
== DTR_CONTROL_DISABLE
)
1240 port
.c_cflag
&= ~CRTSCTS
;
1244 port
.c_iflag
|= IXON
;
1246 port
.c_iflag
|= IXOFF
;
1248 if (tcsetattr(fd
,TCSADRAIN
,&port
)==-1) {
1249 commerror
= WinError();
1258 /*****************************************************************************
1259 * GetCommState (USER.202)
1261 INT16
GetCommState16(INT16 fd
, LPDCB16 lpdcb
)
1263 struct termios port
;
1265 dprintf_comm(stddeb
,"GetCommState: fd %d, ptr %p\n", fd
, lpdcb
);
1266 if (tcgetattr(fd
, &port
) == -1) {
1267 commerror
= WinError();
1273 switch (port
.c_cflag
& CBAUD
) {
1275 switch (port
.c_ospeed
) {
1278 lpdcb
->BaudRate
= 110;
1281 lpdcb
->BaudRate
= 300;
1284 lpdcb
->BaudRate
= 600;
1287 lpdcb
->BaudRate
= 1200;
1290 lpdcb
->BaudRate
= 2400;
1293 lpdcb
->BaudRate
= 4800;
1296 lpdcb
->BaudRate
= 9600;
1299 lpdcb
->BaudRate
= 19200;
1302 lpdcb
->BaudRate
= 38400;
1306 switch (port
.c_cflag
& CSIZE
) {
1308 lpdcb
->ByteSize
= 5;
1311 lpdcb
->ByteSize
= 6;
1314 lpdcb
->ByteSize
= 7;
1317 lpdcb
->ByteSize
= 8;
1321 switch (port
.c_cflag
& ~(PARENB
| PARODD
)) {
1323 lpdcb
->fParity
= NOPARITY
;
1326 lpdcb
->fParity
= EVENPARITY
;
1328 case (PARENB
| PARODD
):
1329 lpdcb
->fParity
= ODDPARITY
;
1333 if (port
.c_cflag
& CSTOPB
)
1334 lpdcb
->StopBits
= TWOSTOPBITS
;
1336 lpdcb
->StopBits
= ONESTOPBIT
;
1338 lpdcb
->RlsTimeout
= 50;
1339 lpdcb
->CtsTimeout
= 50;
1340 lpdcb
->DsrTimeout
= 50;
1344 lpdcb
->fDtrDisable
= 0;
1348 if (port
.c_cflag
& CRTSCTS
) {
1349 lpdcb
->fDtrflow
= 1;
1350 lpdcb
->fRtsflow
= 1;
1351 lpdcb
->fOutxCtsFlow
= 1;
1352 lpdcb
->fOutxDsrFlow
= 1;
1355 lpdcb
->fDtrDisable
= 1;
1357 if (port
.c_iflag
& IXON
)
1362 if (port
.c_iflag
& IXOFF
)
1371 lpdcb
->XoffLim
= 10;
1377 /*****************************************************************************
1378 * GetCommState (KERNEL32.159)
1380 BOOL32
GetCommState32(INT32 fd
, LPDCB32 lpdcb
)
1382 struct termios port
;
1385 dprintf_comm(stddeb
,"GetCommState32: fd %d, ptr %p\n", fd
, lpdcb
);
1386 if (tcgetattr(fd
, &port
) == -1) {
1387 commerror
= WinError();
1392 switch (port
.c_cflag
& CBAUD
) {
1394 switch (port
.c_ospeed
) {
1397 lpdcb
->BaudRate
= 110;
1400 lpdcb
->BaudRate
= 300;
1403 lpdcb
->BaudRate
= 600;
1406 lpdcb
->BaudRate
= 1200;
1409 lpdcb
->BaudRate
= 2400;
1412 lpdcb
->BaudRate
= 4800;
1415 lpdcb
->BaudRate
= 9600;
1418 lpdcb
->BaudRate
= 19200;
1421 lpdcb
->BaudRate
= 38400;
1425 switch (port
.c_cflag
& CSIZE
) {
1427 lpdcb
->ByteSize
= 5;
1430 lpdcb
->ByteSize
= 6;
1433 lpdcb
->ByteSize
= 7;
1436 lpdcb
->ByteSize
= 8;
1440 switch (port
.c_cflag
& ~(PARENB
| PARODD
)) {
1442 lpdcb
->fParity
= NOPARITY
;
1445 lpdcb
->fParity
= EVENPARITY
;
1447 case (PARENB
| PARODD
):
1448 lpdcb
->fParity
= ODDPARITY
;
1452 if (port
.c_cflag
& CSTOPB
)
1453 lpdcb
->StopBits
= TWOSTOPBITS
;
1455 lpdcb
->StopBits
= ONESTOPBIT
;
1462 if (port
.c_cflag
& CRTSCTS
) {
1463 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
1464 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
1465 lpdcb
->fOutxCtsFlow
= 1;
1466 lpdcb
->fOutxDsrFlow
= 1;
1470 lpdcb
->fDtrControl
= DTR_CONTROL_DISABLE
;
1471 lpdcb
->fRtsControl
= RTS_CONTROL_DISABLE
;
1473 if (port
.c_iflag
& IXON
)
1478 if (port
.c_iflag
& IXOFF
)
1487 lpdcb
->XoffLim
= 10;
1493 /*****************************************************************************
1494 * TransmitCommChar (USER.206)
1496 INT16
TransmitCommChar16(INT16 fd
,CHAR chTransmit
)
1498 struct DosDeviceStruct
*ptr
;
1500 dprintf_comm(stddeb
,
1501 "TransmitCommChar: fd %d, data %d \n", fd
, chTransmit
);
1502 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1503 commerror
= IE_BADID
;
1507 if (ptr
->suspended
) {
1508 commerror
= IE_HARDWARE
;
1512 if (write(fd
, (void *) &chTransmit
, 1) == -1) {
1513 commerror
= WinError();
1521 /*****************************************************************************
1522 * TransmitCommChar (KERNEL32.535)
1524 BOOL32
TransmitCommChar32(INT32 fd
,CHAR chTransmit
)
1526 struct DosDeviceStruct
*ptr
;
1528 dprintf_comm(stddeb
,"TransmitCommChar32(%d,'%c')\n",fd
,chTransmit
);
1529 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1530 commerror
= IE_BADID
;
1534 if (ptr
->suspended
) {
1535 commerror
= IE_HARDWARE
;
1538 if (write(fd
, (void *) &chTransmit
, 1) == -1) {
1539 commerror
= WinError();
1547 /*****************************************************************************
1548 * UngetCommChar (USER.212)
1550 INT16
UngetCommChar(INT16 fd
,CHAR chUnget
)
1552 struct DosDeviceStruct
*ptr
;
1554 dprintf_comm(stddeb
,"UngetCommChar: fd %d (char %d)\n", fd
, chUnget
);
1555 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1556 commerror
= IE_BADID
;
1560 if (ptr
->suspended
) {
1561 commerror
= IE_HARDWARE
;
1566 ptr
->unget_byte
= chUnget
;
1571 /*****************************************************************************
1572 * ReadComm (USER.204)
1574 INT16
ReadComm(INT16 fd
,LPSTR lpvBuf
,INT16 cbRead
)
1577 struct DosDeviceStruct
*ptr
;
1579 dprintf_comm(stddeb
,
1580 "ReadComm: fd %d, ptr %p, length %d\n", fd
, lpvBuf
, cbRead
);
1581 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1582 commerror
= IE_BADID
;
1586 if (ptr
->suspended
) {
1587 commerror
= IE_HARDWARE
;
1592 *lpvBuf
= ptr
->unget_byte
;
1600 status
= read(fd
, (void *) lpvBuf
, cbRead
);
1603 if (errno
!= EAGAIN
) {
1604 commerror
= WinError();
1612 return length
+ status
;
1616 /*****************************************************************************
1617 * WriteComm (USER.205)
1619 INT16
WriteComm(INT16 fd
, LPSTR lpvBuf
, INT16 cbWrite
)
1622 struct DosDeviceStruct
*ptr
;
1624 dprintf_comm(stddeb
,"WriteComm: fd %d, ptr %p, length %d\n",
1625 fd
, lpvBuf
, cbWrite
);
1626 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1627 commerror
= IE_BADID
;
1631 if (ptr
->suspended
) {
1632 commerror
= IE_HARDWARE
;
1636 for (x
=0; x
!= cbWrite
; x
++)
1637 dprintf_comm(stddeb
,"%c", *(lpvBuf
+ x
) );
1639 length
= write(fd
, (void *) lpvBuf
, cbWrite
);
1642 commerror
= WinError();
1651 /*****************************************************************************
1652 * GetCommTimeouts (KERNEL32.160)
1654 BOOL32
GetCommTimeouts(INT32 fd
,LPCOMMTIMEOUTS lptimeouts
) {
1655 dprintf_comm(stddeb
,"GetCommTimeouts(%x,%p), empty stub.\n",
1661 /*****************************************************************************
1662 * SetCommTimeouts (KERNEL32.453)
1664 BOOL32
SetCommTimeouts(INT32 fd
,LPCOMMTIMEOUTS lptimeouts
) {
1665 dprintf_comm(stddeb
,"SetCommTimeouts(%x,%p), empty stub.\n",