Release 980104
[wine/multimedia.git] / misc / comm.c
blob73681d94e91e2445fc9c3de2a63fc53ce63ce981
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"
40 #ifndef TIOCINQ
41 #define TIOCINQ FIONREAD
42 #endif
43 #define msr 35 /* offset in unknown structure commMask */
45 * [RER] These are globals are wrong. They should be in DosDeviceStruct
46 * on a per port basis.
48 int commerror = 0, eventmask = 0;
50 struct DosDeviceStruct COM[MAX_PORTS];
51 struct DosDeviceStruct LPT[MAX_PORTS];
52 LPCVOID *unknown[MAX_PORTS];
54 void COMM_Init(void)
56 int x;
57 char option[10], temp[256], *btemp;
58 struct stat st;
60 for (x=0; x!=MAX_PORTS; x++) {
61 strcpy(option,"COMx");
62 option[3] = '1' + x;
63 option[4] = '\0';
65 PROFILE_GetWineIniString( "serialports", option, "*",
66 temp, sizeof(temp) );
67 if (!strcmp(temp, "*") || *temp == '\0')
68 COM[x].devicename = NULL;
69 else {
70 btemp = strchr(temp,',');
71 if (btemp != NULL) {
72 *btemp++ = '\0';
73 COM[x].baudrate = atoi(btemp);
74 } else {
75 COM[x].baudrate = -1;
77 stat(temp, &st);
78 if (!S_ISCHR(st.st_mode))
79 fprintf(stderr,"comm: can't use `%s' as %s !\n", temp, option);
80 else
81 if ((COM[x].devicename = malloc(strlen(temp)+1)) == NULL)
82 fprintf(stderr,"comm: can't malloc for device info!\n");
83 else {
84 COM[x].fd = 0;
85 strcpy(COM[x].devicename, temp);
87 dprintf_comm(stddeb,
88 "Comm_Init: %s = %s\n", option, COM[x].devicename);
91 strcpy(option, "LPTx");
92 option[3] = '1' + x;
93 option[4] = '\0';
95 PROFILE_GetWineIniString( "parallelports", option, "*",
96 temp, sizeof(temp) );
97 if (!strcmp(temp, "*") || *temp == '\0')
98 LPT[x].devicename = NULL;
99 else {
100 stat(temp, &st);
101 if (!S_ISCHR(st.st_mode))
102 fprintf(stderr,"comm: can't use `%s' as %s !\n", temp, option);
103 else
104 if ((LPT[x].devicename = malloc(strlen(temp)+1)) == NULL)
105 fprintf(stderr,"comm: can't malloc for device info!\n");
106 else {
107 LPT[x].fd = 0;
108 strcpy(LPT[x].devicename, temp);
110 dprintf_comm(stddeb,
111 "Comm_Init: %s = %s\n", option, LPT[x].devicename);
118 struct DosDeviceStruct *GetDeviceStruct(int fd)
120 int x;
122 for (x=0; x!=MAX_PORTS; x++) {
123 if (COM[x].fd == fd)
124 return &COM[x];
125 if (LPT[x].fd == fd)
126 return &LPT[x];
129 return NULL;
132 int GetCommPort(int fd)
134 int x;
136 for (x=0; x<MAX_PORTS; x++) {
137 if (COM[x].fd == fd)
138 return x;
141 return -1;
144 int ValidCOMPort(int x)
146 return(x < MAX_PORTS ? (int) COM[x].devicename : 0);
149 int ValidLPTPort(int x)
151 return(x < MAX_PORTS ? (int) LPT[x].devicename : 0);
154 int WinError(void)
156 dprintf_comm(stddeb, "WinError: errno = %d\n", errno);
157 switch (errno) {
158 default:
159 return CE_IOE;
163 /**************************************************************************
164 * BuildCommDCB (USER.213)
166 BOOL16 WINAPI BuildCommDCB16(LPCSTR device, LPDCB16 lpdcb)
168 /* "COM1:9600,n,8,1" */
169 /* 012345 */
170 int port;
171 char *ptr, temp[256];
173 dprintf_comm(stddeb,
174 "BuildCommDCB: (%s), ptr %p\n", device, lpdcb);
175 commerror = 0;
177 if (!lstrncmpi32A(device,"COM",3)) {
178 port = device[3] - '0';
181 if (port-- == 0) {
182 fprintf(stderr, "comm: BUG ! COM0 can't exists!.\n");
183 commerror = IE_BADID;
186 if (!ValidCOMPort(port)) {
187 commerror = IE_BADID;
188 return -1;
191 memset(lpdcb, 0, sizeof(DCB16)); /* initialize */
193 if (!COM[port].fd) {
194 OpenComm(device, 0, 0);
196 lpdcb->Id = COM[port].fd;
198 if (!*(device+4))
199 return 0;
201 if (*(device+4) != ':')
202 return -1;
204 strcpy(temp,device+5);
205 ptr = strtok(temp, ", ");
207 if (COM[port].baudrate > 0)
208 lpdcb->BaudRate = COM[port].baudrate;
209 else
210 lpdcb->BaudRate = atoi(ptr);
211 dprintf_comm(stddeb,"BuildCommDCB: baudrate (%d)\n", lpdcb->BaudRate);
213 ptr = strtok(NULL, ", ");
214 if (islower(*ptr))
215 *ptr = toupper(*ptr);
217 dprintf_comm(stddeb,"BuildCommDCB: parity (%c)\n", *ptr);
218 lpdcb->fParity = 1;
219 switch (*ptr) {
220 case 'N':
221 lpdcb->Parity = NOPARITY;
222 lpdcb->fParity = 0;
223 break;
224 case 'E':
225 lpdcb->Parity = EVENPARITY;
226 break;
227 case 'M':
228 lpdcb->Parity = MARKPARITY;
229 break;
230 case 'O':
231 lpdcb->Parity = ODDPARITY;
232 break;
233 default:
234 fprintf(stderr,"comm: unknown parity `%c'!\n", *ptr);
235 return -1;
238 ptr = strtok(NULL, ", ");
239 dprintf_comm(stddeb, "BuildCommDCB: charsize (%c)\n", *ptr);
240 lpdcb->ByteSize = *ptr - '0';
242 ptr = strtok(NULL, ", ");
243 dprintf_comm(stddeb, "BuildCommDCB: stopbits (%c)\n", *ptr);
244 switch (*ptr) {
245 case '1':
246 lpdcb->StopBits = ONESTOPBIT;
247 break;
248 case '2':
249 lpdcb->StopBits = TWOSTOPBITS;
250 break;
251 default:
252 fprintf(stderr,"comm: unknown # of stopbits `%c'!\n", *ptr);
253 return -1;
257 return 0;
260 /**************************************************************************
261 * BuildCommDCBA (KERNEL32.14)
263 BOOL32 WINAPI BuildCommDCB32A(LPCSTR device,LPDCB32 lpdcb)
265 return BuildCommDCBAndTimeouts32A(device,lpdcb,NULL);
268 /**************************************************************************
269 * BuildCommDCBAndTimeoutsA (KERNEL32.15)
271 BOOL32 WINAPI BuildCommDCBAndTimeouts32A(LPCSTR device, LPDCB32 lpdcb,
272 LPCOMMTIMEOUTS lptimeouts)
274 int port;
275 char *ptr,*temp;
277 dprintf_comm(stddeb,"BuildCommDCBAndTimeouts32A(%s,%p,%p)\n",device,lpdcb,lptimeouts);
278 commerror = 0;
280 if (!lstrncmpi32A(device,"COM",3)) {
281 port=device[3]-'0';
282 if (port--==0) {
283 fprintf(stderr,"comm:BUG! COM0 can't exists!.\n");
284 return FALSE;
286 if (!ValidCOMPort(port))
287 return FALSE;
288 if (*(device+4)!=':')
289 return FALSE;
290 temp=(LPSTR)(device+5);
291 } else
292 temp=(LPSTR)device;
294 memset(lpdcb, 0, sizeof(DCB32)); /* initialize */
296 lpdcb->DCBlength = sizeof(DCB32);
297 if (strchr(temp,',')) { /* old style */
298 DCB16 dcb16;
299 BOOL16 ret;
300 char last=temp[strlen(temp)-1];
302 ret=BuildCommDCB16(device,&dcb16);
303 if (!ret)
304 return FALSE;
305 lpdcb->BaudRate = dcb16.BaudRate;
306 lpdcb->ByteSize = dcb16.ByteSize;
307 lpdcb->fBinary = dcb16.fBinary;
308 lpdcb->Parity = dcb16.Parity;
309 lpdcb->fParity = dcb16.fParity;
310 lpdcb->fNull = dcb16.fNull;
311 lpdcb->StopBits = dcb16.StopBits;
312 if (last == 'x') {
313 lpdcb->fInX = TRUE;
314 lpdcb->fOutX = TRUE;
315 lpdcb->fOutxCtsFlow = FALSE;
316 lpdcb->fOutxDsrFlow = FALSE;
317 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
318 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
319 } else if (last=='p') {
320 lpdcb->fInX = FALSE;
321 lpdcb->fOutX = FALSE;
322 lpdcb->fOutxCtsFlow = TRUE;
323 lpdcb->fOutxDsrFlow = TRUE;
324 lpdcb->fDtrControl = DTR_CONTROL_HANDSHAKE;
325 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
326 } else {
327 lpdcb->fInX = FALSE;
328 lpdcb->fOutX = FALSE;
329 lpdcb->fOutxCtsFlow = FALSE;
330 lpdcb->fOutxDsrFlow = FALSE;
331 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
332 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
334 lpdcb->XonChar = dcb16.XonChar;
335 lpdcb->XoffChar = dcb16.XoffChar;
336 lpdcb->ErrorChar= dcb16.PeChar;
337 lpdcb->fErrorChar= dcb16.fPeChar;
338 lpdcb->EofChar = dcb16.EofChar;
339 lpdcb->EvtChar = dcb16.EvtChar;
340 lpdcb->XonLim = dcb16.XonLim;
341 lpdcb->XoffLim = dcb16.XoffLim;
342 return TRUE;
344 ptr=strtok(temp," ");
345 while (ptr) {
346 DWORD flag,x;
348 flag=0;
349 if (!strncmp("baud=",ptr,5)) {
350 if (!sscanf(ptr+5,"%ld",&x))
351 fprintf(stderr,"BuildCommDCB32A:Couldn't parse %s\n",ptr);
352 lpdcb->BaudRate = x;
353 flag=1;
355 if (!strncmp("stop=",ptr,5)) {
356 if (!sscanf(ptr+5,"%ld",&x))
357 fprintf(stderr,"BuildCommDCB32A:Couldn't parse %s\n",ptr);
358 lpdcb->StopBits = x;
359 flag=1;
361 if (!strncmp("data=",ptr,5)) {
362 if (!sscanf(ptr+5,"%ld",&x))
363 fprintf(stderr,"BuildCommDCB32A:Couldn't parse %s\n",ptr);
364 lpdcb->ByteSize = x;
365 flag=1;
367 if (!strncmp("parity=",ptr,7)) {
368 lpdcb->fParity = TRUE;
369 switch (ptr[8]) {
370 case 'N':case 'n':
371 lpdcb->fParity = FALSE;
372 lpdcb->Parity = NOPARITY;
373 break;
374 case 'E':case 'e':
375 lpdcb->Parity = EVENPARITY;
376 break;
377 case 'O':case 'o':
378 lpdcb->Parity = ODDPARITY;
379 break;
380 case 'M':case 'm':
381 lpdcb->Parity = MARKPARITY;
382 break;
384 flag=1;
386 if (!flag)
387 fprintf(stderr,"BuildCommDCB32A: Unhandled specifier '%s', please report.\n",ptr);
388 ptr=strtok(NULL," ");
390 if (lpdcb->BaudRate==110)
391 lpdcb->StopBits = 2;
392 return TRUE;
395 /**************************************************************************
396 * BuildCommDCBAndTimeoutsW (KERNEL32.16)
398 BOOL32 WINAPI BuildCommDCBAndTimeouts32W( LPCWSTR devid, LPDCB32 lpdcb,
399 LPCOMMTIMEOUTS lptimeouts )
401 LPSTR devidA;
402 BOOL32 ret;
404 dprintf_comm(stddeb,"BuildCommDCBAndTimeouts32W(%p,%p,%p)\n",devid,lpdcb,lptimeouts);
405 devidA = HEAP_strdupWtoA( GetProcessHeap(), 0, devid );
406 ret=BuildCommDCBAndTimeouts32A(devidA,lpdcb,lptimeouts);
407 HeapFree( GetProcessHeap(), 0, devidA );
408 return ret;
411 /**************************************************************************
412 * BuildCommDCBW (KERNEL32.17)
414 BOOL32 WINAPI BuildCommDCB32W(LPCWSTR devid,LPDCB32 lpdcb)
416 return BuildCommDCBAndTimeouts32W(devid,lpdcb,NULL);
419 /*****************************************************************************
420 * OpenComm (USER.200)
422 INT16 WINAPI OpenComm(LPCSTR device,UINT16 cbInQueue,UINT16 cbOutQueue)
424 int port,fd;
426 dprintf_comm(stddeb,
427 "OpenComm: %s, %d, %d\n", device, cbInQueue, cbOutQueue);
428 commerror = 0;
430 if (!lstrncmpi32A(device,"COM",3)) {
431 port = device[3] - '0';
433 if (port-- == 0) {
434 fprintf(stderr, "comm: BUG ! COM0 doesn't exist !\n");
435 commerror = IE_BADID;
438 dprintf_comm(stddeb,
439 "OpenComm: %s = %s\n", device, COM[port].devicename);
441 if (!ValidCOMPort(port)) {
442 commerror = IE_BADID;
443 return -1;
445 if (COM[port].fd) {
446 return COM[port].fd;
449 fd = open(COM[port].devicename, O_RDWR | O_NONBLOCK);
450 if (fd == -1) {
451 commerror = WinError();
452 return -1;
453 } else {
454 unknown[port] = SEGPTR_ALLOC(40);
455 bzero(unknown[port],40);
456 COM[port].fd = fd;
457 return fd;
460 else
461 if (!lstrncmpi32A(device,"LPT",3)) {
462 port = device[3] - '0';
464 if (!ValidLPTPort(port)) {
465 commerror = IE_BADID;
466 return -1;
468 if (LPT[port].fd) {
469 commerror = IE_OPEN;
470 return -1;
473 fd = open(LPT[port].devicename, O_RDWR | O_NONBLOCK, 0);
474 if (fd == -1) {
475 commerror = WinError();
476 return -1;
477 } else {
478 LPT[port].fd = fd;
479 return fd;
482 return 0;
485 /*****************************************************************************
486 * CloseComm (USER.207)
488 INT16 WINAPI CloseComm(INT16 fd)
490 int port;
491 dprintf_comm(stddeb,"CloseComm: fd %d\n", fd);
492 if ((port = GetCommPort(fd)) !=-1) { /* [LW] */
493 SEGPTR_FREE(unknown[port]);
494 COM[port].fd = 0; /* my adaptation of RER's fix */
495 } else {
496 commerror = IE_BADID;
497 return -1;
500 if (close(fd) == -1) {
501 commerror = WinError();
502 return -1;
503 } else {
504 commerror = 0;
505 return 0;
509 /*****************************************************************************
510 * SetCommBreak (USER.210)
512 INT16 WINAPI SetCommBreak16(INT16 fd)
514 struct DosDeviceStruct *ptr;
516 dprintf_comm(stddeb,"SetCommBreak: fd: %d\n", fd);
517 if ((ptr = GetDeviceStruct(fd)) == NULL) {
518 commerror = IE_BADID;
519 return -1;
522 ptr->suspended = 1;
523 commerror = 0;
524 return 0;
527 /*****************************************************************************
528 * SetCommBreak (KERNEL32.449)
530 BOOL32 WINAPI SetCommBreak32(INT32 fd)
533 struct DosDeviceStruct *ptr;
535 dprintf_comm(stddeb,"SetCommBreak: fd: %d\n", fd);
536 if ((ptr = GetDeviceStruct(fd)) == NULL) {
537 commerror = IE_BADID;
538 return FALSE;
541 ptr->suspended = 1;
542 commerror = 0;
543 return TRUE;
546 /*****************************************************************************
547 * ClearCommBreak (USER.211)
549 INT16 WINAPI ClearCommBreak16(INT16 fd)
551 struct DosDeviceStruct *ptr;
553 dprintf_comm(stddeb,"ClearCommBreak: fd: %d\n", fd);
554 if ((ptr = GetDeviceStruct(fd)) == NULL) {
555 commerror = IE_BADID;
556 return -1;
559 ptr->suspended = 0;
560 commerror = 0;
561 return 0;
564 /*****************************************************************************
565 * ClearCommBreak (KERNEL32.20)
567 BOOL32 WINAPI ClearCommBreak32(INT32 fd)
569 struct DosDeviceStruct *ptr;
571 dprintf_comm(stddeb,"ClearCommBreak: fd: %d\n", fd);
572 if ((ptr = GetDeviceStruct(fd)) == NULL) {
573 commerror = IE_BADID;
574 return FALSE;
577 ptr->suspended = 0;
578 commerror = 0;
579 return TRUE;
582 /*****************************************************************************
583 * EscapeCommFunction (USER.214)
585 LONG WINAPI EscapeCommFunction16(UINT16 fd,UINT16 nFunction)
587 int max;
588 struct termios port;
590 dprintf_comm(stddeb,"EscapeCommFunction fd: %d, function: %d\n", fd, nFunction);
591 if (tcgetattr(fd,&port) == -1) {
592 commerror=WinError();
593 return -1;
596 switch (nFunction) {
597 case RESETDEV:
598 break;
600 case GETMAXCOM:
601 for (max = MAX_PORTS;!COM[max].devicename;max--)
603 return max;
604 break;
606 case GETMAXLPT:
607 for (max = MAX_PORTS;!LPT[max].devicename;max--)
609 return 0x80 + max;
610 break;
612 #ifdef TIOCM_DTR
613 case CLRDTR:
614 port.c_cflag &= TIOCM_DTR;
615 break;
616 #endif
618 #ifdef TIOCM_RTS
619 case CLRRTS:
620 port.c_cflag &= TIOCM_RTS;
621 break;
622 #endif
624 #ifdef CRTSCTS
625 case SETDTR:
626 port.c_cflag |= CRTSCTS;
627 break;
629 case SETRTS:
630 port.c_cflag |= CRTSCTS;
631 break;
632 #endif
634 case SETXOFF:
635 port.c_iflag |= IXOFF;
636 break;
638 case SETXON:
639 port.c_iflag |= IXON;
640 break;
642 default:
643 fprintf(stderr,
644 "EscapeCommFunction fd: %d, unknown function: %d\n",
645 fd, nFunction);
646 break;
649 if (tcsetattr(fd, TCSADRAIN, &port) == -1) {
650 commerror = WinError();
651 return -1;
652 } else {
653 commerror = 0;
654 return 0;
658 /*****************************************************************************
659 * EscapeCommFunction (KERNEL32.214)
661 BOOL32 WINAPI EscapeCommFunction32(INT32 fd,UINT32 nFunction)
663 struct termios port;
664 struct DosDeviceStruct *ptr;
666 dprintf_comm(stddeb,"EscapeCommFunction fd: %d, function: %d\n", fd, nFunction);
667 if (tcgetattr(fd,&port) == -1) {
668 commerror=WinError();
669 return FALSE;
671 if ((ptr = GetDeviceStruct(fd)) == NULL) {
672 commerror = IE_BADID;
673 return FALSE;
676 switch (nFunction) {
677 case RESETDEV:
678 break;
680 #ifdef TIOCM_DTR
681 case CLRDTR:
682 port.c_cflag &= TIOCM_DTR;
683 break;
684 #endif
686 #ifdef TIOCM_RTS
687 case CLRRTS:
688 port.c_cflag &= TIOCM_RTS;
689 break;
690 #endif
692 #ifdef CRTSCTS
693 case SETDTR:
694 port.c_cflag |= CRTSCTS;
695 break;
697 case SETRTS:
698 port.c_cflag |= CRTSCTS;
699 break;
700 #endif
702 case SETXOFF:
703 port.c_iflag |= IXOFF;
704 break;
706 case SETXON:
707 port.c_iflag |= IXON;
708 break;
709 case SETBREAK:
710 ptr->suspended = 1;
711 break;
712 case CLRBREAK:
713 ptr->suspended = 0;
714 break;
715 default:
716 fprintf(stderr,
717 "EscapeCommFunction32 fd: %d, unknown function: %d\n",
718 fd, nFunction);
719 break;
722 if (tcsetattr(fd, TCSADRAIN, &port) == -1) {
723 commerror = WinError();
724 return FALSE;
725 } else {
726 commerror = 0;
727 return TRUE;
731 /*****************************************************************************
732 * FlushComm (USER.215)
734 INT16 WINAPI FlushComm(INT16 fd,INT16 fnQueue)
736 int queue;
738 dprintf_comm(stddeb,"FlushComm fd: %d, queue: %d\n", fd, fnQueue);
739 switch (fnQueue) {
740 case 0: queue = TCOFLUSH;
741 break;
742 case 1: queue = TCIFLUSH;
743 break;
744 default:fprintf(stderr,
745 "FlushComm fd: %d, UNKNOWN queue: %d\n",
746 fd, fnQueue);
747 return -1;
749 if (tcflush(fd, queue)) {
750 commerror = WinError();
751 return -1;
752 } else {
753 commerror = 0;
754 return 0;
758 /********************************************************************
759 * PurgeComm (KERNEL32.557)
761 BOOL32 WINAPI PurgeComm( HANDLE32 hFile, DWORD flags)
763 dprintf_comm(stdnimp, "PurgeComm(%08x %08lx) unimplemented stub\n",
764 hFile, flags);
765 return 0;
768 /********************************************************************
769 * GetCommError (USER.203)
771 INT16 WINAPI GetCommError(INT16 fd,LPCOMSTAT lpStat)
773 int temperror;
774 unsigned long cnt;
775 int rc;
777 if (lpStat) {
778 lpStat->status = 0;
780 rc = ioctl(fd, TIOCOUTQ, &cnt);
781 if (rc) fprintf(stderr, "Error !\n");
782 lpStat->cbOutQue = cnt;
784 rc = ioctl(fd, TIOCINQ, &cnt);
785 if (rc) fprintf(stderr, "Error !\n");
786 lpStat->cbInQue = cnt;
788 dprintf_comm(stddeb,
789 "GetCommError: fd %d, error %d, lpStat %d %d %d\n",
790 fd, commerror,
791 lpStat->status, lpStat->cbInQue, lpStat->cbOutQue);
793 else
794 dprintf_comm(stddeb,
795 "GetCommError: fd %d, error %d, lpStat NULL\n",
796 fd, commerror);
799 * [RER] I have no idea what the following is trying to accomplish.
800 * [RER] It is certainly not what the reference manual suggests.
802 temperror = commerror;
803 commerror = 0;
804 return(temperror);
807 /*****************************************************************************
808 * ClearCommError (KERNEL32.21)
810 BOOL32 WINAPI ClearCommError(INT32 fd,LPDWORD errors,LPCOMSTAT lpStat)
812 int temperror;
814 dprintf_comm(stddeb,
815 "ClearCommError: fd %d (current error %d)\n", fd, commerror);
816 temperror = commerror;
817 commerror = 0;
818 return TRUE;
821 /*****************************************************************************
822 * SetCommEventMask (USER.208)
824 SEGPTR WINAPI SetCommEventMask(INT16 fd,UINT16 fuEvtMask)
826 unsigned char *stol;
827 int act;
828 int repid;
829 unsigned int mstat;
830 dprintf_comm(stddeb,"SetCommEventMask:fd %d,mask %d\n",fd,fuEvtMask);
831 eventmask |= fuEvtMask;
832 if ((act = GetCommPort(fd)) == -1) {
833 dprintf_comm(stddeb," fd %d not comm port\n",act);
834 return NULL;}
835 stol = unknown[act];
836 stol += msr;
837 repid = ioctl(fd,TIOCMGET,&mstat);
838 dprintf_comm(stddeb,
839 " ioctl %d, msr %x at %p %p\n",repid,mstat,stol,unknown[act]);
840 if ((mstat&TIOCM_CAR)) {*stol |= 0x80;}
841 else {*stol &=0x7f;}
842 dprintf_comm(stddeb," modem dcd construct %x\n",*stol);
843 return SEGPTR_GET(unknown[act]);
846 /*****************************************************************************
847 * GetCommEventMask (USER.209)
849 UINT16 WINAPI GetCommEventMask(INT16 fd,UINT16 fnEvtClear)
851 int events = 0;
853 dprintf_comm(stddeb,
854 "GetCommEventMask: fd %d, mask %d\n", fd, fnEvtClear);
857 * Determine if any characters are available
859 if (fnEvtClear & EV_RXCHAR)
861 int rc;
862 unsigned long cnt;
864 rc = ioctl(fd, TIOCINQ, &cnt);
865 if (cnt) events |= EV_RXCHAR;
867 dprintf_comm(stddeb,
868 "GetCommEventMask: rxchar %ld\n", cnt);
872 * There are other events that need to be checked for
874 /* TODO */
876 dprintf_comm(stddeb,
877 "GetCommEventMask: return events %d\n", events);
878 return events;
881 * [RER] The following was gibberish
883 #if 0
884 tempmask = eventmask;
885 eventmask &= ~fnEvtClear;
886 return eventmask;
887 #endif
890 /*****************************************************************************
891 * SetupComm (KERNEL32.676)
893 BOOL32 WINAPI SetupComm( HANDLE32 hFile, DWORD insize, DWORD outsize)
895 dprintf_comm(stdnimp, "SetupComm: insize %ld outsize %ld unimplemented stub\n", insize, outsize);
896 return FALSE;
899 /*****************************************************************************
900 * GetCommMask (KERNEL32.156)
902 BOOL32 WINAPI GetCommMask(INT32 fd,LPDWORD evtmask)
904 dprintf_comm(stddeb,
905 "GetCommMask: fd %d, mask %p\n", fd, evtmask);
906 *evtmask = eventmask;
907 return TRUE;
910 /*****************************************************************************
911 * SetCommMask (KERNEL32.451)
913 BOOL32 WINAPI SetCommMask(INT32 fd,DWORD evtmask)
915 dprintf_comm(stddeb,
916 "SetCommMask: fd %d, mask %lx\n", fd, evtmask);
917 eventmask = evtmask;
918 return TRUE;
921 /*****************************************************************************
922 * SetCommState16 (USER.201)
924 INT16 WINAPI SetCommState16(LPDCB16 lpdcb)
926 struct termios port;
927 struct DosDeviceStruct *ptr;
929 dprintf_comm(stddeb,
930 "SetCommState16: fd %d, ptr %p\n", lpdcb->Id, lpdcb);
931 if (tcgetattr(lpdcb->Id, &port) == -1) {
932 commerror = WinError();
933 return -1;
936 port.c_cc[VMIN] = 0;
937 port.c_cc[VTIME] = 1;
939 #ifdef IMAXBEL
940 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR|IMAXBEL);
941 #else
942 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR);
943 #endif
944 port.c_iflag |= (IGNBRK);
946 port.c_oflag &= ~(OPOST);
948 port.c_cflag &= ~(HUPCL);
949 port.c_cflag |= CLOCAL | CREAD;
951 port.c_lflag &= ~(ICANON|ECHO|ISIG);
952 port.c_lflag |= NOFLSH;
954 if ((ptr = GetDeviceStruct(lpdcb->Id)) == NULL) {
955 commerror = IE_BADID;
956 return -1;
958 if (ptr->baudrate > 0)
959 lpdcb->BaudRate = ptr->baudrate;
960 dprintf_comm(stddeb,"SetCommState: baudrate %d\n",lpdcb->BaudRate);
961 #ifdef CBAUD
962 port.c_cflag &= ~CBAUD;
963 switch (lpdcb->BaudRate) {
964 case 110:
965 case CBR_110:
966 port.c_cflag |= B110;
967 break;
968 case 300:
969 case CBR_300:
970 port.c_cflag |= B300;
971 break;
972 case 600:
973 case CBR_600:
974 port.c_cflag |= B600;
975 break;
976 case 1200:
977 case CBR_1200:
978 port.c_cflag |= B1200;
979 break;
980 case 2400:
981 case CBR_2400:
982 port.c_cflag |= B2400;
983 break;
984 case 4800:
985 case CBR_4800:
986 port.c_cflag |= B4800;
987 break;
988 case 9600:
989 case CBR_9600:
990 port.c_cflag |= B9600;
991 break;
992 case 19200:
993 case CBR_19200:
994 port.c_cflag |= B19200;
995 break;
996 case 38400:
997 case CBR_38400:
998 port.c_cflag |= B38400;
999 break;
1000 case 57600:
1001 port.c_cflag |= B57600;
1002 break;
1003 case 57601:
1004 port.c_cflag |= B115200;
1005 break;
1006 default:
1007 commerror = IE_BAUDRATE;
1008 return -1;
1010 #elif !defined(__EMX__)
1011 switch (lpdcb->BaudRate) {
1012 case 110:
1013 case CBR_110:
1014 port.c_ospeed = B110;
1015 break;
1016 case 300:
1017 case CBR_300:
1018 port.c_ospeed = B300;
1019 break;
1020 case 600:
1021 case CBR_600:
1022 port.c_ospeed = B600;
1023 break;
1024 case 1200:
1025 case CBR_1200:
1026 port.c_ospeed = B1200;
1027 break;
1028 case 2400:
1029 case CBR_2400:
1030 port.c_ospeed = B2400;
1031 break;
1032 case 4800:
1033 case CBR_4800:
1034 port.c_ospeed = B4800;
1035 break;
1036 case 9600:
1037 case CBR_9600:
1038 port.c_ospeed = B9600;
1039 break;
1040 case 19200:
1041 case CBR_19200:
1042 port.c_ospeed = B19200;
1043 break;
1044 case 38400:
1045 case CBR_38400:
1046 port.c_ospeed = B38400;
1047 break;
1048 default:
1049 commerror = IE_BAUDRATE;
1050 return -1;
1052 port.c_ispeed = port.c_ospeed;
1053 #endif
1054 dprintf_comm(stddeb,"SetCommState: bytesize %d\n",lpdcb->ByteSize);
1055 port.c_cflag &= ~CSIZE;
1056 switch (lpdcb->ByteSize) {
1057 case 5:
1058 port.c_cflag |= CS5;
1059 break;
1060 case 6:
1061 port.c_cflag |= CS6;
1062 break;
1063 case 7:
1064 port.c_cflag |= CS7;
1065 break;
1066 case 8:
1067 port.c_cflag |= CS8;
1068 break;
1069 default:
1070 commerror = IE_BYTESIZE;
1071 return -1;
1074 dprintf_comm(stddeb,"SetCommState: parity %d\n",lpdcb->Parity);
1075 port.c_cflag &= ~(PARENB | PARODD);
1076 if (lpdcb->fParity)
1077 switch (lpdcb->Parity) {
1078 case NOPARITY:
1079 port.c_iflag &= ~INPCK;
1080 break;
1081 case ODDPARITY:
1082 port.c_cflag |= (PARENB | PARODD);
1083 port.c_iflag |= INPCK;
1084 break;
1085 case EVENPARITY:
1086 port.c_cflag |= PARENB;
1087 port.c_iflag |= INPCK;
1088 break;
1089 default:
1090 commerror = IE_BYTESIZE;
1091 return -1;
1095 dprintf_comm(stddeb,"SetCommState: stopbits %d\n",lpdcb->StopBits);
1097 switch (lpdcb->StopBits) {
1098 case ONESTOPBIT:
1099 port.c_cflag &= ~CSTOPB;
1100 break;
1101 case TWOSTOPBITS:
1102 port.c_cflag |= CSTOPB;
1103 break;
1104 default:
1105 commerror = IE_BYTESIZE;
1106 return -1;
1108 #ifdef CRTSCTS
1110 if (lpdcb->fDtrflow || lpdcb->fRtsflow || lpdcb->fOutxCtsFlow)
1111 port.c_cflag |= CRTSCTS;
1113 if (lpdcb->fDtrDisable)
1114 port.c_cflag &= ~CRTSCTS;
1115 #endif
1116 if (lpdcb->fInX)
1117 port.c_iflag |= IXON;
1118 else
1119 port.c_iflag &= ~IXON;
1120 if (lpdcb->fOutX)
1121 port.c_iflag |= IXOFF;
1122 else
1123 port.c_iflag &= ~IXOFF;
1125 if (tcsetattr(lpdcb->Id, TCSADRAIN, &port) == -1) {
1126 commerror = WinError();
1127 return FALSE;
1128 } else {
1129 commerror = 0;
1130 return 0;
1134 /*****************************************************************************
1135 * SetCommState32 (KERNEL32.452)
1137 BOOL32 WINAPI SetCommState32(INT32 fd,LPDCB32 lpdcb)
1139 struct termios port;
1140 struct DosDeviceStruct *ptr;
1142 dprintf_comm(stddeb,"SetCommState32: fd %d, ptr %p\n",fd,lpdcb);
1143 if (tcgetattr(fd,&port) == -1) {
1144 commerror = WinError();
1145 return FALSE;
1148 port.c_cc[VMIN] = 0;
1149 port.c_cc[VTIME] = 1;
1151 #ifdef IMAXBEL
1152 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR|IMAXBEL);
1153 #else
1154 port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR);
1155 #endif
1156 port.c_iflag |= (IGNBRK);
1158 port.c_oflag &= ~(OPOST);
1160 port.c_cflag &= ~(HUPCL);
1161 port.c_cflag |= CLOCAL | CREAD;
1163 port.c_lflag &= ~(ICANON|ECHO|ISIG);
1164 port.c_lflag |= NOFLSH;
1166 if ((ptr = GetDeviceStruct(fd)) == NULL) {
1167 commerror = IE_BADID;
1168 return FALSE;
1170 if (ptr->baudrate > 0)
1171 lpdcb->BaudRate = ptr->baudrate;
1172 dprintf_comm(stddeb,"SetCommState: baudrate %ld\n",lpdcb->BaudRate);
1173 #ifdef CBAUD
1174 port.c_cflag &= ~CBAUD;
1175 switch (lpdcb->BaudRate) {
1176 case 110:
1177 case CBR_110:
1178 port.c_cflag |= B110;
1179 break;
1180 case 300:
1181 case CBR_300:
1182 port.c_cflag |= B300;
1183 break;
1184 case 600:
1185 case CBR_600:
1186 port.c_cflag |= B600;
1187 break;
1188 case 1200:
1189 case CBR_1200:
1190 port.c_cflag |= B1200;
1191 break;
1192 case 2400:
1193 case CBR_2400:
1194 port.c_cflag |= B2400;
1195 break;
1196 case 4800:
1197 case CBR_4800:
1198 port.c_cflag |= B4800;
1199 break;
1200 case 9600:
1201 case CBR_9600:
1202 port.c_cflag |= B9600;
1203 break;
1204 case 19200:
1205 case CBR_19200:
1206 port.c_cflag |= B19200;
1207 break;
1208 case 38400:
1209 case CBR_38400:
1210 port.c_cflag |= B38400;
1211 break;
1212 default:
1213 commerror = IE_BAUDRATE;
1214 return FALSE;
1216 #elif !defined(__EMX__)
1217 switch (lpdcb->BaudRate) {
1218 case 110:
1219 case CBR_110:
1220 port.c_ospeed = B110;
1221 break;
1222 case 300:
1223 case CBR_300:
1224 port.c_ospeed = B300;
1225 break;
1226 case 600:
1227 case CBR_600:
1228 port.c_ospeed = B600;
1229 break;
1230 case 1200:
1231 case CBR_1200:
1232 port.c_ospeed = B1200;
1233 break;
1234 case 2400:
1235 case CBR_2400:
1236 port.c_ospeed = B2400;
1237 break;
1238 case 4800:
1239 case CBR_4800:
1240 port.c_ospeed = B4800;
1241 break;
1242 case 9600:
1243 case CBR_9600:
1244 port.c_ospeed = B9600;
1245 break;
1246 case 19200:
1247 case CBR_19200:
1248 port.c_ospeed = B19200;
1249 break;
1250 case 38400:
1251 case CBR_38400:
1252 port.c_ospeed = B38400;
1253 break;
1254 default:
1255 commerror = IE_BAUDRATE;
1256 return FALSE;
1258 port.c_ispeed = port.c_ospeed;
1259 #endif
1260 dprintf_comm(stddeb,"SetCommState: bytesize %d\n",lpdcb->ByteSize);
1261 port.c_cflag &= ~CSIZE;
1262 switch (lpdcb->ByteSize) {
1263 case 5:
1264 port.c_cflag |= CS5;
1265 break;
1266 case 6:
1267 port.c_cflag |= CS6;
1268 break;
1269 case 7:
1270 port.c_cflag |= CS7;
1271 break;
1272 case 8:
1273 port.c_cflag |= CS8;
1274 break;
1275 default:
1276 commerror = IE_BYTESIZE;
1277 return FALSE;
1280 dprintf_comm(stddeb,"SetCommState: parity %d\n",lpdcb->Parity);
1281 port.c_cflag &= ~(PARENB | PARODD);
1282 if (lpdcb->fParity)
1283 switch (lpdcb->Parity) {
1284 case NOPARITY:
1285 port.c_iflag &= ~INPCK;
1286 break;
1287 case ODDPARITY:
1288 port.c_cflag |= (PARENB | PARODD);
1289 port.c_iflag |= INPCK;
1290 break;
1291 case EVENPARITY:
1292 port.c_cflag |= PARENB;
1293 port.c_iflag |= INPCK;
1294 break;
1295 default:
1296 commerror = IE_BYTESIZE;
1297 return FALSE;
1301 dprintf_comm(stddeb,"SetCommState: stopbits %d\n",lpdcb->StopBits);
1302 switch (lpdcb->StopBits) {
1303 case ONESTOPBIT:
1304 port.c_cflag &= ~CSTOPB;
1305 break;
1306 case TWOSTOPBITS:
1307 port.c_cflag |= CSTOPB;
1308 break;
1309 default:
1310 commerror = IE_BYTESIZE;
1311 return FALSE;
1313 #ifdef CRTSCTS
1314 if ( lpdcb->fOutxCtsFlow ||
1315 lpdcb->fDtrControl == DTR_CONTROL_ENABLE||
1316 lpdcb->fRtsControl == RTS_CONTROL_ENABLE
1318 port.c_cflag |= CRTSCTS;
1319 if (lpdcb->fDtrControl == DTR_CONTROL_DISABLE)
1320 port.c_cflag &= ~CRTSCTS;
1322 #endif
1323 if (lpdcb->fInX)
1324 port.c_iflag |= IXON;
1325 else
1326 port.c_iflag &= ~IXON;
1327 if (lpdcb->fOutX)
1328 port.c_iflag |= IXOFF;
1329 else
1330 port.c_iflag &= ~IXOFF;
1332 if (tcsetattr(fd,TCSADRAIN,&port)==-1) {
1333 commerror = WinError();
1334 return FALSE;
1335 } else {
1336 commerror = 0;
1337 return TRUE;
1342 /*****************************************************************************
1343 * GetCommState (USER.202)
1345 INT16 WINAPI GetCommState16(INT16 fd, LPDCB16 lpdcb)
1347 struct termios port;
1349 dprintf_comm(stddeb,"GetCommState16: fd %d, ptr %p\n", fd, lpdcb);
1350 if (tcgetattr(fd, &port) == -1) {
1351 commerror = WinError();
1352 return -1;
1354 lpdcb->Id = fd;
1355 #ifndef __EMX__
1356 #ifdef CBAUD
1357 switch (port.c_cflag & CBAUD) {
1358 #else
1359 switch (port.c_ospeed) {
1360 #endif
1361 case B110:
1362 lpdcb->BaudRate = 110;
1363 break;
1364 case B300:
1365 lpdcb->BaudRate = 300;
1366 break;
1367 case B600:
1368 lpdcb->BaudRate = 600;
1369 break;
1370 case B1200:
1371 lpdcb->BaudRate = 1200;
1372 break;
1373 case B2400:
1374 lpdcb->BaudRate = 2400;
1375 break;
1376 case B4800:
1377 lpdcb->BaudRate = 4800;
1378 break;
1379 case B9600:
1380 lpdcb->BaudRate = 9600;
1381 break;
1382 case B19200:
1383 lpdcb->BaudRate = 19200;
1384 break;
1385 case B38400:
1386 lpdcb->BaudRate = 38400;
1387 break;
1388 case B57600:
1389 lpdcb->BaudRate = 57600;
1390 break;
1391 case B115200:
1392 lpdcb->BaudRate = 57601;
1393 break;
1395 #endif
1396 switch (port.c_cflag & CSIZE) {
1397 case CS5:
1398 lpdcb->ByteSize = 5;
1399 break;
1400 case CS6:
1401 lpdcb->ByteSize = 6;
1402 break;
1403 case CS7:
1404 lpdcb->ByteSize = 7;
1405 break;
1406 case CS8:
1407 lpdcb->ByteSize = 8;
1408 break;
1411 switch (port.c_cflag & ~(PARENB | PARODD)) {
1412 case 0:
1413 lpdcb->fParity = NOPARITY;
1414 break;
1415 case PARENB:
1416 lpdcb->fParity = EVENPARITY;
1417 break;
1418 case (PARENB | PARODD):
1419 lpdcb->fParity = ODDPARITY;
1420 break;
1423 if (port.c_cflag & CSTOPB)
1424 lpdcb->StopBits = TWOSTOPBITS;
1425 else
1426 lpdcb->StopBits = ONESTOPBIT;
1428 lpdcb->RlsTimeout = 50;
1429 lpdcb->CtsTimeout = 50;
1430 lpdcb->DsrTimeout = 50;
1431 lpdcb->fNull = 0;
1432 lpdcb->fChEvt = 0;
1433 lpdcb->fBinary = 1;
1434 lpdcb->fDtrDisable = 0;
1436 #ifdef CRTSCTS
1438 if (port.c_cflag & CRTSCTS) {
1439 lpdcb->fDtrflow = 1;
1440 lpdcb->fRtsflow = 1;
1441 lpdcb->fOutxCtsFlow = 1;
1442 lpdcb->fOutxDsrFlow = 1;
1443 } else
1444 #endif
1445 lpdcb->fDtrDisable = 1;
1447 if (port.c_iflag & IXON)
1448 lpdcb->fInX = 1;
1449 else
1450 lpdcb->fInX = 0;
1452 if (port.c_iflag & IXOFF)
1453 lpdcb->fOutX = 1;
1454 else
1455 lpdcb->fOutX = 0;
1457 lpdcb->XonChar =
1458 lpdcb->XoffChar =
1460 lpdcb->XonLim = 10;
1461 lpdcb->XoffLim = 10;
1463 commerror = 0;
1464 return 0;
1467 /*****************************************************************************
1468 * GetCommState (KERNEL32.159)
1470 BOOL32 WINAPI GetCommState32(INT32 fd, LPDCB32 lpdcb)
1472 struct termios port;
1474 dprintf_comm(stddeb,"GetCommState32: fd %d, ptr %p\n", fd, lpdcb);
1475 if (GetDeviceStruct(fd) == NULL) return FALSE;
1476 if (tcgetattr(fd, &port) == -1) {
1477 commerror = WinError();
1478 return FALSE;
1480 #ifndef __EMX__
1481 #ifdef CBAUD
1482 switch (port.c_cflag & CBAUD) {
1483 #else
1484 switch (port.c_ospeed) {
1485 #endif
1486 case B110:
1487 lpdcb->BaudRate = 110;
1488 break;
1489 case B300:
1490 lpdcb->BaudRate = 300;
1491 break;
1492 case B600:
1493 lpdcb->BaudRate = 600;
1494 break;
1495 case B1200:
1496 lpdcb->BaudRate = 1200;
1497 break;
1498 case B2400:
1499 lpdcb->BaudRate = 2400;
1500 break;
1501 case B4800:
1502 lpdcb->BaudRate = 4800;
1503 break;
1504 case B9600:
1505 lpdcb->BaudRate = 9600;
1506 break;
1507 case B19200:
1508 lpdcb->BaudRate = 19200;
1509 break;
1510 case B38400:
1511 lpdcb->BaudRate = 38400;
1512 break;
1514 #endif
1515 switch (port.c_cflag & CSIZE) {
1516 case CS5:
1517 lpdcb->ByteSize = 5;
1518 break;
1519 case CS6:
1520 lpdcb->ByteSize = 6;
1521 break;
1522 case CS7:
1523 lpdcb->ByteSize = 7;
1524 break;
1525 case CS8:
1526 lpdcb->ByteSize = 8;
1527 break;
1530 switch (port.c_cflag & ~(PARENB | PARODD)) {
1531 case 0:
1532 lpdcb->fParity = NOPARITY;
1533 break;
1534 case PARENB:
1535 lpdcb->fParity = EVENPARITY;
1536 break;
1537 case (PARENB | PARODD):
1538 lpdcb->fParity = ODDPARITY;
1539 break;
1542 if (port.c_cflag & CSTOPB)
1543 lpdcb->StopBits = TWOSTOPBITS;
1544 else
1545 lpdcb->StopBits = ONESTOPBIT;
1547 lpdcb->fNull = 0;
1548 lpdcb->fBinary = 1;
1550 #ifdef CRTSCTS
1552 if (port.c_cflag & CRTSCTS) {
1553 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
1554 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
1555 lpdcb->fOutxCtsFlow = 1;
1556 lpdcb->fOutxDsrFlow = 1;
1557 } else
1558 #endif
1560 lpdcb->fDtrControl = DTR_CONTROL_DISABLE;
1561 lpdcb->fRtsControl = RTS_CONTROL_DISABLE;
1563 if (port.c_iflag & IXON)
1564 lpdcb->fInX = 1;
1565 else
1566 lpdcb->fInX = 0;
1568 if (port.c_iflag & IXOFF)
1569 lpdcb->fOutX = 1;
1570 else
1571 lpdcb->fOutX = 0;
1573 lpdcb->XonChar =
1574 lpdcb->XoffChar =
1576 lpdcb->XonLim = 10;
1577 lpdcb->XoffLim = 10;
1579 commerror = 0;
1580 return TRUE;
1583 /*****************************************************************************
1584 * TransmitCommChar (USER.206)
1586 INT16 WINAPI TransmitCommChar16(INT16 fd,CHAR chTransmit)
1588 struct DosDeviceStruct *ptr;
1590 dprintf_comm(stddeb,
1591 "TransmitCommChar: fd %d, data %d \n", fd, chTransmit);
1592 if ((ptr = GetDeviceStruct(fd)) == NULL) {
1593 commerror = IE_BADID;
1594 return -1;
1597 if (ptr->suspended) {
1598 commerror = IE_HARDWARE;
1599 return -1;
1602 if (write(fd, (void *) &chTransmit, 1) == -1) {
1603 commerror = WinError();
1604 return -1;
1605 } else {
1606 commerror = 0;
1607 return 0;
1611 /*****************************************************************************
1612 * TransmitCommChar (KERNEL32.535)
1614 BOOL32 WINAPI TransmitCommChar32(INT32 fd,CHAR chTransmit)
1616 struct DosDeviceStruct *ptr;
1618 dprintf_comm(stddeb,"TransmitCommChar32(%d,'%c')\n",fd,chTransmit);
1619 if ((ptr = GetDeviceStruct(fd)) == NULL) {
1620 commerror = IE_BADID;
1621 return FALSE;
1624 if (ptr->suspended) {
1625 commerror = IE_HARDWARE;
1626 return FALSE;
1628 if (write(fd, (void *) &chTransmit, 1) == -1) {
1629 commerror = WinError();
1630 return FALSE;
1631 } else {
1632 commerror = 0;
1633 return TRUE;
1637 /*****************************************************************************
1638 * UngetCommChar (USER.212)
1640 INT16 WINAPI UngetCommChar(INT16 fd,CHAR chUnget)
1642 struct DosDeviceStruct *ptr;
1644 dprintf_comm(stddeb,"UngetCommChar: fd %d (char %d)\n", fd, chUnget);
1645 if ((ptr = GetDeviceStruct(fd)) == NULL) {
1646 commerror = IE_BADID;
1647 return -1;
1650 if (ptr->suspended) {
1651 commerror = IE_HARDWARE;
1652 return -1;
1655 ptr->unget = 1;
1656 ptr->unget_byte = chUnget;
1657 commerror = 0;
1658 return 0;
1661 /*****************************************************************************
1662 * ReadComm (USER.204)
1664 INT16 WINAPI ReadComm(INT16 fd,LPSTR lpvBuf,INT16 cbRead)
1666 int status, x, length;
1667 struct DosDeviceStruct *ptr;
1669 dprintf_comm(stddeb,
1670 "ReadComm: fd %d, ptr %p, length %d\n", fd, lpvBuf, cbRead);
1671 if ((ptr = GetDeviceStruct(fd)) == NULL) {
1672 commerror = IE_BADID;
1673 return -1;
1676 if (ptr->suspended) {
1677 commerror = IE_HARDWARE;
1678 return -1;
1681 if (ptr->unget) {
1682 *lpvBuf = ptr->unget_byte;
1683 lpvBuf++;
1684 ptr->unget = 0;
1686 length = 1;
1687 } else
1688 length = 0;
1690 status = read(fd, (void *) lpvBuf, cbRead);
1692 if (status == -1) {
1693 if (errno != EAGAIN) {
1694 commerror = WinError();
1695 return -1 - length;
1696 } else {
1697 commerror = 0;
1698 return length;
1700 } else {
1701 for (x=0; x < length+status; x++)
1702 dprintf_comm(stddeb,"%c",*(lpvBuf+x));
1703 dprintf_comm(stddeb,"\nthus endeth\n");
1704 commerror = 0;
1705 return length + status;
1709 /*****************************************************************************
1710 * WriteComm (USER.205)
1712 INT16 WINAPI WriteComm(INT16 fd, LPSTR lpvBuf, INT16 cbWrite)
1714 int x, length;
1715 struct DosDeviceStruct *ptr;
1717 dprintf_comm(stddeb,"WriteComm: fd %d, ptr %p, length %d\n",
1718 fd, lpvBuf, cbWrite);
1719 if ((ptr = GetDeviceStruct(fd)) == NULL) {
1720 commerror = IE_BADID;
1721 return -1;
1724 if (ptr->suspended) {
1725 commerror = IE_HARDWARE;
1726 return -1;
1729 for (x=0; x != cbWrite ; x++)
1730 dprintf_comm(stddeb,"%c", *(lpvBuf + x) );
1731 dprintf_comm(stddeb,"\n");
1732 length = write(fd, (void *) lpvBuf, cbWrite);
1734 if (length == -1) {
1735 commerror = WinError();
1736 return -1;
1737 } else {
1738 commerror = 0;
1739 return length;
1744 /*****************************************************************************
1745 * GetCommTimeouts (KERNEL32.160)
1747 BOOL32 WINAPI GetCommTimeouts(INT32 fd,LPCOMMTIMEOUTS lptimeouts)
1749 fprintf(stderr,"GetCommTimeouts(%x,%p), empty stub.\n",
1750 fd,lptimeouts
1752 return TRUE;
1755 /*****************************************************************************
1756 * SetCommTimeouts (KERNEL32.453)
1758 BOOL32 WINAPI SetCommTimeouts(INT32 fd,LPCOMMTIMEOUTS lptimeouts) {
1759 fprintf(stderr,"SetCommTimeouts(%x,%p), empty stub.\n",
1760 fd,lptimeouts
1762 return TRUE;
1765 /***********************************************************************
1766 * EnableCommNotification (USER.246)
1768 BOOL16 WINAPI EnableCommNotification( INT16 fd, HWND16 hwnd,
1769 INT16 cbWriteNotify, INT16 cbOutQueue )
1771 fprintf(stderr, "EnableCommNotification(%d, %x, %d, %d), empty stub.\n", fd, hwnd, cbWriteNotify, cbOutQueue);
1772 return TRUE;