Release 970804
[wine/multimedia.git] / misc / comm.c
blobd119200ee39c22e61d6f2c0279d27a348a681531
1 /*
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.
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <termios.h>
19 #include <fcntl.h>
20 #include <string.h>
21 #include <errno.h>
22 #include <ctype.h>
23 #include <sys/stat.h>
24 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
25 #include <sys/filio.h>
26 #endif
27 #include <sys/ioctl.h>
28 #include <unistd.h>
30 #include "windows.h"
31 #include "comm.h"
32 #include "heap.h"
33 #include "options.h"
34 #include "stddebug.h"
35 #include "debug.h"
36 #include "handle32.h"
38 #ifndef TIOCINQ
39 #define TIOCINQ FIONREAD
40 #endif
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];
51 void COMM_Init(void)
53 int x;
54 char option[10], temp[256], *btemp;
55 struct stat st;
57 for (x=0; x!=MAX_PORTS; x++) {
58 strcpy(option,"COMx");
59 option[3] = '1' + x;
60 option[4] = '\0';
62 PROFILE_GetWineIniString( "serialports", option, "*",
63 temp, sizeof(temp) );
64 if (!strcmp(temp, "*") || *temp == '\0')
65 COM[x].devicename = NULL;
66 else {
67 btemp = strchr(temp,',');
68 if (btemp != NULL) {
69 *btemp++ = '\0';
70 COM[x].baudrate = atoi(btemp);
71 } else {
72 COM[x].baudrate = -1;
74 stat(temp, &st);
75 if (!S_ISCHR(st.st_mode))
76 fprintf(stderr,"comm: can't use `%s' as %s !\n", temp, option);
77 else
78 if ((COM[x].devicename = malloc(strlen(temp)+1)) == NULL)
79 fprintf(stderr,"comm: can't malloc for device info!\n");
80 else {
81 COM[x].fd = 0;
82 strcpy(COM[x].devicename, temp);
84 dprintf_comm(stddeb,
85 "Comm_Init: %s = %s\n", option, COM[x].devicename);
88 strcpy(option, "LPTx");
89 option[3] = '1' + x;
90 option[4] = '\0';
92 PROFILE_GetWineIniString( "parallelports", option, "*",
93 temp, sizeof(temp) );
94 if (!strcmp(temp, "*") || *temp == '\0')
95 LPT[x].devicename = NULL;
96 else {
97 stat(temp, &st);
98 if (!S_ISCHR(st.st_mode))
99 fprintf(stderr,"comm: can't use `%s' as %s !\n", temp, option);
100 else
101 if ((LPT[x].devicename = malloc(strlen(temp)+1)) == NULL)
102 fprintf(stderr,"comm: can't malloc for device info!\n");
103 else {
104 LPT[x].fd = 0;
105 strcpy(LPT[x].devicename, temp);
107 dprintf_comm(stddeb,
108 "Comm_Init: %s = %s\n", option, LPT[x].devicename);
115 struct DosDeviceStruct *GetDeviceStruct(int fd)
117 int x;
119 for (x=0; x!=MAX_PORTS; x++) {
120 if (COM[x].fd == fd)
121 return &COM[x];
122 if (LPT[x].fd == fd)
123 return &LPT[x];
126 return NULL;
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);
139 int WinError(void)
141 dprintf_comm(stddeb, "WinError: errno = %d\n", errno);
142 switch (errno) {
143 default:
144 return CE_IOE;
148 /**************************************************************************
149 * BuildCommDCB (USER.213)
151 BOOL16 BuildCommDCB16(LPCSTR device, LPDCB16 lpdcb)
153 /* "COM1:9600,n,8,1" */
154 /* 012345 */
155 int port;
156 char *ptr, temp[256];
158 dprintf_comm(stddeb,
159 "BuildCommDCB: (%s), ptr %p\n", device, lpdcb);
160 commerror = 0;
162 if (!lstrncmpi32A(device,"COM",3)) {
163 port = device[3] - '0';
166 if (port-- == 0) {
167 fprintf(stderr, "comm: BUG ! COM0 can't exists!.\n");
168 commerror = IE_BADID;
171 if (!ValidCOMPort(port)) {
172 commerror = IE_BADID;
173 return -1;
176 if (!COM[port].fd) {
177 OpenComm(device, 0, 0);
179 lpdcb->Id = COM[port].fd;
181 if (!*(device+4))
182 return 0;
184 if (*(device+4) != ':')
185 return -1;
187 strcpy(temp,device+5);
188 ptr = strtok(temp, ", ");
190 if (COM[port].baudrate > 0)
191 lpdcb->BaudRate = COM[port].baudrate;
192 else
193 lpdcb->BaudRate = atoi(ptr);
194 dprintf_comm(stddeb,"BuildCommDCB: baudrate (%d)\n", lpdcb->BaudRate);
196 ptr = strtok(NULL, ", ");
197 if (islower(*ptr))
198 *ptr = toupper(*ptr);
200 dprintf_comm(stddeb,"BuildCommDCB: parity (%c)\n", *ptr);
201 lpdcb->fParity = 1;
202 switch (*ptr) {
203 case 'N':
204 lpdcb->Parity = NOPARITY;
205 lpdcb->fParity = 0;
206 break;
207 case 'E':
208 lpdcb->Parity = EVENPARITY;
209 break;
210 case 'M':
211 lpdcb->Parity = MARKPARITY;
212 break;
213 case 'O':
214 lpdcb->Parity = ODDPARITY;
215 break;
216 default:
217 fprintf(stderr,"comm: unknown parity `%c'!\n", *ptr);
218 return -1;
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);
227 switch (*ptr) {
228 case '1':
229 lpdcb->StopBits = ONESTOPBIT;
230 break;
231 case '2':
232 lpdcb->StopBits = TWOSTOPBITS;
233 break;
234 default:
235 fprintf(stderr,"comm: unknown # of stopbits `%c'!\n", *ptr);
236 return -1;
240 return 0;
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) {
254 int port;
255 char *ptr,*temp;
257 dprintf_comm(stddeb,"BuildCommDCBAndTimeouts32A(%s,%p,%p)\n",device,lpdcb,lptimeouts);
258 commerror = 0;
260 if (!lstrncmpi32A(device,"COM",3)) {
261 port=device[3]-'0';
262 if (port--==0) {
263 fprintf(stderr,"comm:BUG! COM0 can't exists!.\n");
264 return FALSE;
266 if (!ValidCOMPort(port))
267 return FALSE;
268 if (*(device+4)!=':')
269 return FALSE;
270 temp=(LPSTR)(device+5);
271 } else
272 temp=(LPSTR)device;
273 lpdcb->DCBlength = sizeof(DCB32);
274 if (strchr(temp,',')) { /* old style */
275 DCB16 dcb16;
276 BOOL16 ret;
277 char last=temp[strlen(temp)-1];
279 ret=BuildCommDCB16(device,&dcb16);
280 if (!ret)
281 return FALSE;
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;
289 if (last == 'x') {
290 lpdcb->fInX = TRUE;
291 lpdcb->fOutX = TRUE;
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') {
297 lpdcb->fInX = FALSE;
298 lpdcb->fOutX = FALSE;
299 lpdcb->fOutxCtsFlow = TRUE;
300 lpdcb->fOutxDsrFlow = TRUE;
301 lpdcb->fDtrControl = DTR_CONTROL_HANDSHAKE;
302 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
303 } else {
304 lpdcb->fInX = FALSE;
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;
319 return TRUE;
321 ptr=strtok(temp," ");
322 while (ptr) {
323 DWORD flag,x;
325 flag=0;
326 if (!strncmp("baud=",ptr,5)) {
327 if (!sscanf(ptr+5,"%ld",&x))
328 fprintf(stderr,"BuildCommDCB32A:Couldn't parse %s\n",ptr);
329 lpdcb->BaudRate = x;
330 flag=1;
332 if (!strncmp("stop=",ptr,5)) {
333 if (!sscanf(ptr+5,"%ld",&x))
334 fprintf(stderr,"BuildCommDCB32A:Couldn't parse %s\n",ptr);
335 lpdcb->StopBits = x;
336 flag=1;
338 if (!strncmp("data=",ptr,5)) {
339 if (!sscanf(ptr+5,"%ld",&x))
340 fprintf(stderr,"BuildCommDCB32A:Couldn't parse %s\n",ptr);
341 lpdcb->ByteSize = x;
342 flag=1;
344 if (!strncmp("parity=",ptr,7)) {
345 lpdcb->fParity = TRUE;
346 switch (ptr[8]) {
347 case 'N':case 'n':
348 lpdcb->fParity = FALSE;
349 lpdcb->Parity = NOPARITY;
350 break;
351 case 'E':case 'e':
352 lpdcb->Parity = EVENPARITY;
353 break;
354 case 'O':case 'o':
355 lpdcb->Parity = ODDPARITY;
356 break;
357 case 'M':case 'm':
358 lpdcb->Parity = MARKPARITY;
359 break;
361 flag=1;
363 if (!flag)
364 fprintf(stderr,"BuildCommDCB32A: Unhandled specifier '%s', please report.\n",ptr);
365 ptr=strtok(NULL," ");
367 if (lpdcb->BaudRate==110)
368 lpdcb->StopBits = 2;
369 return TRUE;
372 /**************************************************************************
373 * BuildCommDCBAndTimeoutsW (KERNEL32.16)
375 BOOL32 BuildCommDCBAndTimeouts32W(
376 LPCWSTR devid,LPDCB32 lpdcb,LPCOMMTIMEOUTS lptimeouts
378 LPSTR devidA;
379 BOOL32 ret;
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 );
385 return ret;
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)
400 int port,fd;
402 dprintf_comm(stddeb,
403 "OpenComm: %s, %d, %d\n", device, cbInQueue, cbOutQueue);
404 commerror = 0;
406 if (!lstrncmpi32A(device,"COM",3)) {
407 port = device[3] - '0';
409 if (port-- == 0) {
410 fprintf(stderr, "comm: BUG ! COM0 doesn't exist !\n");
411 commerror = IE_BADID;
414 dprintf_comm(stddeb,
415 "OpenComm: %s = %s\n", device, COM[port].devicename);
417 if (!ValidCOMPort(port)) {
418 commerror = IE_BADID;
419 return -1;
421 if (COM[port].fd) {
422 return COM[port].fd;
425 fd = open(COM[port].devicename, O_RDWR | O_NONBLOCK);
426 if (fd == -1) {
427 commerror = WinError();
428 return -1;
429 } else {
430 COM[port].fd = fd;
431 return fd;
434 else
435 if (!lstrncmpi32A(device,"LPT",3)) {
436 port = device[3] - '0';
438 if (!ValidLPTPort(port)) {
439 commerror = IE_BADID;
440 return -1;
442 if (LPT[port].fd) {
443 commerror = IE_OPEN;
444 return -1;
447 fd = open(LPT[port].devicename, O_RDWR | O_NONBLOCK, 0);
448 if (fd == -1) {
449 commerror = WinError();
450 return -1;
451 } else {
452 LPT[port].fd = fd;
453 return fd;
456 return 0;
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;
469 return -1;
472 ptr->fd = 0; /* [RER] Really, -1 would be a better value */
474 if (close(fd) == -1) {
475 commerror = WinError();
476 return -1;
477 } else {
478 commerror = 0;
479 return 0;
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;
493 return -1;
496 ptr->suspended = 1;
497 commerror = 0;
498 return 0;
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;
512 return FALSE;
515 ptr->suspended = 1;
516 commerror = 0;
517 return TRUE;
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;
530 return -1;
533 ptr->suspended = 0;
534 commerror = 0;
535 return 0;
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;
548 return FALSE;
551 ptr->suspended = 0;
552 commerror = 0;
553 return TRUE;
556 /*****************************************************************************
557 * EscapeCommFunction (USER.214)
559 LONG EscapeCommFunction16(UINT16 fd,UINT16 nFunction)
561 int max;
562 struct termios port;
564 dprintf_comm(stddeb,"EscapeCommFunction fd: %d, function: %d\n", fd, nFunction);
565 if (tcgetattr(fd,&port) == -1) {
566 commerror=WinError();
567 return -1;
570 switch (nFunction) {
571 case RESETDEV:
572 break;
574 case GETMAXCOM:
575 for (max = MAX_PORTS;!COM[max].devicename;max--)
577 return max;
578 break;
580 case GETMAXLPT:
581 for (max = MAX_PORTS;!LPT[max].devicename;max--)
583 return 0x80 + max;
584 break;
586 #ifdef TIOCM_DTR
587 case CLRDTR:
588 port.c_cflag &= TIOCM_DTR;
589 break;
590 #endif
592 #ifdef TIOCM_RTS
593 case CLRRTS:
594 port.c_cflag &= TIOCM_RTS;
595 break;
596 #endif
598 #ifdef CRTSCTS
599 case SETDTR:
600 port.c_cflag |= CRTSCTS;
601 break;
603 case SETRTS:
604 port.c_cflag |= CRTSCTS;
605 break;
606 #endif
608 case SETXOFF:
609 port.c_iflag |= IXOFF;
610 break;
612 case SETXON:
613 port.c_iflag |= IXON;
614 break;
616 default:
617 fprintf(stderr,
618 "EscapeCommFunction fd: %d, unknown function: %d\n",
619 fd, nFunction);
620 break;
623 if (tcsetattr(fd, TCSADRAIN, &port) == -1) {
624 commerror = WinError();
625 return -1;
626 } else {
627 commerror = 0;
628 return 0;
632 /*****************************************************************************
633 * EscapeCommFunction (KERNEL32.214)
635 BOOL32 EscapeCommFunction32(INT32 fd,UINT32 nFunction)
637 struct termios port;
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();
643 return FALSE;
645 if ((ptr = GetDeviceStruct(fd)) == NULL) {
646 commerror = IE_BADID;
647 return FALSE;
650 switch (nFunction) {
651 case RESETDEV:
652 break;
654 #ifdef TIOCM_DTR
655 case CLRDTR:
656 port.c_cflag &= TIOCM_DTR;
657 break;
658 #endif
660 #ifdef TIOCM_RTS
661 case CLRRTS:
662 port.c_cflag &= TIOCM_RTS;
663 break;
664 #endif
666 #ifdef CRTSCTS
667 case SETDTR:
668 port.c_cflag |= CRTSCTS;
669 break;
671 case SETRTS:
672 port.c_cflag |= CRTSCTS;
673 break;
674 #endif
676 case SETXOFF:
677 port.c_iflag |= IXOFF;
678 break;
680 case SETXON:
681 port.c_iflag |= IXON;
682 break;
683 case SETBREAK:
684 ptr->suspended = 1;
685 break;
686 case CLRBREAK:
687 ptr->suspended = 0;
688 break;
689 default:
690 fprintf(stderr,
691 "EscapeCommFunction32 fd: %d, unknown function: %d\n",
692 fd, nFunction);
693 break;
696 if (tcsetattr(fd, TCSADRAIN, &port) == -1) {
697 commerror = WinError();
698 return FALSE;
699 } else {
700 commerror = 0;
701 return TRUE;
705 /*****************************************************************************
706 * FlushComm (USER.215)
708 INT16 FlushComm(INT16 fd,INT16 fnQueue)
710 int queue;
712 dprintf_comm(stddeb,"FlushComm fd: %d, queue: %d\n", fd, fnQueue);
713 switch (fnQueue) {
714 case 0: queue = TCOFLUSH;
715 break;
716 case 1: queue = TCIFLUSH;
717 break;
718 default:fprintf(stderr,
719 "FlushComm fd: %d, UNKNOWN queue: %d\n",
720 fd, fnQueue);
721 return -1;
723 if (tcflush(fd, fnQueue)) {
724 commerror = WinError();
725 return -1;
726 } else {
727 commerror = 0;
728 return 0;
732 /*****************************************************************************
733 * GetCommError (USER.203)
735 INT16 GetCommError(INT16 fd,LPCOMSTAT lpStat)
737 int temperror;
738 unsigned long cnt;
739 int rc;
741 if (lpStat) {
742 lpStat->status = 0;
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;
752 dprintf_comm(stddeb,
753 "GetCommError: fd %d, error %d, lpStat %d %d %d\n",
754 fd, commerror,
755 lpStat->status, lpStat->cbInQue, lpStat->cbOutQue);
757 else
758 dprintf_comm(stddeb,
759 "GetCommError: fd %d, error %d, lpStat NULL\n",
760 fd, commerror);
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;
767 commerror = 0;
768 return(temperror);
771 /*****************************************************************************
772 * ClearCommError (KERNEL32.21)
774 BOOL32 ClearCommError(INT32 fd,LPDWORD errors,LPCOMSTAT lpStat)
776 int temperror;
778 dprintf_comm(stddeb,
779 "ClearCommError: fd %d (current error %d)\n", fd, commerror);
780 temperror = commerror;
781 commerror = 0;
782 return TRUE;
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)
800 int events = 0;
802 dprintf_comm(stddeb,
803 "GetCommEventMask: fd %d, mask %d\n", fd, fnEvtClear);
806 * Determine if any characters are available
808 if (fnEvtClear & EV_RXCHAR)
810 int rc;
811 unsigned long cnt;
813 rc = ioctl(fd, TIOCINQ, &cnt);
814 if (cnt) events |= EV_RXCHAR;
816 dprintf_comm(stddeb,
817 "GetCommEventMask: rxchar %ld\n", cnt);
821 * There are other events that need to be checked for
823 /* TODO */
825 dprintf_comm(stddeb,
826 "GetCommEventMask: return events %d\n", events);
827 return events;
830 * [RER] The following was gibberish
832 #if 0
833 tempmask = eventmask;
834 eventmask &= ~fnEvtClear;
835 return eventmask;
836 #endif
839 /*****************************************************************************
840 * GetCommMask (KERNEL32.156)
842 BOOL32 GetCommMask(INT32 fd,LPDWORD evtmask)
844 dprintf_comm(stddeb,
845 "GetCommMask: fd %d, mask %p\n", fd, evtmask);
846 *evtmask = eventmask;
847 return TRUE;
850 /*****************************************************************************
851 * SetCommMask (KERNEL32.451)
853 BOOL32 SetCommMask(INT32 fd,DWORD evtmask)
855 dprintf_comm(stddeb,
856 "SetCommMask: fd %d, mask %lx\n", fd, evtmask);
857 eventmask = evtmask;
858 return TRUE;
861 /*****************************************************************************
862 * SetCommState16 (USER.201)
864 INT16 SetCommState16(LPDCB16 lpdcb)
866 struct termios port;
867 struct DosDeviceStruct *ptr;
869 dprintf_comm(stddeb,
870 "SetCommState: fd %d, ptr %p\n", lpdcb->Id, lpdcb);
871 if (tcgetattr(lpdcb->Id, &port) == -1) {
872 commerror = WinError();
873 return -1;
876 port.c_cc[VMIN] = 0;
877 port.c_cc[VTIME] = 1;
879 #ifdef IMAXBEL
880 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR|IMAXBEL);
881 #else
882 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR);
883 #endif
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;
896 return -1;
898 if (ptr->baudrate > 0)
899 lpdcb->BaudRate = ptr->baudrate;
900 dprintf_comm(stddeb,"SetCommState: baudrate %d\n",lpdcb->BaudRate);
901 #ifdef CBAUD
902 port.c_cflag &= ~CBAUD;
903 switch (lpdcb->BaudRate) {
904 case 110:
905 case CBR_110:
906 port.c_cflag |= B110;
907 break;
908 case 300:
909 case CBR_300:
910 port.c_cflag |= B300;
911 break;
912 case 600:
913 case CBR_600:
914 port.c_cflag |= B600;
915 break;
916 case 1200:
917 case CBR_1200:
918 port.c_cflag |= B1200;
919 break;
920 case 2400:
921 case CBR_2400:
922 port.c_cflag |= B2400;
923 break;
924 case 4800:
925 case CBR_4800:
926 port.c_cflag |= B4800;
927 break;
928 case 9600:
929 case CBR_9600:
930 port.c_cflag |= B9600;
931 break;
932 case 19200:
933 case CBR_19200:
934 port.c_cflag |= B19200;
935 break;
936 case 38400:
937 case CBR_38400:
938 port.c_cflag |= B38400;
939 break;
940 default:
941 commerror = IE_BAUDRATE;
942 return -1;
944 #elif !defined(__EMX__)
945 switch (lpdcb->BaudRate) {
946 case 110:
947 case CBR_110:
948 port.c_ospeed = B110;
949 break;
950 case 300:
951 case CBR_300:
952 port.c_ospeed = B300;
953 break;
954 case 600:
955 case CBR_600:
956 port.c_ospeed = B600;
957 break;
958 case 1200:
959 case CBR_1200:
960 port.c_ospeed = B1200;
961 break;
962 case 2400:
963 case CBR_2400:
964 port.c_ospeed = B2400;
965 break;
966 case 4800:
967 case CBR_4800:
968 port.c_ospeed = B4800;
969 break;
970 case 9600:
971 case CBR_9600:
972 port.c_ospeed = B9600;
973 break;
974 case 19200:
975 case CBR_19200:
976 port.c_ospeed = B19200;
977 break;
978 case 38400:
979 case CBR_38400:
980 port.c_ospeed = B38400;
981 break;
982 default:
983 commerror = IE_BAUDRATE;
984 return -1;
986 port.c_ispeed = port.c_ospeed;
987 #endif
988 dprintf_comm(stddeb,"SetCommState: bytesize %d\n",lpdcb->ByteSize);
989 port.c_cflag &= ~CSIZE;
990 switch (lpdcb->ByteSize) {
991 case 5:
992 port.c_cflag |= CS5;
993 break;
994 case 6:
995 port.c_cflag |= CS6;
996 break;
997 case 7:
998 port.c_cflag |= CS7;
999 break;
1000 case 8:
1001 port.c_cflag |= CS8;
1002 break;
1003 default:
1004 commerror = IE_BYTESIZE;
1005 return -1;
1008 dprintf_comm(stddeb,"SetCommState: parity %d\n",lpdcb->Parity);
1009 port.c_cflag &= ~(PARENB | PARODD);
1010 if (lpdcb->fParity)
1011 switch (lpdcb->Parity) {
1012 case NOPARITY:
1013 port.c_iflag &= ~INPCK;
1014 break;
1015 case ODDPARITY:
1016 port.c_cflag |= (PARENB | PARODD);
1017 port.c_iflag |= INPCK;
1018 break;
1019 case EVENPARITY:
1020 port.c_cflag |= PARENB;
1021 port.c_iflag |= INPCK;
1022 break;
1023 default:
1024 commerror = IE_BYTESIZE;
1025 return -1;
1029 dprintf_comm(stddeb,"SetCommState: stopbits %d\n",lpdcb->StopBits);
1030 switch (lpdcb->StopBits) {
1031 case ONESTOPBIT:
1032 port.c_cflag &= ~CSTOPB;
1033 break;
1034 case TWOSTOPBITS:
1035 port.c_cflag |= CSTOPB;
1036 break;
1037 default:
1038 commerror = IE_BYTESIZE;
1039 return -1;
1041 #ifdef CRTSCTS
1043 if (lpdcb->fDtrflow || lpdcb->fRtsflow || lpdcb->fOutxCtsFlow)
1044 port.c_cflag |= CRTSCTS;
1046 if (lpdcb->fDtrDisable)
1047 port.c_cflag &= ~CRTSCTS;
1048 #endif
1049 if (lpdcb->fInX)
1050 port.c_iflag |= IXON;
1051 if (lpdcb->fOutX)
1052 port.c_iflag |= IXOFF;
1054 if (tcsetattr(lpdcb->Id, TCSADRAIN, &port) == -1) {
1055 commerror = WinError();
1056 return -1;
1057 } else {
1058 commerror = 0;
1059 return 0;
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();
1074 return FALSE;
1077 port.c_cc[VMIN] = 0;
1078 port.c_cc[VTIME] = 1;
1080 #ifdef IMAXBEL
1081 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR|IMAXBEL);
1082 #else
1083 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR);
1084 #endif
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;
1097 return FALSE;
1099 if (ptr->baudrate > 0)
1100 lpdcb->BaudRate = ptr->baudrate;
1101 dprintf_comm(stddeb,"SetCommState: baudrate %ld\n",lpdcb->BaudRate);
1102 #ifdef CBAUD
1103 port.c_cflag &= ~CBAUD;
1104 switch (lpdcb->BaudRate) {
1105 case 110:
1106 case CBR_110:
1107 port.c_cflag |= B110;
1108 break;
1109 case 300:
1110 case CBR_300:
1111 port.c_cflag |= B300;
1112 break;
1113 case 600:
1114 case CBR_600:
1115 port.c_cflag |= B600;
1116 break;
1117 case 1200:
1118 case CBR_1200:
1119 port.c_cflag |= B1200;
1120 break;
1121 case 2400:
1122 case CBR_2400:
1123 port.c_cflag |= B2400;
1124 break;
1125 case 4800:
1126 case CBR_4800:
1127 port.c_cflag |= B4800;
1128 break;
1129 case 9600:
1130 case CBR_9600:
1131 port.c_cflag |= B9600;
1132 break;
1133 case 19200:
1134 case CBR_19200:
1135 port.c_cflag |= B19200;
1136 break;
1137 case 38400:
1138 case CBR_38400:
1139 port.c_cflag |= B38400;
1140 break;
1141 default:
1142 commerror = IE_BAUDRATE;
1143 return FALSE;
1145 #elif !defined(__EMX__)
1146 switch (lpdcb->BaudRate) {
1147 case 110:
1148 case CBR_110:
1149 port.c_ospeed = B110;
1150 break;
1151 case 300:
1152 case CBR_300:
1153 port.c_ospeed = B300;
1154 break;
1155 case 600:
1156 case CBR_600:
1157 port.c_ospeed = B600;
1158 break;
1159 case 1200:
1160 case CBR_1200:
1161 port.c_ospeed = B1200;
1162 break;
1163 case 2400:
1164 case CBR_2400:
1165 port.c_ospeed = B2400;
1166 break;
1167 case 4800:
1168 case CBR_4800:
1169 port.c_ospeed = B4800;
1170 break;
1171 case 9600:
1172 case CBR_9600:
1173 port.c_ospeed = B9600;
1174 break;
1175 case 19200:
1176 case CBR_19200:
1177 port.c_ospeed = B19200;
1178 break;
1179 case 38400:
1180 case CBR_38400:
1181 port.c_ospeed = B38400;
1182 break;
1183 default:
1184 commerror = IE_BAUDRATE;
1185 return FALSE;
1187 port.c_ispeed = port.c_ospeed;
1188 #endif
1189 dprintf_comm(stddeb,"SetCommState: bytesize %d\n",lpdcb->ByteSize);
1190 port.c_cflag &= ~CSIZE;
1191 switch (lpdcb->ByteSize) {
1192 case 5:
1193 port.c_cflag |= CS5;
1194 break;
1195 case 6:
1196 port.c_cflag |= CS6;
1197 break;
1198 case 7:
1199 port.c_cflag |= CS7;
1200 break;
1201 case 8:
1202 port.c_cflag |= CS8;
1203 break;
1204 default:
1205 commerror = IE_BYTESIZE;
1206 return FALSE;
1209 dprintf_comm(stddeb,"SetCommState: parity %d\n",lpdcb->Parity);
1210 port.c_cflag &= ~(PARENB | PARODD);
1211 if (lpdcb->fParity)
1212 switch (lpdcb->Parity) {
1213 case NOPARITY:
1214 port.c_iflag &= ~INPCK;
1215 break;
1216 case ODDPARITY:
1217 port.c_cflag |= (PARENB | PARODD);
1218 port.c_iflag |= INPCK;
1219 break;
1220 case EVENPARITY:
1221 port.c_cflag |= PARENB;
1222 port.c_iflag |= INPCK;
1223 break;
1224 default:
1225 commerror = IE_BYTESIZE;
1226 return FALSE;
1230 dprintf_comm(stddeb,"SetCommState: stopbits %d\n",lpdcb->StopBits);
1231 switch (lpdcb->StopBits) {
1232 case ONESTOPBIT:
1233 port.c_cflag &= ~CSTOPB;
1234 break;
1235 case TWOSTOPBITS:
1236 port.c_cflag |= CSTOPB;
1237 break;
1238 default:
1239 commerror = IE_BYTESIZE;
1240 return FALSE;
1242 #ifdef CRTSCTS
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;
1251 #endif
1252 if (lpdcb->fInX)
1253 port.c_iflag |= IXON;
1254 if (lpdcb->fOutX)
1255 port.c_iflag |= IXOFF;
1257 if (tcsetattr(fd,TCSADRAIN,&port)==-1) {
1258 commerror = WinError();
1259 return FALSE;
1260 } else {
1261 commerror = 0;
1262 return TRUE;
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();
1277 return -1;
1279 lpdcb->Id = fd;
1280 #ifndef __EMX__
1281 #ifdef CBAUD
1282 switch (port.c_cflag & CBAUD) {
1283 #else
1284 switch (port.c_ospeed) {
1285 #endif
1286 case B110:
1287 lpdcb->BaudRate = 110;
1288 break;
1289 case B300:
1290 lpdcb->BaudRate = 300;
1291 break;
1292 case B600:
1293 lpdcb->BaudRate = 600;
1294 break;
1295 case B1200:
1296 lpdcb->BaudRate = 1200;
1297 break;
1298 case B2400:
1299 lpdcb->BaudRate = 2400;
1300 break;
1301 case B4800:
1302 lpdcb->BaudRate = 4800;
1303 break;
1304 case B9600:
1305 lpdcb->BaudRate = 9600;
1306 break;
1307 case B19200:
1308 lpdcb->BaudRate = 19200;
1309 break;
1310 case B38400:
1311 lpdcb->BaudRate = 38400;
1312 break;
1314 #endif
1315 switch (port.c_cflag & CSIZE) {
1316 case CS5:
1317 lpdcb->ByteSize = 5;
1318 break;
1319 case CS6:
1320 lpdcb->ByteSize = 6;
1321 break;
1322 case CS7:
1323 lpdcb->ByteSize = 7;
1324 break;
1325 case CS8:
1326 lpdcb->ByteSize = 8;
1327 break;
1330 switch (port.c_cflag & ~(PARENB | PARODD)) {
1331 case 0:
1332 lpdcb->fParity = NOPARITY;
1333 break;
1334 case PARENB:
1335 lpdcb->fParity = EVENPARITY;
1336 break;
1337 case (PARENB | PARODD):
1338 lpdcb->fParity = ODDPARITY;
1339 break;
1342 if (port.c_cflag & CSTOPB)
1343 lpdcb->StopBits = TWOSTOPBITS;
1344 else
1345 lpdcb->StopBits = ONESTOPBIT;
1347 lpdcb->RlsTimeout = 50;
1348 lpdcb->CtsTimeout = 50;
1349 lpdcb->DsrTimeout = 50;
1350 lpdcb->fNull = 0;
1351 lpdcb->fChEvt = 0;
1352 lpdcb->fBinary = 1;
1353 lpdcb->fDtrDisable = 0;
1355 #ifdef CRTSCTS
1357 if (port.c_cflag & CRTSCTS) {
1358 lpdcb->fDtrflow = 1;
1359 lpdcb->fRtsflow = 1;
1360 lpdcb->fOutxCtsFlow = 1;
1361 lpdcb->fOutxDsrFlow = 1;
1362 } else
1363 #endif
1364 lpdcb->fDtrDisable = 1;
1366 if (port.c_iflag & IXON)
1367 lpdcb->fInX = 1;
1368 else
1369 lpdcb->fInX = 0;
1371 if (port.c_iflag & IXOFF)
1372 lpdcb->fOutX = 1;
1373 else
1374 lpdcb->fOutX = 0;
1376 lpdcb->XonChar =
1377 lpdcb->XoffChar =
1379 lpdcb->XonLim = 10;
1380 lpdcb->XoffLim = 10;
1382 commerror = 0;
1383 return 0;
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();
1397 return FALSE;
1399 #ifndef __EMX__
1400 #ifdef CBAUD
1401 switch (port.c_cflag & CBAUD) {
1402 #else
1403 switch (port.c_ospeed) {
1404 #endif
1405 case B110:
1406 lpdcb->BaudRate = 110;
1407 break;
1408 case B300:
1409 lpdcb->BaudRate = 300;
1410 break;
1411 case B600:
1412 lpdcb->BaudRate = 600;
1413 break;
1414 case B1200:
1415 lpdcb->BaudRate = 1200;
1416 break;
1417 case B2400:
1418 lpdcb->BaudRate = 2400;
1419 break;
1420 case B4800:
1421 lpdcb->BaudRate = 4800;
1422 break;
1423 case B9600:
1424 lpdcb->BaudRate = 9600;
1425 break;
1426 case B19200:
1427 lpdcb->BaudRate = 19200;
1428 break;
1429 case B38400:
1430 lpdcb->BaudRate = 38400;
1431 break;
1433 #endif
1434 switch (port.c_cflag & CSIZE) {
1435 case CS5:
1436 lpdcb->ByteSize = 5;
1437 break;
1438 case CS6:
1439 lpdcb->ByteSize = 6;
1440 break;
1441 case CS7:
1442 lpdcb->ByteSize = 7;
1443 break;
1444 case CS8:
1445 lpdcb->ByteSize = 8;
1446 break;
1449 switch (port.c_cflag & ~(PARENB | PARODD)) {
1450 case 0:
1451 lpdcb->fParity = NOPARITY;
1452 break;
1453 case PARENB:
1454 lpdcb->fParity = EVENPARITY;
1455 break;
1456 case (PARENB | PARODD):
1457 lpdcb->fParity = ODDPARITY;
1458 break;
1461 if (port.c_cflag & CSTOPB)
1462 lpdcb->StopBits = TWOSTOPBITS;
1463 else
1464 lpdcb->StopBits = ONESTOPBIT;
1466 lpdcb->fNull = 0;
1467 lpdcb->fBinary = 1;
1469 #ifdef CRTSCTS
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;
1476 } else
1477 #endif
1479 lpdcb->fDtrControl = DTR_CONTROL_DISABLE;
1480 lpdcb->fRtsControl = RTS_CONTROL_DISABLE;
1482 if (port.c_iflag & IXON)
1483 lpdcb->fInX = 1;
1484 else
1485 lpdcb->fInX = 0;
1487 if (port.c_iflag & IXOFF)
1488 lpdcb->fOutX = 1;
1489 else
1490 lpdcb->fOutX = 0;
1492 lpdcb->XonChar =
1493 lpdcb->XoffChar =
1495 lpdcb->XonLim = 10;
1496 lpdcb->XoffLim = 10;
1498 commerror = 0;
1499 return TRUE;
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;
1513 return -1;
1516 if (ptr->suspended) {
1517 commerror = IE_HARDWARE;
1518 return -1;
1521 if (write(fd, (void *) &chTransmit, 1) == -1) {
1522 commerror = WinError();
1523 return -1;
1524 } else {
1525 commerror = 0;
1526 return 0;
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;
1540 return FALSE;
1543 if (ptr->suspended) {
1544 commerror = IE_HARDWARE;
1545 return FALSE;
1547 if (write(fd, (void *) &chTransmit, 1) == -1) {
1548 commerror = WinError();
1549 return FALSE;
1550 } else {
1551 commerror = 0;
1552 return TRUE;
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;
1566 return -1;
1569 if (ptr->suspended) {
1570 commerror = IE_HARDWARE;
1571 return -1;
1574 ptr->unget = 1;
1575 ptr->unget_byte = chUnget;
1576 commerror = 0;
1577 return 0;
1580 /*****************************************************************************
1581 * ReadComm (USER.204)
1583 INT16 ReadComm(INT16 fd,LPSTR lpvBuf,INT16 cbRead)
1585 int status, length;
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;
1592 return -1;
1595 if (ptr->suspended) {
1596 commerror = IE_HARDWARE;
1597 return -1;
1600 if (ptr->unget) {
1601 *lpvBuf = ptr->unget_byte;
1602 lpvBuf++;
1603 ptr->unget = 0;
1605 length = 1;
1606 } else
1607 length = 0;
1609 status = read(fd, (void *) lpvBuf, cbRead);
1611 if (status == -1) {
1612 if (errno != EAGAIN) {
1613 commerror = WinError();
1614 return -1 - length;
1615 } else {
1616 commerror = 0;
1617 return length;
1619 } else {
1620 commerror = 0;
1621 return length + status;
1625 /*****************************************************************************
1626 * WriteComm (USER.205)
1628 INT16 WriteComm(INT16 fd, LPSTR lpvBuf, INT16 cbWrite)
1630 int x, length;
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;
1637 return -1;
1640 if (ptr->suspended) {
1641 commerror = IE_HARDWARE;
1642 return -1;
1645 for (x=0; x != cbWrite ; x++)
1646 dprintf_comm(stddeb,"%c", *(lpvBuf + x) );
1648 length = write(fd, (void *) lpvBuf, cbWrite);
1650 if (length == -1) {
1651 commerror = WinError();
1652 return -1;
1653 } else {
1654 commerror = 0;
1655 return length;
1660 /*****************************************************************************
1661 * GetCommTimeouts (KERNEL32.160)
1663 BOOL32 GetCommTimeouts(INT32 fd,LPCOMMTIMEOUTS lptimeouts) {
1664 fprintf(stderr,"GetCommTimeouts(%x,%p), empty stub.\n",
1665 fd,lptimeouts
1667 return TRUE;
1670 /*****************************************************************************
1671 * SetCommTimeouts (KERNEL32.453)
1673 BOOL32 SetCommTimeouts(INT32 fd,LPCOMMTIMEOUTS lptimeouts) {
1674 fprintf(stderr,"SetCommTimeouts(%x,%p), empty stub.\n",
1675 fd,lptimeouts
1677 return TRUE;
1680 /***********************************************************************
1681 * EnableCommNotification (USER.246)
1683 BOOL16 EnableCommNotification( INT16 fd, HWND16 hwnd, INT16 cbWriteNotify,
1684 INT16 cbOutQueue )
1686 fprintf(stderr, "EnableCommNotification(%d, %x, %d, %d), empty stub.\n", fd, hwnd, cbWriteNotify, cbOutQueue);
1687 return TRUE;