Release 971221
[wine/multimedia.git] / misc / comm.c
blob08f967537589b8962d4cbb3834dfaf9fc429fab1
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.
15 * August 12, 1997. Take a bash at SetCommEventMask - Lawson Whitney
16 * <lawson_whitney@juno.com>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <termios.h>
22 #include <fcntl.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <ctype.h>
26 #include <sys/stat.h>
27 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__svr4__)
28 #include <sys/filio.h>
29 #endif
30 #include <sys/ioctl.h>
31 #include <unistd.h>
33 #include "windows.h"
34 #include "comm.h"
35 #include "heap.h"
36 #include "options.h"
37 #include "stddebug.h"
38 #include "debug.h"
39 #include "handle32.h"
41 #ifndef TIOCINQ
42 #define TIOCINQ FIONREAD
43 #endif
44 #define msr 35 /* offset in unknown structure commMask */
46 * [RER] These are globals are wrong. They should be in DosDeviceStruct
47 * on a per port basis.
49 int commerror = 0, eventmask = 0;
51 struct DosDeviceStruct COM[MAX_PORTS];
52 struct DosDeviceStruct LPT[MAX_PORTS];
53 LPCVOID *unknown[MAX_PORTS];
55 void COMM_Init(void)
57 int x;
58 char option[10], temp[256], *btemp;
59 struct stat st;
61 for (x=0; x!=MAX_PORTS; x++) {
62 strcpy(option,"COMx");
63 option[3] = '1' + x;
64 option[4] = '\0';
66 PROFILE_GetWineIniString( "serialports", option, "*",
67 temp, sizeof(temp) );
68 if (!strcmp(temp, "*") || *temp == '\0')
69 COM[x].devicename = NULL;
70 else {
71 btemp = strchr(temp,',');
72 if (btemp != NULL) {
73 *btemp++ = '\0';
74 COM[x].baudrate = atoi(btemp);
75 } else {
76 COM[x].baudrate = -1;
78 stat(temp, &st);
79 if (!S_ISCHR(st.st_mode))
80 fprintf(stderr,"comm: can't use `%s' as %s !\n", temp, option);
81 else
82 if ((COM[x].devicename = malloc(strlen(temp)+1)) == NULL)
83 fprintf(stderr,"comm: can't malloc for device info!\n");
84 else {
85 COM[x].fd = 0;
86 strcpy(COM[x].devicename, temp);
88 dprintf_comm(stddeb,
89 "Comm_Init: %s = %s\n", option, COM[x].devicename);
92 strcpy(option, "LPTx");
93 option[3] = '1' + x;
94 option[4] = '\0';
96 PROFILE_GetWineIniString( "parallelports", option, "*",
97 temp, sizeof(temp) );
98 if (!strcmp(temp, "*") || *temp == '\0')
99 LPT[x].devicename = NULL;
100 else {
101 stat(temp, &st);
102 if (!S_ISCHR(st.st_mode))
103 fprintf(stderr,"comm: can't use `%s' as %s !\n", temp, option);
104 else
105 if ((LPT[x].devicename = malloc(strlen(temp)+1)) == NULL)
106 fprintf(stderr,"comm: can't malloc for device info!\n");
107 else {
108 LPT[x].fd = 0;
109 strcpy(LPT[x].devicename, temp);
111 dprintf_comm(stddeb,
112 "Comm_Init: %s = %s\n", option, LPT[x].devicename);
119 struct DosDeviceStruct *GetDeviceStruct(int fd)
121 int x;
123 for (x=0; x!=MAX_PORTS; x++) {
124 if (COM[x].fd == fd)
125 return &COM[x];
126 if (LPT[x].fd == fd)
127 return &LPT[x];
130 return NULL;
133 int GetCommPort(int fd)
135 int x;
137 for (x=0; x<MAX_PORTS; x++) {
138 if (COM[x].fd == fd)
139 return x;
142 return -1;
145 int ValidCOMPort(int x)
147 return(x < MAX_PORTS ? (int) COM[x].devicename : 0);
150 int ValidLPTPort(int x)
152 return(x < MAX_PORTS ? (int) LPT[x].devicename : 0);
155 int WinError(void)
157 dprintf_comm(stddeb, "WinError: errno = %d\n", errno);
158 switch (errno) {
159 default:
160 return CE_IOE;
164 /**************************************************************************
165 * BuildCommDCB (USER.213)
167 BOOL16 WINAPI BuildCommDCB16(LPCSTR device, LPDCB16 lpdcb)
169 /* "COM1:9600,n,8,1" */
170 /* 012345 */
171 int port;
172 char *ptr, temp[256];
174 dprintf_comm(stddeb,
175 "BuildCommDCB: (%s), ptr %p\n", device, lpdcb);
176 commerror = 0;
178 if (!lstrncmpi32A(device,"COM",3)) {
179 port = device[3] - '0';
182 if (port-- == 0) {
183 fprintf(stderr, "comm: BUG ! COM0 can't exists!.\n");
184 commerror = IE_BADID;
187 if (!ValidCOMPort(port)) {
188 commerror = IE_BADID;
189 return -1;
192 memset(lpdcb, 0, sizeof(DCB16)); /* initialize */
194 if (!COM[port].fd) {
195 OpenComm(device, 0, 0);
197 lpdcb->Id = COM[port].fd;
199 if (!*(device+4))
200 return 0;
202 if (*(device+4) != ':')
203 return -1;
205 strcpy(temp,device+5);
206 ptr = strtok(temp, ", ");
208 if (COM[port].baudrate > 0)
209 lpdcb->BaudRate = COM[port].baudrate;
210 else
211 lpdcb->BaudRate = atoi(ptr);
212 dprintf_comm(stddeb,"BuildCommDCB: baudrate (%d)\n", lpdcb->BaudRate);
214 ptr = strtok(NULL, ", ");
215 if (islower(*ptr))
216 *ptr = toupper(*ptr);
218 dprintf_comm(stddeb,"BuildCommDCB: parity (%c)\n", *ptr);
219 lpdcb->fParity = 1;
220 switch (*ptr) {
221 case 'N':
222 lpdcb->Parity = NOPARITY;
223 lpdcb->fParity = 0;
224 break;
225 case 'E':
226 lpdcb->Parity = EVENPARITY;
227 break;
228 case 'M':
229 lpdcb->Parity = MARKPARITY;
230 break;
231 case 'O':
232 lpdcb->Parity = ODDPARITY;
233 break;
234 default:
235 fprintf(stderr,"comm: unknown parity `%c'!\n", *ptr);
236 return -1;
239 ptr = strtok(NULL, ", ");
240 dprintf_comm(stddeb, "BuildCommDCB: charsize (%c)\n", *ptr);
241 lpdcb->ByteSize = *ptr - '0';
243 ptr = strtok(NULL, ", ");
244 dprintf_comm(stddeb, "BuildCommDCB: stopbits (%c)\n", *ptr);
245 switch (*ptr) {
246 case '1':
247 lpdcb->StopBits = ONESTOPBIT;
248 break;
249 case '2':
250 lpdcb->StopBits = TWOSTOPBITS;
251 break;
252 default:
253 fprintf(stderr,"comm: unknown # of stopbits `%c'!\n", *ptr);
254 return -1;
258 return 0;
261 /**************************************************************************
262 * BuildCommDCBA (KERNEL32.14)
264 BOOL32 WINAPI BuildCommDCB32A(LPCSTR device,LPDCB32 lpdcb)
266 return BuildCommDCBAndTimeouts32A(device,lpdcb,NULL);
269 /**************************************************************************
270 * BuildCommDCBAndTimeoutsA (KERNEL32.15)
272 BOOL32 WINAPI BuildCommDCBAndTimeouts32A(LPCSTR device, LPDCB32 lpdcb,
273 LPCOMMTIMEOUTS lptimeouts)
275 int port;
276 char *ptr,*temp;
278 dprintf_comm(stddeb,"BuildCommDCBAndTimeouts32A(%s,%p,%p)\n",device,lpdcb,lptimeouts);
279 commerror = 0;
281 if (!lstrncmpi32A(device,"COM",3)) {
282 port=device[3]-'0';
283 if (port--==0) {
284 fprintf(stderr,"comm:BUG! COM0 can't exists!.\n");
285 return FALSE;
287 if (!ValidCOMPort(port))
288 return FALSE;
289 if (*(device+4)!=':')
290 return FALSE;
291 temp=(LPSTR)(device+5);
292 } else
293 temp=(LPSTR)device;
295 memset(lpdcb, 0, sizeof(DCB32)); /* initialize */
297 lpdcb->DCBlength = sizeof(DCB32);
298 if (strchr(temp,',')) { /* old style */
299 DCB16 dcb16;
300 BOOL16 ret;
301 char last=temp[strlen(temp)-1];
303 ret=BuildCommDCB16(device,&dcb16);
304 if (!ret)
305 return FALSE;
306 lpdcb->BaudRate = dcb16.BaudRate;
307 lpdcb->ByteSize = dcb16.ByteSize;
308 lpdcb->fBinary = dcb16.fBinary;
309 lpdcb->Parity = dcb16.Parity;
310 lpdcb->fParity = dcb16.fParity;
311 lpdcb->fNull = dcb16.fNull;
312 lpdcb->StopBits = dcb16.StopBits;
313 if (last == 'x') {
314 lpdcb->fInX = TRUE;
315 lpdcb->fOutX = TRUE;
316 lpdcb->fOutxCtsFlow = FALSE;
317 lpdcb->fOutxDsrFlow = FALSE;
318 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
319 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
320 } else if (last=='p') {
321 lpdcb->fInX = FALSE;
322 lpdcb->fOutX = FALSE;
323 lpdcb->fOutxCtsFlow = TRUE;
324 lpdcb->fOutxDsrFlow = TRUE;
325 lpdcb->fDtrControl = DTR_CONTROL_HANDSHAKE;
326 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
327 } else {
328 lpdcb->fInX = FALSE;
329 lpdcb->fOutX = FALSE;
330 lpdcb->fOutxCtsFlow = FALSE;
331 lpdcb->fOutxDsrFlow = FALSE;
332 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
333 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
335 lpdcb->XonChar = dcb16.XonChar;
336 lpdcb->XoffChar = dcb16.XoffChar;
337 lpdcb->ErrorChar= dcb16.PeChar;
338 lpdcb->fErrorChar= dcb16.fPeChar;
339 lpdcb->EofChar = dcb16.EofChar;
340 lpdcb->EvtChar = dcb16.EvtChar;
341 lpdcb->XonLim = dcb16.XonLim;
342 lpdcb->XoffLim = dcb16.XoffLim;
343 return TRUE;
345 ptr=strtok(temp," ");
346 while (ptr) {
347 DWORD flag,x;
349 flag=0;
350 if (!strncmp("baud=",ptr,5)) {
351 if (!sscanf(ptr+5,"%ld",&x))
352 fprintf(stderr,"BuildCommDCB32A:Couldn't parse %s\n",ptr);
353 lpdcb->BaudRate = x;
354 flag=1;
356 if (!strncmp("stop=",ptr,5)) {
357 if (!sscanf(ptr+5,"%ld",&x))
358 fprintf(stderr,"BuildCommDCB32A:Couldn't parse %s\n",ptr);
359 lpdcb->StopBits = x;
360 flag=1;
362 if (!strncmp("data=",ptr,5)) {
363 if (!sscanf(ptr+5,"%ld",&x))
364 fprintf(stderr,"BuildCommDCB32A:Couldn't parse %s\n",ptr);
365 lpdcb->ByteSize = x;
366 flag=1;
368 if (!strncmp("parity=",ptr,7)) {
369 lpdcb->fParity = TRUE;
370 switch (ptr[8]) {
371 case 'N':case 'n':
372 lpdcb->fParity = FALSE;
373 lpdcb->Parity = NOPARITY;
374 break;
375 case 'E':case 'e':
376 lpdcb->Parity = EVENPARITY;
377 break;
378 case 'O':case 'o':
379 lpdcb->Parity = ODDPARITY;
380 break;
381 case 'M':case 'm':
382 lpdcb->Parity = MARKPARITY;
383 break;
385 flag=1;
387 if (!flag)
388 fprintf(stderr,"BuildCommDCB32A: Unhandled specifier '%s', please report.\n",ptr);
389 ptr=strtok(NULL," ");
391 if (lpdcb->BaudRate==110)
392 lpdcb->StopBits = 2;
393 return TRUE;
396 /**************************************************************************
397 * BuildCommDCBAndTimeoutsW (KERNEL32.16)
399 BOOL32 WINAPI BuildCommDCBAndTimeouts32W( LPCWSTR devid, LPDCB32 lpdcb,
400 LPCOMMTIMEOUTS lptimeouts )
402 LPSTR devidA;
403 BOOL32 ret;
405 dprintf_comm(stddeb,"BuildCommDCBAndTimeouts32W(%p,%p,%p)\n",devid,lpdcb,lptimeouts);
406 devidA = HEAP_strdupWtoA( GetProcessHeap(), 0, devid );
407 ret=BuildCommDCBAndTimeouts32A(devidA,lpdcb,lptimeouts);
408 HeapFree( GetProcessHeap(), 0, devidA );
409 return ret;
412 /**************************************************************************
413 * BuildCommDCBW (KERNEL32.17)
415 BOOL32 WINAPI BuildCommDCB32W(LPCWSTR devid,LPDCB32 lpdcb)
417 return BuildCommDCBAndTimeouts32W(devid,lpdcb,NULL);
420 /*****************************************************************************
421 * OpenComm (USER.200)
423 INT16 WINAPI OpenComm(LPCSTR device,UINT16 cbInQueue,UINT16 cbOutQueue)
425 int port,fd;
427 dprintf_comm(stddeb,
428 "OpenComm: %s, %d, %d\n", device, cbInQueue, cbOutQueue);
429 commerror = 0;
431 if (!lstrncmpi32A(device,"COM",3)) {
432 port = device[3] - '0';
434 if (port-- == 0) {
435 fprintf(stderr, "comm: BUG ! COM0 doesn't exist !\n");
436 commerror = IE_BADID;
439 dprintf_comm(stddeb,
440 "OpenComm: %s = %s\n", device, COM[port].devicename);
442 if (!ValidCOMPort(port)) {
443 commerror = IE_BADID;
444 return -1;
446 if (COM[port].fd) {
447 return COM[port].fd;
450 fd = open(COM[port].devicename, O_RDWR | O_NONBLOCK);
451 if (fd == -1) {
452 commerror = WinError();
453 return -1;
454 } else {
455 unknown[port] = SEGPTR_ALLOC(40);
456 bzero(unknown[port],40);
457 COM[port].fd = fd;
458 return fd;
461 else
462 if (!lstrncmpi32A(device,"LPT",3)) {
463 port = device[3] - '0';
465 if (!ValidLPTPort(port)) {
466 commerror = IE_BADID;
467 return -1;
469 if (LPT[port].fd) {
470 commerror = IE_OPEN;
471 return -1;
474 fd = open(LPT[port].devicename, O_RDWR | O_NONBLOCK, 0);
475 if (fd == -1) {
476 commerror = WinError();
477 return -1;
478 } else {
479 LPT[port].fd = fd;
480 return fd;
483 return 0;
486 /*****************************************************************************
487 * CloseComm (USER.207)
489 INT16 WINAPI CloseComm(INT16 fd)
491 int port;
492 dprintf_comm(stddeb,"CloseComm: fd %d\n", fd);
493 if ((port = GetCommPort(fd)) !=-1) { /* [LW] */
494 SEGPTR_FREE(unknown[port]);
495 COM[port].fd = 0; /* my adaptation of RER's fix */
496 } else {
497 commerror = IE_BADID;
498 return -1;
501 if (close(fd) == -1) {
502 commerror = WinError();
503 return -1;
504 } else {
505 commerror = 0;
506 return 0;
510 /*****************************************************************************
511 * SetCommBreak (USER.210)
513 INT16 WINAPI SetCommBreak16(INT16 fd)
515 struct DosDeviceStruct *ptr;
517 dprintf_comm(stddeb,"SetCommBreak: fd: %d\n", fd);
518 if ((ptr = GetDeviceStruct(fd)) == NULL) {
519 commerror = IE_BADID;
520 return -1;
523 ptr->suspended = 1;
524 commerror = 0;
525 return 0;
528 /*****************************************************************************
529 * SetCommBreak (KERNEL32.449)
531 BOOL32 WINAPI SetCommBreak32(INT32 fd)
534 struct DosDeviceStruct *ptr;
536 dprintf_comm(stddeb,"SetCommBreak: fd: %d\n", fd);
537 if ((ptr = GetDeviceStruct(fd)) == NULL) {
538 commerror = IE_BADID;
539 return FALSE;
542 ptr->suspended = 1;
543 commerror = 0;
544 return TRUE;
547 /*****************************************************************************
548 * ClearCommBreak (USER.211)
550 INT16 WINAPI ClearCommBreak16(INT16 fd)
552 struct DosDeviceStruct *ptr;
554 dprintf_comm(stddeb,"ClearCommBreak: fd: %d\n", fd);
555 if ((ptr = GetDeviceStruct(fd)) == NULL) {
556 commerror = IE_BADID;
557 return -1;
560 ptr->suspended = 0;
561 commerror = 0;
562 return 0;
565 /*****************************************************************************
566 * ClearCommBreak (KERNEL32.20)
568 BOOL32 WINAPI ClearCommBreak32(INT32 fd)
570 struct DosDeviceStruct *ptr;
572 dprintf_comm(stddeb,"ClearCommBreak: fd: %d\n", fd);
573 if ((ptr = GetDeviceStruct(fd)) == NULL) {
574 commerror = IE_BADID;
575 return FALSE;
578 ptr->suspended = 0;
579 commerror = 0;
580 return TRUE;
583 /*****************************************************************************
584 * EscapeCommFunction (USER.214)
586 LONG WINAPI EscapeCommFunction16(UINT16 fd,UINT16 nFunction)
588 int max;
589 struct termios port;
591 dprintf_comm(stddeb,"EscapeCommFunction fd: %d, function: %d\n", fd, nFunction);
592 if (tcgetattr(fd,&port) == -1) {
593 commerror=WinError();
594 return -1;
597 switch (nFunction) {
598 case RESETDEV:
599 break;
601 case GETMAXCOM:
602 for (max = MAX_PORTS;!COM[max].devicename;max--)
604 return max;
605 break;
607 case GETMAXLPT:
608 for (max = MAX_PORTS;!LPT[max].devicename;max--)
610 return 0x80 + max;
611 break;
613 #ifdef TIOCM_DTR
614 case CLRDTR:
615 port.c_cflag &= TIOCM_DTR;
616 break;
617 #endif
619 #ifdef TIOCM_RTS
620 case CLRRTS:
621 port.c_cflag &= TIOCM_RTS;
622 break;
623 #endif
625 #ifdef CRTSCTS
626 case SETDTR:
627 port.c_cflag |= CRTSCTS;
628 break;
630 case SETRTS:
631 port.c_cflag |= CRTSCTS;
632 break;
633 #endif
635 case SETXOFF:
636 port.c_iflag |= IXOFF;
637 break;
639 case SETXON:
640 port.c_iflag |= IXON;
641 break;
643 default:
644 fprintf(stderr,
645 "EscapeCommFunction fd: %d, unknown function: %d\n",
646 fd, nFunction);
647 break;
650 if (tcsetattr(fd, TCSADRAIN, &port) == -1) {
651 commerror = WinError();
652 return -1;
653 } else {
654 commerror = 0;
655 return 0;
659 /*****************************************************************************
660 * EscapeCommFunction (KERNEL32.214)
662 BOOL32 WINAPI EscapeCommFunction32(INT32 fd,UINT32 nFunction)
664 struct termios port;
665 struct DosDeviceStruct *ptr;
667 dprintf_comm(stddeb,"EscapeCommFunction fd: %d, function: %d\n", fd, nFunction);
668 if (tcgetattr(fd,&port) == -1) {
669 commerror=WinError();
670 return FALSE;
672 if ((ptr = GetDeviceStruct(fd)) == NULL) {
673 commerror = IE_BADID;
674 return FALSE;
677 switch (nFunction) {
678 case RESETDEV:
679 break;
681 #ifdef TIOCM_DTR
682 case CLRDTR:
683 port.c_cflag &= TIOCM_DTR;
684 break;
685 #endif
687 #ifdef TIOCM_RTS
688 case CLRRTS:
689 port.c_cflag &= TIOCM_RTS;
690 break;
691 #endif
693 #ifdef CRTSCTS
694 case SETDTR:
695 port.c_cflag |= CRTSCTS;
696 break;
698 case SETRTS:
699 port.c_cflag |= CRTSCTS;
700 break;
701 #endif
703 case SETXOFF:
704 port.c_iflag |= IXOFF;
705 break;
707 case SETXON:
708 port.c_iflag |= IXON;
709 break;
710 case SETBREAK:
711 ptr->suspended = 1;
712 break;
713 case CLRBREAK:
714 ptr->suspended = 0;
715 break;
716 default:
717 fprintf(stderr,
718 "EscapeCommFunction32 fd: %d, unknown function: %d\n",
719 fd, nFunction);
720 break;
723 if (tcsetattr(fd, TCSADRAIN, &port) == -1) {
724 commerror = WinError();
725 return FALSE;
726 } else {
727 commerror = 0;
728 return TRUE;
732 /*****************************************************************************
733 * FlushComm (USER.215)
735 INT16 WINAPI FlushComm(INT16 fd,INT16 fnQueue)
737 int queue;
739 dprintf_comm(stddeb,"FlushComm fd: %d, queue: %d\n", fd, fnQueue);
740 switch (fnQueue) {
741 case 0: queue = TCOFLUSH;
742 break;
743 case 1: queue = TCIFLUSH;
744 break;
745 default:fprintf(stderr,
746 "FlushComm fd: %d, UNKNOWN queue: %d\n",
747 fd, fnQueue);
748 return -1;
750 if (tcflush(fd, queue)) {
751 commerror = WinError();
752 return -1;
753 } else {
754 commerror = 0;
755 return 0;
759 /********************************************************************
760 * PurgeComm (KERNEL32.557)
762 BOOL32 WINAPI PurgeComm( HANDLE32 hFile, DWORD flags)
764 dprintf_comm(stdnimp, "PurgeComm(%08x %08lx) unimplemented stub\n",
765 hFile, flags);
766 return 0;
769 /********************************************************************
770 * GetCommError (USER.203)
772 INT16 WINAPI GetCommError(INT16 fd,LPCOMSTAT lpStat)
774 int temperror;
775 unsigned long cnt;
776 int rc;
778 if (lpStat) {
779 lpStat->status = 0;
781 rc = ioctl(fd, TIOCOUTQ, &cnt);
782 if (rc) fprintf(stderr, "Error !\n");
783 lpStat->cbOutQue = cnt;
785 rc = ioctl(fd, TIOCINQ, &cnt);
786 if (rc) fprintf(stderr, "Error !\n");
787 lpStat->cbInQue = cnt;
789 dprintf_comm(stddeb,
790 "GetCommError: fd %d, error %d, lpStat %d %d %d\n",
791 fd, commerror,
792 lpStat->status, lpStat->cbInQue, lpStat->cbOutQue);
794 else
795 dprintf_comm(stddeb,
796 "GetCommError: fd %d, error %d, lpStat NULL\n",
797 fd, commerror);
800 * [RER] I have no idea what the following is trying to accomplish.
801 * [RER] It is certainly not what the reference manual suggests.
803 temperror = commerror;
804 commerror = 0;
805 return(temperror);
808 /*****************************************************************************
809 * ClearCommError (KERNEL32.21)
811 BOOL32 WINAPI ClearCommError(INT32 fd,LPDWORD errors,LPCOMSTAT lpStat)
813 int temperror;
815 dprintf_comm(stddeb,
816 "ClearCommError: fd %d (current error %d)\n", fd, commerror);
817 temperror = commerror;
818 commerror = 0;
819 return TRUE;
822 /*****************************************************************************
823 * SetCommEventMask (USER.208)
825 SEGPTR WINAPI SetCommEventMask(INT16 fd,UINT16 fuEvtMask)
827 unsigned char *stol;
828 int act;
829 int repid;
830 unsigned int mstat;
831 dprintf_comm(stddeb,"SetCommEventMask:fd %d,mask %d\n",fd,fuEvtMask);
832 eventmask |= fuEvtMask;
833 if ((act = GetCommPort(fd)) == -1) {
834 dprintf_comm(stddeb," fd %d not comm port\n",act);
835 return NULL;}
836 stol = unknown[act];
837 stol += msr;
838 repid = ioctl(fd,TIOCMGET,&mstat);
839 dprintf_comm(stddeb,
840 " ioctl %d, msr %x at %p %p\n",repid,mstat,stol,unknown[act]);
841 if ((mstat&TIOCM_CAR)) {*stol |= 0x80;}
842 else {*stol &=0x7f;}
843 dprintf_comm(stddeb," modem dcd construct %x\n",*stol);
844 return SEGPTR_GET(unknown[act]);
847 /*****************************************************************************
848 * GetCommEventMask (USER.209)
850 UINT16 WINAPI GetCommEventMask(INT16 fd,UINT16 fnEvtClear)
852 int events = 0;
854 dprintf_comm(stddeb,
855 "GetCommEventMask: fd %d, mask %d\n", fd, fnEvtClear);
858 * Determine if any characters are available
860 if (fnEvtClear & EV_RXCHAR)
862 int rc;
863 unsigned long cnt;
865 rc = ioctl(fd, TIOCINQ, &cnt);
866 if (cnt) events |= EV_RXCHAR;
868 dprintf_comm(stddeb,
869 "GetCommEventMask: rxchar %ld\n", cnt);
873 * There are other events that need to be checked for
875 /* TODO */
877 dprintf_comm(stddeb,
878 "GetCommEventMask: return events %d\n", events);
879 return events;
882 * [RER] The following was gibberish
884 #if 0
885 tempmask = eventmask;
886 eventmask &= ~fnEvtClear;
887 return eventmask;
888 #endif
891 /*****************************************************************************
892 * SetupComm (KERNEL32.676)
894 BOOL32 WINAPI SetupComm( HANDLE32 hFile, DWORD insize, DWORD outsize)
896 dprintf_comm(stdnimp, "SetupComm: insize %ld outsize %ld unimplemented stub\n", insize, outsize);
897 return FALSE;
900 /*****************************************************************************
901 * GetCommMask (KERNEL32.156)
903 BOOL32 WINAPI GetCommMask(INT32 fd,LPDWORD evtmask)
905 dprintf_comm(stddeb,
906 "GetCommMask: fd %d, mask %p\n", fd, evtmask);
907 *evtmask = eventmask;
908 return TRUE;
911 /*****************************************************************************
912 * SetCommMask (KERNEL32.451)
914 BOOL32 WINAPI SetCommMask(INT32 fd,DWORD evtmask)
916 dprintf_comm(stddeb,
917 "SetCommMask: fd %d, mask %lx\n", fd, evtmask);
918 eventmask = evtmask;
919 return TRUE;
922 /*****************************************************************************
923 * SetCommState16 (USER.201)
925 INT16 WINAPI SetCommState16(LPDCB16 lpdcb)
927 struct termios port;
928 struct DosDeviceStruct *ptr;
930 dprintf_comm(stddeb,
931 "SetCommState16: fd %d, ptr %p\n", lpdcb->Id, lpdcb);
932 if (tcgetattr(lpdcb->Id, &port) == -1) {
933 commerror = WinError();
934 return -1;
937 port.c_cc[VMIN] = 0;
938 port.c_cc[VTIME] = 1;
940 #ifdef IMAXBEL
941 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR|IMAXBEL);
942 #else
943 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR);
944 #endif
945 port.c_iflag |= (IGNBRK);
947 port.c_oflag &= ~(OPOST);
949 port.c_cflag &= ~(HUPCL);
950 port.c_cflag |= CLOCAL | CREAD;
952 port.c_lflag &= ~(ICANON|ECHO|ISIG);
953 port.c_lflag |= NOFLSH;
955 if ((ptr = GetDeviceStruct(lpdcb->Id)) == NULL) {
956 commerror = IE_BADID;
957 return -1;
959 if (ptr->baudrate > 0)
960 lpdcb->BaudRate = ptr->baudrate;
961 dprintf_comm(stddeb,"SetCommState: baudrate %d\n",lpdcb->BaudRate);
962 #ifdef CBAUD
963 port.c_cflag &= ~CBAUD;
964 switch (lpdcb->BaudRate) {
965 case 110:
966 case CBR_110:
967 port.c_cflag |= B110;
968 break;
969 case 300:
970 case CBR_300:
971 port.c_cflag |= B300;
972 break;
973 case 600:
974 case CBR_600:
975 port.c_cflag |= B600;
976 break;
977 case 1200:
978 case CBR_1200:
979 port.c_cflag |= B1200;
980 break;
981 case 2400:
982 case CBR_2400:
983 port.c_cflag |= B2400;
984 break;
985 case 4800:
986 case CBR_4800:
987 port.c_cflag |= B4800;
988 break;
989 case 9600:
990 case CBR_9600:
991 port.c_cflag |= B9600;
992 break;
993 case 19200:
994 case CBR_19200:
995 port.c_cflag |= B19200;
996 break;
997 case 38400:
998 case CBR_38400:
999 port.c_cflag |= B38400;
1000 break;
1001 case 57600:
1002 port.c_cflag |= B57600;
1003 break;
1004 case 57601:
1005 port.c_cflag |= B115200;
1006 break;
1007 default:
1008 commerror = IE_BAUDRATE;
1009 return -1;
1011 #elif !defined(__EMX__)
1012 switch (lpdcb->BaudRate) {
1013 case 110:
1014 case CBR_110:
1015 port.c_ospeed = B110;
1016 break;
1017 case 300:
1018 case CBR_300:
1019 port.c_ospeed = B300;
1020 break;
1021 case 600:
1022 case CBR_600:
1023 port.c_ospeed = B600;
1024 break;
1025 case 1200:
1026 case CBR_1200:
1027 port.c_ospeed = B1200;
1028 break;
1029 case 2400:
1030 case CBR_2400:
1031 port.c_ospeed = B2400;
1032 break;
1033 case 4800:
1034 case CBR_4800:
1035 port.c_ospeed = B4800;
1036 break;
1037 case 9600:
1038 case CBR_9600:
1039 port.c_ospeed = B9600;
1040 break;
1041 case 19200:
1042 case CBR_19200:
1043 port.c_ospeed = B19200;
1044 break;
1045 case 38400:
1046 case CBR_38400:
1047 port.c_ospeed = B38400;
1048 break;
1049 default:
1050 commerror = IE_BAUDRATE;
1051 return -1;
1053 port.c_ispeed = port.c_ospeed;
1054 #endif
1055 dprintf_comm(stddeb,"SetCommState: bytesize %d\n",lpdcb->ByteSize);
1056 port.c_cflag &= ~CSIZE;
1057 switch (lpdcb->ByteSize) {
1058 case 5:
1059 port.c_cflag |= CS5;
1060 break;
1061 case 6:
1062 port.c_cflag |= CS6;
1063 break;
1064 case 7:
1065 port.c_cflag |= CS7;
1066 break;
1067 case 8:
1068 port.c_cflag |= CS8;
1069 break;
1070 default:
1071 commerror = IE_BYTESIZE;
1072 return -1;
1075 dprintf_comm(stddeb,"SetCommState: parity %d\n",lpdcb->Parity);
1076 port.c_cflag &= ~(PARENB | PARODD);
1077 if (lpdcb->fParity)
1078 switch (lpdcb->Parity) {
1079 case NOPARITY:
1080 port.c_iflag &= ~INPCK;
1081 break;
1082 case ODDPARITY:
1083 port.c_cflag |= (PARENB | PARODD);
1084 port.c_iflag |= INPCK;
1085 break;
1086 case EVENPARITY:
1087 port.c_cflag |= PARENB;
1088 port.c_iflag |= INPCK;
1089 break;
1090 default:
1091 commerror = IE_BYTESIZE;
1092 return -1;
1096 dprintf_comm(stddeb,"SetCommState: stopbits %d\n",lpdcb->StopBits);
1098 switch (lpdcb->StopBits) {
1099 case ONESTOPBIT:
1100 port.c_cflag &= ~CSTOPB;
1101 break;
1102 case TWOSTOPBITS:
1103 port.c_cflag |= CSTOPB;
1104 break;
1105 default:
1106 commerror = IE_BYTESIZE;
1107 return -1;
1109 #ifdef CRTSCTS
1111 if (lpdcb->fDtrflow || lpdcb->fRtsflow || lpdcb->fOutxCtsFlow)
1112 port.c_cflag |= CRTSCTS;
1114 if (lpdcb->fDtrDisable)
1115 port.c_cflag &= ~CRTSCTS;
1116 #endif
1117 if (lpdcb->fInX)
1118 port.c_iflag |= IXON;
1119 else
1120 port.c_iflag &= ~IXON;
1121 if (lpdcb->fOutX)
1122 port.c_iflag |= IXOFF;
1123 else
1124 port.c_iflag &= ~IXOFF;
1126 if (tcsetattr(lpdcb->Id, TCSADRAIN, &port) == -1) {
1127 commerror = WinError();
1128 return FALSE;
1129 } else {
1130 commerror = 0;
1131 return 0;
1135 /*****************************************************************************
1136 * SetCommState32 (KERNEL32.452)
1138 BOOL32 WINAPI SetCommState32(INT32 fd,LPDCB32 lpdcb)
1140 struct termios port;
1141 struct DosDeviceStruct *ptr;
1143 dprintf_comm(stddeb,"SetCommState32: fd %d, ptr %p\n",fd,lpdcb);
1144 if (tcgetattr(fd,&port) == -1) {
1145 commerror = WinError();
1146 return FALSE;
1149 port.c_cc[VMIN] = 0;
1150 port.c_cc[VTIME] = 1;
1152 #ifdef IMAXBEL
1153 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR|IMAXBEL);
1154 #else
1155 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR);
1156 #endif
1157 port.c_iflag |= (IGNBRK);
1159 port.c_oflag &= ~(OPOST);
1161 port.c_cflag &= ~(HUPCL);
1162 port.c_cflag |= CLOCAL | CREAD;
1164 port.c_lflag &= ~(ICANON|ECHO|ISIG);
1165 port.c_lflag |= NOFLSH;
1167 if ((ptr = GetDeviceStruct(fd)) == NULL) {
1168 commerror = IE_BADID;
1169 return FALSE;
1171 if (ptr->baudrate > 0)
1172 lpdcb->BaudRate = ptr->baudrate;
1173 dprintf_comm(stddeb,"SetCommState: baudrate %ld\n",lpdcb->BaudRate);
1174 #ifdef CBAUD
1175 port.c_cflag &= ~CBAUD;
1176 switch (lpdcb->BaudRate) {
1177 case 110:
1178 case CBR_110:
1179 port.c_cflag |= B110;
1180 break;
1181 case 300:
1182 case CBR_300:
1183 port.c_cflag |= B300;
1184 break;
1185 case 600:
1186 case CBR_600:
1187 port.c_cflag |= B600;
1188 break;
1189 case 1200:
1190 case CBR_1200:
1191 port.c_cflag |= B1200;
1192 break;
1193 case 2400:
1194 case CBR_2400:
1195 port.c_cflag |= B2400;
1196 break;
1197 case 4800:
1198 case CBR_4800:
1199 port.c_cflag |= B4800;
1200 break;
1201 case 9600:
1202 case CBR_9600:
1203 port.c_cflag |= B9600;
1204 break;
1205 case 19200:
1206 case CBR_19200:
1207 port.c_cflag |= B19200;
1208 break;
1209 case 38400:
1210 case CBR_38400:
1211 port.c_cflag |= B38400;
1212 break;
1213 default:
1214 commerror = IE_BAUDRATE;
1215 return FALSE;
1217 #elif !defined(__EMX__)
1218 switch (lpdcb->BaudRate) {
1219 case 110:
1220 case CBR_110:
1221 port.c_ospeed = B110;
1222 break;
1223 case 300:
1224 case CBR_300:
1225 port.c_ospeed = B300;
1226 break;
1227 case 600:
1228 case CBR_600:
1229 port.c_ospeed = B600;
1230 break;
1231 case 1200:
1232 case CBR_1200:
1233 port.c_ospeed = B1200;
1234 break;
1235 case 2400:
1236 case CBR_2400:
1237 port.c_ospeed = B2400;
1238 break;
1239 case 4800:
1240 case CBR_4800:
1241 port.c_ospeed = B4800;
1242 break;
1243 case 9600:
1244 case CBR_9600:
1245 port.c_ospeed = B9600;
1246 break;
1247 case 19200:
1248 case CBR_19200:
1249 port.c_ospeed = B19200;
1250 break;
1251 case 38400:
1252 case CBR_38400:
1253 port.c_ospeed = B38400;
1254 break;
1255 default:
1256 commerror = IE_BAUDRATE;
1257 return FALSE;
1259 port.c_ispeed = port.c_ospeed;
1260 #endif
1261 dprintf_comm(stddeb,"SetCommState: bytesize %d\n",lpdcb->ByteSize);
1262 port.c_cflag &= ~CSIZE;
1263 switch (lpdcb->ByteSize) {
1264 case 5:
1265 port.c_cflag |= CS5;
1266 break;
1267 case 6:
1268 port.c_cflag |= CS6;
1269 break;
1270 case 7:
1271 port.c_cflag |= CS7;
1272 break;
1273 case 8:
1274 port.c_cflag |= CS8;
1275 break;
1276 default:
1277 commerror = IE_BYTESIZE;
1278 return FALSE;
1281 dprintf_comm(stddeb,"SetCommState: parity %d\n",lpdcb->Parity);
1282 port.c_cflag &= ~(PARENB | PARODD);
1283 if (lpdcb->fParity)
1284 switch (lpdcb->Parity) {
1285 case NOPARITY:
1286 port.c_iflag &= ~INPCK;
1287 break;
1288 case ODDPARITY:
1289 port.c_cflag |= (PARENB | PARODD);
1290 port.c_iflag |= INPCK;
1291 break;
1292 case EVENPARITY:
1293 port.c_cflag |= PARENB;
1294 port.c_iflag |= INPCK;
1295 break;
1296 default:
1297 commerror = IE_BYTESIZE;
1298 return FALSE;
1302 dprintf_comm(stddeb,"SetCommState: stopbits %d\n",lpdcb->StopBits);
1303 switch (lpdcb->StopBits) {
1304 case ONESTOPBIT:
1305 port.c_cflag &= ~CSTOPB;
1306 break;
1307 case TWOSTOPBITS:
1308 port.c_cflag |= CSTOPB;
1309 break;
1310 default:
1311 commerror = IE_BYTESIZE;
1312 return FALSE;
1314 #ifdef CRTSCTS
1315 if ( lpdcb->fOutxCtsFlow ||
1316 lpdcb->fDtrControl == DTR_CONTROL_ENABLE||
1317 lpdcb->fRtsControl == RTS_CONTROL_ENABLE
1319 port.c_cflag |= CRTSCTS;
1320 if (lpdcb->fDtrControl == DTR_CONTROL_DISABLE)
1321 port.c_cflag &= ~CRTSCTS;
1323 #endif
1324 if (lpdcb->fInX)
1325 port.c_iflag |= IXON;
1326 else
1327 port.c_iflag &= ~IXON;
1328 if (lpdcb->fOutX)
1329 port.c_iflag |= IXOFF;
1330 else
1331 port.c_iflag &= ~IXOFF;
1333 if (tcsetattr(fd,TCSADRAIN,&port)==-1) {
1334 commerror = WinError();
1335 return FALSE;
1336 } else {
1337 commerror = 0;
1338 return TRUE;
1343 /*****************************************************************************
1344 * GetCommState (USER.202)
1346 INT16 WINAPI GetCommState16(INT16 fd, LPDCB16 lpdcb)
1348 struct termios port;
1350 dprintf_comm(stddeb,"GetCommState16: fd %d, ptr %p\n", fd, lpdcb);
1351 if (tcgetattr(fd, &port) == -1) {
1352 commerror = WinError();
1353 return -1;
1355 lpdcb->Id = fd;
1356 #ifndef __EMX__
1357 #ifdef CBAUD
1358 switch (port.c_cflag & CBAUD) {
1359 #else
1360 switch (port.c_ospeed) {
1361 #endif
1362 case B110:
1363 lpdcb->BaudRate = 110;
1364 break;
1365 case B300:
1366 lpdcb->BaudRate = 300;
1367 break;
1368 case B600:
1369 lpdcb->BaudRate = 600;
1370 break;
1371 case B1200:
1372 lpdcb->BaudRate = 1200;
1373 break;
1374 case B2400:
1375 lpdcb->BaudRate = 2400;
1376 break;
1377 case B4800:
1378 lpdcb->BaudRate = 4800;
1379 break;
1380 case B9600:
1381 lpdcb->BaudRate = 9600;
1382 break;
1383 case B19200:
1384 lpdcb->BaudRate = 19200;
1385 break;
1386 case B38400:
1387 lpdcb->BaudRate = 38400;
1388 break;
1389 case B57600:
1390 lpdcb->BaudRate = 57600;
1391 break;
1392 case B115200:
1393 lpdcb->BaudRate = 57601;
1394 break;
1396 #endif
1397 switch (port.c_cflag & CSIZE) {
1398 case CS5:
1399 lpdcb->ByteSize = 5;
1400 break;
1401 case CS6:
1402 lpdcb->ByteSize = 6;
1403 break;
1404 case CS7:
1405 lpdcb->ByteSize = 7;
1406 break;
1407 case CS8:
1408 lpdcb->ByteSize = 8;
1409 break;
1412 switch (port.c_cflag & ~(PARENB | PARODD)) {
1413 case 0:
1414 lpdcb->fParity = NOPARITY;
1415 break;
1416 case PARENB:
1417 lpdcb->fParity = EVENPARITY;
1418 break;
1419 case (PARENB | PARODD):
1420 lpdcb->fParity = ODDPARITY;
1421 break;
1424 if (port.c_cflag & CSTOPB)
1425 lpdcb->StopBits = TWOSTOPBITS;
1426 else
1427 lpdcb->StopBits = ONESTOPBIT;
1429 lpdcb->RlsTimeout = 50;
1430 lpdcb->CtsTimeout = 50;
1431 lpdcb->DsrTimeout = 50;
1432 lpdcb->fNull = 0;
1433 lpdcb->fChEvt = 0;
1434 lpdcb->fBinary = 1;
1435 lpdcb->fDtrDisable = 0;
1437 #ifdef CRTSCTS
1439 if (port.c_cflag & CRTSCTS) {
1440 lpdcb->fDtrflow = 1;
1441 lpdcb->fRtsflow = 1;
1442 lpdcb->fOutxCtsFlow = 1;
1443 lpdcb->fOutxDsrFlow = 1;
1444 } else
1445 #endif
1446 lpdcb->fDtrDisable = 1;
1448 if (port.c_iflag & IXON)
1449 lpdcb->fInX = 1;
1450 else
1451 lpdcb->fInX = 0;
1453 if (port.c_iflag & IXOFF)
1454 lpdcb->fOutX = 1;
1455 else
1456 lpdcb->fOutX = 0;
1458 lpdcb->XonChar =
1459 lpdcb->XoffChar =
1461 lpdcb->XonLim = 10;
1462 lpdcb->XoffLim = 10;
1464 commerror = 0;
1465 return 0;
1468 /*****************************************************************************
1469 * GetCommState (KERNEL32.159)
1471 BOOL32 WINAPI GetCommState32(INT32 fd, LPDCB32 lpdcb)
1473 struct termios port;
1475 dprintf_comm(stddeb,"GetCommState32: fd %d, ptr %p\n", fd, lpdcb);
1476 if (GetDeviceStruct(fd) == NULL) return FALSE;
1477 if (tcgetattr(fd, &port) == -1) {
1478 commerror = WinError();
1479 return FALSE;
1481 #ifndef __EMX__
1482 #ifdef CBAUD
1483 switch (port.c_cflag & CBAUD) {
1484 #else
1485 switch (port.c_ospeed) {
1486 #endif
1487 case B110:
1488 lpdcb->BaudRate = 110;
1489 break;
1490 case B300:
1491 lpdcb->BaudRate = 300;
1492 break;
1493 case B600:
1494 lpdcb->BaudRate = 600;
1495 break;
1496 case B1200:
1497 lpdcb->BaudRate = 1200;
1498 break;
1499 case B2400:
1500 lpdcb->BaudRate = 2400;
1501 break;
1502 case B4800:
1503 lpdcb->BaudRate = 4800;
1504 break;
1505 case B9600:
1506 lpdcb->BaudRate = 9600;
1507 break;
1508 case B19200:
1509 lpdcb->BaudRate = 19200;
1510 break;
1511 case B38400:
1512 lpdcb->BaudRate = 38400;
1513 break;
1515 #endif
1516 switch (port.c_cflag & CSIZE) {
1517 case CS5:
1518 lpdcb->ByteSize = 5;
1519 break;
1520 case CS6:
1521 lpdcb->ByteSize = 6;
1522 break;
1523 case CS7:
1524 lpdcb->ByteSize = 7;
1525 break;
1526 case CS8:
1527 lpdcb->ByteSize = 8;
1528 break;
1531 switch (port.c_cflag & ~(PARENB | PARODD)) {
1532 case 0:
1533 lpdcb->fParity = NOPARITY;
1534 break;
1535 case PARENB:
1536 lpdcb->fParity = EVENPARITY;
1537 break;
1538 case (PARENB | PARODD):
1539 lpdcb->fParity = ODDPARITY;
1540 break;
1543 if (port.c_cflag & CSTOPB)
1544 lpdcb->StopBits = TWOSTOPBITS;
1545 else
1546 lpdcb->StopBits = ONESTOPBIT;
1548 lpdcb->fNull = 0;
1549 lpdcb->fBinary = 1;
1551 #ifdef CRTSCTS
1553 if (port.c_cflag & CRTSCTS) {
1554 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
1555 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
1556 lpdcb->fOutxCtsFlow = 1;
1557 lpdcb->fOutxDsrFlow = 1;
1558 } else
1559 #endif
1561 lpdcb->fDtrControl = DTR_CONTROL_DISABLE;
1562 lpdcb->fRtsControl = RTS_CONTROL_DISABLE;
1564 if (port.c_iflag & IXON)
1565 lpdcb->fInX = 1;
1566 else
1567 lpdcb->fInX = 0;
1569 if (port.c_iflag & IXOFF)
1570 lpdcb->fOutX = 1;
1571 else
1572 lpdcb->fOutX = 0;
1574 lpdcb->XonChar =
1575 lpdcb->XoffChar =
1577 lpdcb->XonLim = 10;
1578 lpdcb->XoffLim = 10;
1580 commerror = 0;
1581 return TRUE;
1584 /*****************************************************************************
1585 * TransmitCommChar (USER.206)
1587 INT16 WINAPI TransmitCommChar16(INT16 fd,CHAR chTransmit)
1589 struct DosDeviceStruct *ptr;
1591 dprintf_comm(stddeb,
1592 "TransmitCommChar: fd %d, data %d \n", fd, chTransmit);
1593 if ((ptr = GetDeviceStruct(fd)) == NULL) {
1594 commerror = IE_BADID;
1595 return -1;
1598 if (ptr->suspended) {
1599 commerror = IE_HARDWARE;
1600 return -1;
1603 if (write(fd, (void *) &chTransmit, 1) == -1) {
1604 commerror = WinError();
1605 return -1;
1606 } else {
1607 commerror = 0;
1608 return 0;
1612 /*****************************************************************************
1613 * TransmitCommChar (KERNEL32.535)
1615 BOOL32 WINAPI TransmitCommChar32(INT32 fd,CHAR chTransmit)
1617 struct DosDeviceStruct *ptr;
1619 dprintf_comm(stddeb,"TransmitCommChar32(%d,'%c')\n",fd,chTransmit);
1620 if ((ptr = GetDeviceStruct(fd)) == NULL) {
1621 commerror = IE_BADID;
1622 return FALSE;
1625 if (ptr->suspended) {
1626 commerror = IE_HARDWARE;
1627 return FALSE;
1629 if (write(fd, (void *) &chTransmit, 1) == -1) {
1630 commerror = WinError();
1631 return FALSE;
1632 } else {
1633 commerror = 0;
1634 return TRUE;
1638 /*****************************************************************************
1639 * UngetCommChar (USER.212)
1641 INT16 WINAPI UngetCommChar(INT16 fd,CHAR chUnget)
1643 struct DosDeviceStruct *ptr;
1645 dprintf_comm(stddeb,"UngetCommChar: fd %d (char %d)\n", fd, chUnget);
1646 if ((ptr = GetDeviceStruct(fd)) == NULL) {
1647 commerror = IE_BADID;
1648 return -1;
1651 if (ptr->suspended) {
1652 commerror = IE_HARDWARE;
1653 return -1;
1656 ptr->unget = 1;
1657 ptr->unget_byte = chUnget;
1658 commerror = 0;
1659 return 0;
1662 /*****************************************************************************
1663 * ReadComm (USER.204)
1665 INT16 WINAPI ReadComm(INT16 fd,LPSTR lpvBuf,INT16 cbRead)
1667 int status, x, length;
1668 struct DosDeviceStruct *ptr;
1670 dprintf_comm(stddeb,
1671 "ReadComm: fd %d, ptr %p, length %d\n", fd, lpvBuf, cbRead);
1672 if ((ptr = GetDeviceStruct(fd)) == NULL) {
1673 commerror = IE_BADID;
1674 return -1;
1677 if (ptr->suspended) {
1678 commerror = IE_HARDWARE;
1679 return -1;
1682 if (ptr->unget) {
1683 *lpvBuf = ptr->unget_byte;
1684 lpvBuf++;
1685 ptr->unget = 0;
1687 length = 1;
1688 } else
1689 length = 0;
1691 status = read(fd, (void *) lpvBuf, cbRead);
1693 if (status == -1) {
1694 if (errno != EAGAIN) {
1695 commerror = WinError();
1696 return -1 - length;
1697 } else {
1698 commerror = 0;
1699 return length;
1701 } else {
1702 for (x=0; x < length+status; x++)
1703 dprintf_comm(stddeb,"%c",*(lpvBuf+x));
1704 dprintf_comm(stddeb,"\nthus endeth\n");
1705 commerror = 0;
1706 return length + status;
1710 /*****************************************************************************
1711 * WriteComm (USER.205)
1713 INT16 WINAPI WriteComm(INT16 fd, LPSTR lpvBuf, INT16 cbWrite)
1715 int x, length;
1716 struct DosDeviceStruct *ptr;
1718 dprintf_comm(stddeb,"WriteComm: fd %d, ptr %p, length %d\n",
1719 fd, lpvBuf, cbWrite);
1720 if ((ptr = GetDeviceStruct(fd)) == NULL) {
1721 commerror = IE_BADID;
1722 return -1;
1725 if (ptr->suspended) {
1726 commerror = IE_HARDWARE;
1727 return -1;
1730 for (x=0; x != cbWrite ; x++)
1731 dprintf_comm(stddeb,"%c", *(lpvBuf + x) );
1732 dprintf_comm(stddeb,"\n");
1733 length = write(fd, (void *) lpvBuf, cbWrite);
1735 if (length == -1) {
1736 commerror = WinError();
1737 return -1;
1738 } else {
1739 commerror = 0;
1740 return length;
1745 /*****************************************************************************
1746 * GetCommTimeouts (KERNEL32.160)
1748 BOOL32 WINAPI GetCommTimeouts(INT32 fd,LPCOMMTIMEOUTS lptimeouts)
1750 fprintf(stderr,"GetCommTimeouts(%x,%p), empty stub.\n",
1751 fd,lptimeouts
1753 return TRUE;
1756 /*****************************************************************************
1757 * SetCommTimeouts (KERNEL32.453)
1759 BOOL32 WINAPI SetCommTimeouts(INT32 fd,LPCOMMTIMEOUTS lptimeouts) {
1760 fprintf(stderr,"SetCommTimeouts(%x,%p), empty stub.\n",
1761 fd,lptimeouts
1763 return TRUE;
1766 /***********************************************************************
1767 * EnableCommNotification (USER.246)
1769 BOOL16 WINAPI EnableCommNotification( INT16 fd, HWND16 hwnd,
1770 INT16 cbWriteNotify, INT16 cbOutQueue )
1772 fprintf(stderr, "EnableCommNotification(%d, %x, %d, %d), empty stub.\n", fd, hwnd, cbWriteNotify, cbOutQueue);
1773 return TRUE;