* fhandler_serial.cc (fhandler_serial::ioctl): Reformat. Set errno

appropriately.  Exit from the bottom.  Correctly deal with third argument for
TCFLSH.  (Suggested by Sergey Okhapkin)
This commit is contained in:
Christopher Faylor 2002-11-04 04:09:14 +00:00
parent 2f14399c16
commit b6183403ae
3 changed files with 130 additions and 84 deletions

View File

@ -1,4 +1,10 @@
2002-11-03 Sergey Okhapkin <sos@prospect.com.ru>
2002-11-03 Christopher Faylor <cgf@redhat.com>
* fhandler_serial.cc (fhandler_serial::ioctl): Reformat. Set errno
appropriately. Exit from the bottom. Correctly deal with third
argument for TCFLSH. (Suggested by Sergey Okhapkin)
2003-11-03 Sergey Okhapkin <sos@prospect.com.ru>
* fhandler_tty.cc (fhandler_tty_slave::ioctl): Do nothing if the new
window size is equal to the old one. Send SIGWINCH if slave connected

View File

@ -380,92 +380,130 @@ fhandler_serial::tcflow (int action)
int
fhandler_serial::ioctl (unsigned int cmd, void *buffer)
{
int res = 0;
# define ibuffer ((int) buffer)
# define ipbuffer (*(int *) 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;
if (ClearCommError (get_handle (), &ev, &st))
res = -1;
else
switch (cmd)
{
case TCFLSH:
res = tcflush (ibuffer);
break;
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;
DWORD modem_lines;
if (GetCommModemStatus (get_handle (), &modem_lines) == 0)
{
__seterrno ();
res = -1;
}
else
{
unsigned modem_status = 0;
if (modem_lines & MS_CTS_ON)
modem_status |= TIOCM_CTS;
if (modem_lines & MS_DSR_ON)
modem_status |= TIOCM_DSR;
if (modem_lines & MS_RING_ON)
modem_status |= TIOCM_RI;
if (modem_lines & MS_RLSD_ON)
modem_status |= TIOCM_CD;
if (!wincap.supports_reading_modem_output_lines ())
modemStatus |= rts | dtr;
modem_status |= rts | dtr;
else
{
result = DeviceIoControl (get_handle (),
0x001B0078,
NULL, 0, &mcr, 4, &cbReturned, 0);
DWORD cb;
DWORD mcr;
BOOL result = DeviceIoControl (get_handle (), 0x001B0078, NULL,
0, &mcr, 4, &cb, 0);
if (!result)
return -1;
if (cbReturned != 4)
return -1;
{
__seterrno ();
res = -1;
goto out;
}
if (cb != 4)
{
set_errno (EINVAL); /* FIXME: right errno? */
res = -1;
goto out;
}
if (mcr & 2)
modemStatus |= TIOCM_RTS;
modem_status |= TIOCM_RTS;
if (mcr & 1)
modemStatus |= TIOCM_DTR;
modem_status |= TIOCM_DTR;
}
*(int *) buffer = modemStatus;
return 0;
ipbuffer = modem_status;
}
break;
case TIOCMSET:
if (request & TIOCM_RTS)
if (ipbuffer & TIOCM_RTS)
{
if (EscapeCommFunction (get_handle (), SETRTS) == 0)
return -1;
else
if (EscapeCommFunction (get_handle (), SETRTS))
rts = TIOCM_RTS;
else
{
__seterrno ();
res = -1;
}
}
else
{
if (EscapeCommFunction (get_handle (), CLRRTS) == 0)
return -1;
else
if (EscapeCommFunction (get_handle (), CLRRTS))
rts = 0;
}
if (request & TIOCM_DTR)
{
if (EscapeCommFunction (get_handle (), SETDTR) == 0)
return -1;
else
{
__seterrno ();
res = -1;
}
}
if (ipbuffer & TIOCM_DTR)
{
if (EscapeCommFunction (get_handle (), SETDTR))
dtr = TIOCM_DTR;
else
{
__seterrno ();
res = -1;
}
}
else
{
if (EscapeCommFunction (get_handle (), CLRDTR) == 0)
return -1;
else
if (EscapeCommFunction (get_handle (), CLRDTR))
dtr = 0;
else
{
__seterrno ();
res = -1;
}
return 0;
}
break;
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;
if (ev & CE_FRAME || ev & CE_IOE || ev & CE_OVERRUN || ev & CE_RXOVER
|| ev & CE_RXPARITY)
{
set_errno (EINVAL); /* FIXME: Use correct errno */
res = -1;
}
else
ipbuffer = st.cbInQue;
break;
default:
set_errno (ENOSYS);
res = -1;
break;
}
out:
termios_printf ("%d = ioctl (%p, %p)", res, cmd, buffer);
# undef ibuffer
# undef ipbuffer
return res;
}
/* tcflush: POSIX 7.2.2.1 */

View File

@ -52,5 +52,7 @@ ioctl (int fd, int cmd, ...)
return tcsetattr (fd, TCSAFLUSH, (struct termios *) argp);
}
return cfd->ioctl (cmd, argp);
int res = cfd->ioctl (cmd, argp);
debug_printf ("returning %d", res);
return res;
}