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