#include "sh.h"
RCSID("$Id: mi.termios.c,v 1.4 2000/07/04 19:38:14 christos Exp $")
#if defined(_MINIX) && !defined(_MINIX_VMD)
#undef B0
#undef B50
#undef B75
#undef B110
#undef B134
#undef B150
#undef B200
#undef B300
#undef B600
#undef B1200
#undef B1800
#undef B2400
#undef B4800
#undef B9600
#undef B19200
#undef B28800
#undef B38400
#undef B57600
#undef B115200
#undef ECHO
#define T_ECHO 000001
#include <errno.h>
#include <sgtty.h>
static _PROTOTYPE( int tc_to_sg_speed, (speed_t speed) );
static _PROTOTYPE( speed_t sg_to_tc_speed, (int speed) );
#define B19200 192
speed_t cfgetispeed(termios_p)
struct termios *termios_p;
{
return termios_p->c_ispeed;
}
speed_t cfgetospeed(termios_p)
struct termios *termios_p;
{
return termios_p->c_ospeed;
}
speed_t cfsetispeed(termios_p, speed)
struct termios *termios_p;
speed_t speed;
{
termios_p->c_ispeed = speed;
return 0;
}
speed_t cfsetospeed(termios_p, speed)
struct termios *termios_p;
speed_t speed;
{
termios_p->c_ospeed = speed;
return 0;
}
static speed_t sg_to_tc_speed(speed)
int speed;
{
switch (speed) {
case B0: return 0;
case B110: return 110;
case B200: return 200;
case B300: return 300;
case B600: return 600;
case B1200: return 1200;
case B1800: return 1800;
case B2400: return 2400;
case B4800: return 4800;
case B9600: return 9600;
case B19200: return 19200;
#ifdef B28800
case B28800: return 28800;
#endif
#ifdef B38400
case B38400: return 38400;
#endif
#ifdef B57600
case B57600: return 57600;
#endif
#ifdef B115200
case B115200: return 115200;
#endif
default: return (speed_t)-1;
}
}
static int tc_to_sg_speed(speed)
speed_t speed;
{
if (speed == 0) return 0;
if (speed == 110) return B110;
if (speed == 200) return B200;
if (speed == 300) return B300;
if (speed == 600) return B600;
if (speed == 1200) return B1200;
if (speed == 1800) return B1800;
if (speed == 2400) return B2400;
if (speed == 4800) return B4800;
if (speed == 9600) return B9600;
if (speed == 19200) return B19200;
#ifdef B28800
if (speed == 28800) return B28800;
#endif
#ifdef B38400
if (speed == 38400) return B38400;
#endif
#ifdef B57600
if (speed == 57600) return B57600;
#endif
#ifdef B115200
if (speed == 115200) return B115200;
#endif
return -1;
}
int tcgetattr(filedes, termios_p)
int filedes;
struct termios *termios_p;
{
struct sgttyb sgbuf;
struct tchars tcbuf;
if (ioctl(filedes, TIOCGETP, &sgbuf) < 0
|| ioctl(filedes, TIOCGETC, (struct sgttyb *) &tcbuf) < 0)
{
return -1;
}
termios_p->c_iflag = IGNBRK;
if (!(sgbuf.sg_flags & RAW))
{
termios_p->c_iflag |= IXON;
if (sgbuf.sg_flags & CRMOD)
{
termios_p->c_iflag |= ICRNL;
}
}
termios_p->c_oflag = sgbuf.sg_flags & (CRMOD | XTABS);
if (termios_p->c_oflag)
{
termios_p->c_oflag |= OPOST;
}
termios_p->c_lflag = 0;
if (sgbuf.sg_flags & ECHO)
{
termios_p->c_lflag |= T_ECHO | ECHOE | ECHOK;
}
if (!(sgbuf.sg_flags & RAW))
{
termios_p->c_lflag |= ISIG;
if (!(sgbuf.sg_flags & CBREAK))
{
termios_p->c_lflag |= ICANON;
}
}
termios_p->c_cflag = CLOCAL | CREAD;
switch (sgbuf.sg_flags & BITS8)
{
case BITS5: termios_p->c_cflag |= CS5; break;
case BITS6: termios_p->c_cflag |= CS6; break;
case BITS7: termios_p->c_cflag |= CS7; break;
case BITS8: termios_p->c_cflag |= CS8; break;
}
if (sgbuf.sg_flags & ODDP)
{
termios_p->c_cflag |= PARENB | PARODD;
}
if (sgbuf.sg_flags & EVENP)
{
termios_p->c_cflag |= PARENB;
}
if (sgbuf.sg_ispeed == B110)
{
termios_p->c_cflag |= CSTOPB;
}
termios_p->c_ospeed =
termios_p->c_ispeed =
sg_to_tc_speed((unsigned char) sgbuf.sg_ispeed);
termios_p->c_cc[VEOF] = tcbuf.t_eofc;
termios_p->c_cc[VEOL] = tcbuf.t_brkc;
termios_p->c_cc[VERASE] = sgbuf.sg_erase;
termios_p->c_cc[VINTR] = tcbuf.t_intrc;
termios_p->c_cc[VKILL] = sgbuf.sg_kill;
termios_p->c_cc[VQUIT] = tcbuf.t_quitc;
termios_p->c_cc[VSTART] = tcbuf.t_startc;
termios_p->c_cc[VSTOP] = tcbuf.t_stopc;
termios_p->c_cc[VMIN] = 1;
termios_p->c_cc[VTIME] = 0;
termios_p->c_cc[VSUSP] = 0;
return 0;
}
int tcsetattr(filedes, opt_actions, termios_p)
int filedes;
int opt_actions;
struct termios *termios_p;
{
struct sgttyb sgbuf;
struct tchars tcbuf;
int sgspeed;
if ((termios_p->c_ispeed != 0 && termios_p->c_ispeed != termios_p->c_ospeed)
|| (sgspeed = tc_to_sg_speed(termios_p->c_ospeed)) < 0)
{
errno = EINVAL;
return -1;
}
sgbuf.sg_ispeed = sgbuf.sg_ospeed = sgspeed;
sgbuf.sg_flags = 0;
if (termios_p->c_oflag & OPOST)
{
if (termios_p->c_oflag & XTABS)
{
sgbuf.sg_flags |= XTABS;
}
}
if (termios_p->c_iflag & ICRNL)
{
sgbuf.sg_flags |= CRMOD;
}
if (termios_p->c_lflag & T_ECHO)
{
sgbuf.sg_flags |= ECHO;
}
if (!(termios_p->c_lflag & ICANON))
{
if (termios_p->c_lflag & ISIG)
{
sgbuf.sg_flags |= CBREAK;
}
else
{
sgbuf.sg_flags |= RAW;
}
}
switch (termios_p->c_cflag & CSIZE)
{
case CS5: sgbuf.sg_flags |= BITS5; break;
case CS6: sgbuf.sg_flags |= BITS6; break;
case CS7: sgbuf.sg_flags |= BITS7; break;
case CS8: sgbuf.sg_flags |= BITS8; break;
}
if (termios_p->c_cflag & PARENB)
{
if (termios_p->c_cflag & PARODD)
{
sgbuf.sg_flags |= ODDP;
}
else
{
sgbuf.sg_flags |= EVENP;
}
}
sgbuf.sg_erase = termios_p->c_cc[VERASE];
sgbuf.sg_kill = termios_p->c_cc[VKILL];
tcbuf.t_intrc = termios_p->c_cc[VINTR];
tcbuf.t_quitc = termios_p->c_cc[VQUIT];
tcbuf.t_startc = termios_p->c_cc[VSTART];
tcbuf.t_stopc = termios_p->c_cc[VSTOP];
tcbuf.t_eofc = termios_p->c_cc[VEOF];
tcbuf.t_brkc = termios_p->c_cc[VEOL];
return ioctl(filedes, TIOCSETP, &sgbuf) < 0 &&
ioctl(filedes, TIOCSETC, (struct sgttyb *) &tcbuf) < 0 ?
-1 : 0;
}
#endif