* fhandler.h (class fhandler_serial): Add new members of

the class - rts,dtr and method ioctl(). Variables rts and dtr
	important for Win 9x only.
	* fhandler_serial.cc (fhandler_serial::open): Add initial setting
	of dtr and rts. Important for Win 9x only.
	(fhandler_serial::ioctl): New function. Implements commands TIOCMGET,
	TIOCMSET and TIOCINQ.
	(fhandler_serial::tcflush): Fixed found error.
	(fhandler_serial::tcsetattr): Add settings of rts and dtr. Important
	for Win 9x only.
	* termios.h: Add new defines as a support for ioctl() function
	on serial device.
This commit is contained in:
Corinna Vinschen 2002-07-22 09:11:45 +00:00
parent 6b2ba9ad49
commit 780c42b43a
4 changed files with 168 additions and 2 deletions

View File

@ -1,3 +1,18 @@
2002-07-22 Jacek Trzcinski <jacek@certum.pl>
* fhandler.h (class fhandler_serial): Add new members of
the class - rts,dtr and method ioctl(). Variables rts and dtr
important for Win 9x only.
* fhandler_serial.cc (fhandler_serial::open): Add initial setting
of dtr and rts. Important for Win 9x only.
(fhandler_serial::ioctl): New function. Implements commands TIOCMGET,
TIOCMSET and TIOCINQ.
(fhandler_serial::tcflush): Fixed found error.
(fhandler_serial::tcsetattr): Add settings of rts and dtr. Important
for Win 9x only.
* termios.h: Add new defines as a support for ioctl() function
on serial device.
2002-07-20 Christopher Faylor <cgf@redhat.com>
* autoload.cc (LoadDLLprime): Add jmp call to allow streamlining of

View File

@ -629,6 +629,8 @@ class fhandler_serial: public fhandler_base
unsigned int vmin_; /* from termios */
unsigned int vtime_; /* from termios */
pid_t pgrp_;
int rts; /* for Windows 9x purposes only */
int dtr; /* for Windows 9x purposes only */
public:
int overlapped_armed;
@ -648,6 +650,7 @@ class fhandler_serial: public fhandler_base
int tcsendbreak (int);
int tcdrain ();
int tcflow (int);
int ioctl (unsigned int cmd, void *);
int tcsetattr (int a, const struct termios *t);
int tcgetattr (struct termios *t);
__off64_t lseek (__off64_t, int) { return 0; }

View File

