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__) || defined(__OpenBSD__)
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 exist !\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
)
744 rc
= ioctl(fd
, TIOCOUTQ
, &cnt
);
745 if (rc
) fprintf(stderr
, "Error !\n");
746 lpStat
->cbOutQue
= cnt
;
748 rc
= ioctl(fd
, TIOCINQ
, &cnt
);
749 if (rc
) fprintf(stderr
, "Error !\n");
750 lpStat
->cbInQue
= cnt
;
753 "GetCommError: fd %d, error %d, lpStat %d %d %d\n",
755 lpStat
->status
, lpStat
->cbInQue
, lpStat
->cbOutQue
);
759 "GetCommError: fd %d, error %d, lpStat NULL\n",
763 * [RER] I have no idea what the following is trying to accomplish.
764 * [RER] It is certainly not what the reference manual suggests.
766 temperror
= commerror
;
771 /*****************************************************************************
772 * ClearCommError (KERNEL32.21)
774 BOOL32
ClearCommError(INT32 fd
,LPDWORD errors
,LPCOMSTAT lpStat
)
779 "ClearCommError: fd %d (current error %d)\n", fd
, commerror
);
780 temperror
= commerror
;
785 /*****************************************************************************
786 * SetCommEventMask (USER.208)
788 UINT16
*SetCommEventMask(INT16 fd
,UINT16 fuEvtMask
)
790 dprintf_comm(stddeb
,"SetCommEventMask:fd %d,mask %d\n",fd
,fuEvtMask
);
791 eventmask
|= fuEvtMask
;
792 return (UINT16
*)&eventmask
; /* FIXME, should be SEGPTR */
795 /*****************************************************************************
796 * GetCommEventMask (USER.209)
798 UINT16
GetCommEventMask(INT16 fd
,UINT16 fnEvtClear
)
803 "GetCommEventMask: fd %d, mask %d\n", fd
, fnEvtClear
);
806 * Determine if any characters are available
808 if (fnEvtClear
& EV_RXCHAR
)
813 rc
= ioctl(fd
, TIOCINQ
, &cnt
);
814 if (cnt
) events
|= EV_RXCHAR
;
817 "GetCommEventMask: rxchar %ld\n", cnt
);
821 * There are other events that need to be checked for
826 "GetCommEventMask: return events %d\n", events
);
830 * [RER] The following was gibberish
833 tempmask
= eventmask
;
834 eventmask
&= ~fnEvtClear
;
839 /*****************************************************************************
840 * GetCommMask (KERNEL32.156)
842 BOOL32
GetCommMask(INT32 fd
,LPDWORD evtmask
)
845 "GetCommMask: fd %d, mask %p\n", fd
, evtmask
);
846 *evtmask
= eventmask
;
850 /*****************************************************************************
851 * SetCommMask (KERNEL32.451)
853 BOOL32
SetCommMask(INT32 fd
,DWORD evtmask
)
856 "SetCommMask: fd %d, mask %lx\n", fd
, evtmask
);
861 /*****************************************************************************
862 * SetCommState16 (USER.201)
864 INT16
SetCommState16(LPDCB16 lpdcb
)
867 struct DosDeviceStruct
*ptr
;
870 "SetCommState: fd %d, ptr %p\n", lpdcb
->Id
, lpdcb
);
871 if (tcgetattr(lpdcb
->Id
, &port
) == -1) {
872 commerror
= WinError();
877 port
.c_cc
[VTIME
] = 1;
880 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
882 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
884 port
.c_iflag
|= (IGNBRK
);
886 port
.c_oflag
&= ~(OPOST
);
888 port
.c_cflag
&= ~(HUPCL
);
889 port
.c_cflag
|= CLOCAL
| CREAD
;
891 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
892 port
.c_lflag
|= NOFLSH
;
894 if ((ptr
= GetDeviceStruct(lpdcb
->Id
)) == NULL
) {
895 commerror
= IE_BADID
;
898 if (ptr
->baudrate
> 0)
899 lpdcb
->BaudRate
= ptr
->baudrate
;
900 dprintf_comm(stddeb
,"SetCommState: baudrate %d\n",lpdcb
->BaudRate
);
902 port
.c_cflag
&= ~CBAUD
;
903 switch (lpdcb
->BaudRate
) {
906 port
.c_cflag
|= B110
;
910 port
.c_cflag
|= B300
;
914 port
.c_cflag
|= B600
;
918 port
.c_cflag
|= B1200
;
922 port
.c_cflag
|= B2400
;
926 port
.c_cflag
|= B4800
;
930 port
.c_cflag
|= B9600
;
934 port
.c_cflag
|= B19200
;
938 port
.c_cflag
|= B38400
;
941 commerror
= IE_BAUDRATE
;
944 #elif !defined(__EMX__)
945 switch (lpdcb
->BaudRate
) {
948 port
.c_ospeed
= B110
;
952 port
.c_ospeed
= B300
;
956 port
.c_ospeed
= B600
;
960 port
.c_ospeed
= B1200
;
964 port
.c_ospeed
= B2400
;
968 port
.c_ospeed
= B4800
;
972 port
.c_ospeed
= B9600
;
976 port
.c_ospeed
= B19200
;
980 port
.c_ospeed
= B38400
;
983 commerror
= IE_BAUDRATE
;
986 port
.c_ispeed
= port
.c_ospeed
;
988 dprintf_comm(stddeb
,"SetCommState: bytesize %d\n",lpdcb
->ByteSize
);
989 port
.c_cflag
&= ~CSIZE
;
990 switch (lpdcb
->ByteSize
) {
1001 port
.c_cflag
|= CS8
;
1004 commerror
= IE_BYTESIZE
;
1008 dprintf_comm(stddeb
,"SetCommState: parity %d\n",lpdcb
->Parity
);
1009 port
.c_cflag
&= ~(PARENB
| PARODD
);
1011 switch (lpdcb
->Parity
) {
1013 port
.c_iflag
&= ~INPCK
;
1016 port
.c_cflag
|= (PARENB
| PARODD
);
1017 port
.c_iflag
|= INPCK
;
1020 port
.c_cflag
|= PARENB
;
1021 port
.c_iflag
|= INPCK
;
1024 commerror
= IE_BYTESIZE
;
1029 dprintf_comm(stddeb
,"SetCommState: stopbits %d\n",lpdcb
->StopBits
);
1030 switch (lpdcb
->StopBits
) {
1032 port
.c_cflag
&= ~CSTOPB
;
1035 port
.c_cflag
|= CSTOPB
;
1038 commerror
= IE_BYTESIZE
;
1043 if (lpdcb
->fDtrflow
|| lpdcb
->fRtsflow
|| lpdcb
->fOutxCtsFlow
)
1044 port
.c_cflag
|= CRTSCTS
;
1046 if (lpdcb
->fDtrDisable
)
1047 port
.c_cflag
&= ~CRTSCTS
;
1050 port
.c_iflag
|= IXON
;
1052 port
.c_iflag
|= IXOFF
;
1054 if (tcsetattr(lpdcb
->Id
, TCSADRAIN
, &port
) == -1) {
1055 commerror
= WinError();
1063 /*****************************************************************************
1064 * SetCommState32 (KERNEL32.452)
1066 BOOL32
SetCommState32(INT32 fd
,LPDCB32 lpdcb
)
1068 struct termios port
;
1069 struct DosDeviceStruct
*ptr
;
1071 dprintf_comm(stddeb
,"SetCommState: fd %d, ptr %p\n",fd
,lpdcb
);
1072 if (tcgetattr(fd
,&port
) == -1) {
1073 commerror
= WinError();
1077 port
.c_cc
[VMIN
] = 0;
1078 port
.c_cc
[VTIME
] = 1;
1081 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
1083 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
1085 port
.c_iflag
|= (IGNBRK
);
1087 port
.c_oflag
&= ~(OPOST
);
1089 port
.c_cflag
&= ~(HUPCL
);
1090 port
.c_cflag
|= CLOCAL
| CREAD
;
1092 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
1093 port
.c_lflag
|= NOFLSH
;
1095 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1096 commerror
= IE_BADID
;
1099 if (ptr
->baudrate
> 0)
1100 lpdcb
->BaudRate
= ptr
->baudrate
;
1101 dprintf_comm(stddeb
,"SetCommState: baudrate %ld\n",lpdcb
->BaudRate
);
1103 port
.c_cflag
&= ~CBAUD
;
1104 switch (lpdcb
->BaudRate
) {
1107 port
.c_cflag
|= B110
;
1111 port
.c_cflag
|= B300
;
1115 port
.c_cflag
|= B600
;
1119 port
.c_cflag
|= B1200
;
1123 port
.c_cflag
|= B2400
;
1127 port
.c_cflag
|= B4800
;
1131 port
.c_cflag
|= B9600
;
1135 port
.c_cflag
|= B19200
;
1139 port
.c_cflag
|= B38400
;
1142 commerror
= IE_BAUDRATE
;
1145 #elif !defined(__EMX__)
1146 switch (lpdcb
->BaudRate
) {
1149 port
.c_ospeed
= B110
;
1153 port
.c_ospeed
= B300
;
1157 port
.c_ospeed
= B600
;
1161 port
.c_ospeed
= B1200
;
1165 port
.c_ospeed
= B2400
;
1169 port
.c_ospeed
= B4800
;
1173 port
.c_ospeed
= B9600
;
1177 port
.c_ospeed
= B19200
;
1181 port
.c_ospeed
= B38400
;
1184 commerror
= IE_BAUDRATE
;
1187 port
.c_ispeed
= port
.c_ospeed
;
1189 dprintf_comm(stddeb
,"SetCommState: bytesize %d\n",lpdcb
->ByteSize
);
1190 port
.c_cflag
&= ~CSIZE
;
1191 switch (lpdcb
->ByteSize
) {
1193 port
.c_cflag
|= CS5
;
1196 port
.c_cflag
|= CS6
;
1199 port
.c_cflag
|= CS7
;
1202 port
.c_cflag
|= CS8
;
1205 commerror
= IE_BYTESIZE
;
1209 dprintf_comm(stddeb
,"SetCommState: parity %d\n",lpdcb
->Parity
);
1210 port
.c_cflag
&= ~(PARENB
| PARODD
);
1212 switch (lpdcb
->Parity
) {
1214 port
.c_iflag
&= ~INPCK
;
1217 port
.c_cflag
|= (PARENB
| PARODD
);
1218 port
.c_iflag
|= INPCK
;
1221 port
.c_cflag
|= PARENB
;
1222 port
.c_iflag
|= INPCK
;
1225 commerror
= IE_BYTESIZE
;
1230 dprintf_comm(stddeb
,"SetCommState: stopbits %d\n",lpdcb
->StopBits
);
1231 switch (lpdcb
->StopBits
) {
1233 port
.c_cflag
&= ~CSTOPB
;
1236 port
.c_cflag
|= CSTOPB
;
1239 commerror
= IE_BYTESIZE
;
1243 if ( lpdcb
->fOutxCtsFlow
||
1244 lpdcb
->fDtrControl
== DTR_CONTROL_ENABLE
||
1245 lpdcb
->fRtsControl
== RTS_CONTROL_ENABLE
1247 port
.c_cflag
|= CRTSCTS
;
1248 if (lpdcb
->fDtrControl
== DTR_CONTROL_DISABLE
)
1249 port
.c_cflag
&= ~CRTSCTS
;
1253 port
.c_iflag
|= IXON
;
1255 port
.c_iflag
|= IXOFF
;
1257 if (tcsetattr(fd
,TCSADRAIN
,&port
)==-1) {
1258 commerror
= WinError();
1267 /*****************************************************************************
1268 * GetCommState (USER.202)
1270 INT16
GetCommState16(INT16 fd
, LPDCB16 lpdcb
)
1272 struct termios port
;
1274 dprintf_comm(stddeb
,"GetCommState: fd %d, ptr %p\n", fd
, lpdcb
);
1275 if (tcgetattr(fd
, &port
) == -1) {
1276 commerror
= WinError();
1282 switch (port
.c_cflag
& CBAUD
) {
1284 switch (port
.c_ospeed
) {
1287 lpdcb
->BaudRate
= 110;
1290 lpdcb
->BaudRate
= 300;
1293 lpdcb
->BaudRate
= 600;
1296 lpdcb
->BaudRate
= 1200;
1299 lpdcb
->BaudRate
= 2400;
1302 lpdcb
->BaudRate
= 4800;
1305 lpdcb
->BaudRate
= 9600;
1308 lpdcb
->BaudRate
= 19200;
1311 lpdcb
->BaudRate
= 38400;
1315 switch (port
.c_cflag
& CSIZE
) {
1317 lpdcb
->ByteSize
= 5;
1320 lpdcb
->ByteSize
= 6;
1323 lpdcb
->ByteSize
= 7;
1326 lpdcb
->ByteSize
= 8;
1330 switch (port
.c_cflag
& ~(PARENB
| PARODD
)) {
1332 lpdcb
->fParity
= NOPARITY
;
1335 lpdcb
->fParity
= EVENPARITY
;
1337 case (PARENB
| PARODD
):
1338 lpdcb
->fParity
= ODDPARITY
;
1342 if (port
.c_cflag
& CSTOPB
)
1343 lpdcb
->StopBits
= TWOSTOPBITS
;
1345 lpdcb
->StopBits
= ONESTOPBIT
;
1347 lpdcb
->RlsTimeout
= 50;
1348 lpdcb
->CtsTimeout
= 50;
1349 lpdcb
->DsrTimeout
= 50;
1353 lpdcb
->fDtrDisable
= 0;
1357 if (port
.c_cflag
& CRTSCTS
) {
1358 lpdcb
->fDtrflow
= 1;
1359 lpdcb
->fRtsflow
= 1;
1360 lpdcb
->fOutxCtsFlow
= 1;
1361 lpdcb
->fOutxDsrFlow
= 1;
1364 lpdcb
->fDtrDisable
= 1;
1366 if (port
.c_iflag
& IXON
)
1371 if (port
.c_iflag
& IXOFF
)
1380 lpdcb
->XoffLim
= 10;
1386 /*****************************************************************************
1387 * GetCommState (KERNEL32.159)
1389 BOOL32
GetCommState32(INT32 fd
, LPDCB32 lpdcb
)
1391 struct termios port
;
1394 dprintf_comm(stddeb
,"GetCommState32: fd %d, ptr %p\n", fd
, lpdcb
);
1395 if (tcgetattr(fd
, &port
) == -1) {
1396 commerror
= WinError();
1401 switch (port
.c_cflag
& CBAUD
) {
1403 switch (port
.c_ospeed
) {
1406 lpdcb
->BaudRate
= 110;
1409 lpdcb
->BaudRate
= 300;
1412 lpdcb
->BaudRate
= 600;
1415 lpdcb
->BaudRate
= 1200;
1418 lpdcb
->BaudRate
= 2400;
1421 lpdcb
->BaudRate
= 4800;
1424 lpdcb
->BaudRate
= 9600;
1427 lpdcb
->BaudRate
= 19200;
1430 lpdcb
->BaudRate
= 38400;
1434 switch (port
.c_cflag
& CSIZE
) {
1436 lpdcb
->ByteSize
= 5;
1439 lpdcb
->ByteSize
= 6;
1442 lpdcb
->ByteSize
= 7;
1445 lpdcb
->ByteSize
= 8;
1449 switch (port
.c_cflag
& ~(PARENB
| PARODD
)) {
1451 lpdcb
->fParity
= NOPARITY
;
1454 lpdcb
->fParity
= EVENPARITY
;
1456 case (PARENB
| PARODD
):
1457 lpdcb
->fParity
= ODDPARITY
;
1461 if (port
.c_cflag
& CSTOPB
)
1462 lpdcb
->StopBits
= TWOSTOPBITS
;
1464 lpdcb
->StopBits
= ONESTOPBIT
;
1471 if (port
.c_cflag
& CRTSCTS
) {
1472 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
1473 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
1474 lpdcb
->fOutxCtsFlow
= 1;
1475 lpdcb
->fOutxDsrFlow
= 1;
1479 lpdcb
->fDtrControl
= DTR_CONTROL_DISABLE
;
1480 lpdcb
->fRtsControl
= RTS_CONTROL_DISABLE
;
1482 if (port
.c_iflag
& IXON
)
1487 if (port
.c_iflag
& IXOFF
)
1496 lpdcb
->XoffLim
= 10;
1502 /*****************************************************************************
1503 * TransmitCommChar (USER.206)
1505 INT16
TransmitCommChar16(INT16 fd
,CHAR chTransmit
)
1507 struct DosDeviceStruct
*ptr
;
1509 dprintf_comm(stddeb
,
1510 "TransmitCommChar: fd %d, data %d \n", fd
, chTransmit
);
1511 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1512 commerror
= IE_BADID
;
1516 if (ptr
->suspended
) {
1517 commerror
= IE_HARDWARE
;
1521 if (write(fd
, (void *) &chTransmit
, 1) == -1) {
1522 commerror
= WinError();
1530 /*****************************************************************************
1531 * TransmitCommChar (KERNEL32.535)
1533 BOOL32
TransmitCommChar32(INT32 fd
,CHAR chTransmit
)
1535 struct DosDeviceStruct
*ptr
;
1537 dprintf_comm(stddeb
,"TransmitCommChar32(%d,'%c')\n",fd
,chTransmit
);
1538 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1539 commerror
= IE_BADID
;
1543 if (ptr
->suspended
) {
1544 commerror
= IE_HARDWARE
;
1547 if (write(fd
, (void *) &chTransmit
, 1) == -1) {
1548 commerror
= WinError();
1556 /*****************************************************************************
1557 * UngetCommChar (USER.212)
1559 INT16
UngetCommChar(INT16 fd
,CHAR chUnget
)
1561 struct DosDeviceStruct
*ptr
;
1563 dprintf_comm(stddeb
,"UngetCommChar: fd %d (char %d)\n", fd
, chUnget
);
1564 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1565 commerror
= IE_BADID
;
1569 if (ptr
->suspended
) {
1570 commerror
= IE_HARDWARE
;
1575 ptr
->unget_byte
= chUnget
;
1580 /*****************************************************************************
1581 * ReadComm (USER.204)
1583 INT16
ReadComm(INT16 fd
,LPSTR lpvBuf
,INT16 cbRead
)
1586 struct DosDeviceStruct
*ptr
;
1588 dprintf_comm(stddeb
,
1589 "ReadComm: fd %d, ptr %p, length %d\n", fd
, lpvBuf
, cbRead
);
1590 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1591 commerror
= IE_BADID
;
1595 if (ptr
->suspended
) {
1596 commerror
= IE_HARDWARE
;
1601 *lpvBuf
= ptr
->unget_byte
;
1609 status
= read(fd
, (void *) lpvBuf
, cbRead
);
1612 if (errno
!= EAGAIN
) {
1613 commerror
= WinError();
1621 return length
+ status
;
1625 /*****************************************************************************
1626 * WriteComm (USER.205)
1628 INT16
WriteComm(INT16 fd
, LPSTR lpvBuf
, INT16 cbWrite
)
1631 struct DosDeviceStruct
*ptr
;
1633 dprintf_comm(stddeb
,"WriteComm: fd %d, ptr %p, length %d\n",
1634 fd
, lpvBuf
, cbWrite
);
1635 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1636 commerror
= IE_BADID
;
1640 if (ptr
->suspended
) {
1641 commerror
= IE_HARDWARE
;
1645 for (x
=0; x
!= cbWrite
; x
++)
1646 dprintf_comm(stddeb
,"%c", *(lpvBuf
+ x
) );
1648 length
= write(fd
, (void *) lpvBuf
, cbWrite
);
1651 commerror
= WinError();
1660 /*****************************************************************************
1661 * GetCommTimeouts (KERNEL32.160)
1663 BOOL32
GetCommTimeouts(INT32 fd
,LPCOMMTIMEOUTS lptimeouts
) {
1664 fprintf(stderr
,"GetCommTimeouts(%x,%p), empty stub.\n",
1670 /*****************************************************************************
1671 * SetCommTimeouts (KERNEL32.453)
1673 BOOL32
SetCommTimeouts(INT32 fd
,LPCOMMTIMEOUTS lptimeouts
) {
1674 fprintf(stderr
,"SetCommTimeouts(%x,%p), empty stub.\n",
1680 /***********************************************************************
1681 * EnableCommNotification (USER.246)
1683 BOOL16
EnableCommNotification( INT16 fd
, HWND16 hwnd
, INT16 cbWriteNotify
,
1686 fprintf(stderr
, "EnableCommNotification(%d, %x, %d, %d), empty stub.\n", fd
, hwnd
, cbWriteNotify
, cbOutQueue
);