@ -268,6 +268,23 @@ fhandler_serial::open (path_conv *, int flags, mode_t mode)
system_printf ("couldn't set initial state for %s, %E", get_name ());
}
/* setting rts and dtr to known state so that ioctl() function with
request TIOCMGET could return correct value of RTS and DTR lines.
Important only for Win 9x systems */
if (wincap.is_winnt() == false)
{
if (EscapeCommFunction (get_handle (), SETDTR) == 0)
system_printf ("couldn't set initial state of DTR for %s, %E", get_name ());
if (EscapeCommFunction (get_handle (), SETRTS) == 0)
system_printf ("couldn't set initial state of RTS for %s, %E", get_name ());
/* even though one of above functions fail I have to set rts and dtr
variables to initial value. */
rts = TIOCM_RTS;
dtr = TIOCM_DTR;
}
SetCommMask (get_handle (), EV_RXCHAR);
set_open_status ();
syscall_printf ("%p = fhandler_serial::open (%s, %p, %p)",
@ -324,7 +341,7 @@ fhandler_serial::tcflow (int action)
DWORD win32action = 0;
DCB dcb;
char xchar;
termios_printf ("action %d", action);
switch (action)
@ -358,6 +375,107 @@ fhandler_serial::tcflow (int action)
return 0;
}
/* ioctl: */
int
fhandler_serial::ioctl (unsigned int cmd, void *buffer)
{
DWORD ev;
COMSTAT st;
DWORD action;
DWORD modemLines;
DWORD mcr;
DWORD cbReturned;
bool result;
int modemStatus;
int request;
request = *(int *) buffer;
action = 0;
modemStatus = 0;
if (!ClearCommError (get_handle (), &ev, &st))
return -1;
switch (cmd)
{
case TIOCMGET:
if (GetCommModemStatus (get_handle (), &modemLines) == 0)
return -1;
if (modemLines & MS_CTS_ON)
modemStatus |= TIOCM_CTS;
if (modemLines & MS_DSR_ON)
modemStatus |= TIOCM_DSR;
if (modemLines & MS_RING_ON)
modemStatus |= TIOCM_RI;
if (modemLines & MS_RLSD_ON)
modemStatus |= TIOCM_CD;
if (wincap.is_winnt() == true)
{
/* here is Windows NT or Windows 2000 part */
result = DeviceIoControl (get_handle (),
0x001B0078,
NULL, 0, &mcr, 4, &cbReturned, 0);
if (!result)
return -1;
if (cbReturned != 4)
return -1;
if (mcr & 2)
modemStatus |= TIOCM_RTS;
if (mcr & 1)
modemStatus |= TIOCM_DTR;
}
else
{
/* here is Windows 9x part */
modemStatus |= rts | dtr;
}
*(int *) buffer = modemStatus;
return 0;
case TIOCMSET:
if (request & TIOCM_RTS)
{
if (EscapeCommFunction (get_handle (), SETRTS) == 0)
return -1;
else
rts = TIOCM_RTS;
}
else
{
if (EscapeCommFunction (get_handle (), CLRRTS) == 0)
return -1;
else
rts = 0;
}
if (request & TIOCM_DTR)
{
if (EscapeCommFunction (get_handle (), SETDTR) == 0)
return -1;
else
dtr = TIOCM_DTR;
}
else
{
if (EscapeCommFunction (get_handle (), CLRDTR) == 0)
return -1;
else
dtr = 0;
}
return 0;
case TIOCINQ:
if (ev & CE_FRAME | ev & CE_IOE | ev & CE_OVERRUN |
ev & CE_RXOVER | ev & CE_RXPARITY)
return -1;
*(int *) buffer = st.cbInQue;
return 0;
default:
return -1;
}
}
/* tcflush: POSIX 7.2.2.1 */
int
fhandler_serial::tcflush (int queue)
@ -395,6 +513,8 @@ fhandler_serial::tcsetattr (int action, const struct termios *t)
COMMTIMEOUTS to;
DCB ostate, state;
unsigned int ovtime = vtime_, ovmin = vmin_;
int tmpDtr, tmpRts;
tmpDtr = tmpRts = 0;
termios_printf ("action %d", action);
if ((action == TCSADRAIN) || (action == TCSAFLUSH))
@ -560,6 +680,7 @@ fhandler_serial::tcsetattr (int action, const struct termios *t)
{ /* disable */
state.fRtsControl = RTS_CONTROL_ENABLE;
state.fOutxCtsFlow = FALSE;
tmpRts = TIOCM_RTS;
}
if (t->c_cflag & CRTSXOFF)
@ -592,7 +713,10 @@ fhandler_serial::tcsetattr (int action, const struct termios *t)
set_w_binary ((t->c_oflag & ONLCR) ? 0 : 1);
if (dropDTR == TRUE)
EscapeCommFunction (get_handle (), CLRDTR);
{
EscapeCommFunction (get_handle (), CLRDTR);
tmpDtr = 0;
}
else
{
/* FIXME: Sometimes when CLRDTR is set, setting
@ -601,7 +725,11 @@ fhandler_serial::tcsetattr (int action, const struct termios *t)
parameters while DTR is still down. */
EscapeCommFunction (get_handle (), SETDTR);
tmpDtr = TIOCM_DTR;
}
rts = tmpRts;
dtr = tmpDtr;
/*
The following documentation on was taken from "Linux Serial Programming

View File

@ -13,6 +13,26 @@ details. */
#ifndef _SYS_TERMIOS_H
#define _SYS_TERMIOS_H
#define TIOCMGET 0x5415
#define TIOCMSET 0x5418
#define TIOCINQ 0x541B
/* TIOCINQ is utilized instead of FIONREAD which has been
accupied for other purposes under CYGWIN.
Other UNIX ioctl requests has been omited because
effects of their work one can achive by standard
POSIX commands */
#define TIOCM_DTR 0x002
#define TIOCM_RTS 0x004
#define TIOCM_CTS 0x020
#define TIOCM_CAR 0x040
#define TIOCM_RNG 0x080
#define TIOCM_DSR 0x100
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG
#define TCOOFF 0
#define TCOON 1
#define TCIOFF 2