home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 2
/
ctrom_ii_b.zip
/
ctrom_ii_b
/
OS2
/
DATACOM
/
MINCOM15
/
SYSDEP1.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-16
|
10KB
|
546 lines
/*
* This file is part of the Minicom Communications Program,
* written by Miquel van Smoorenburg 1991/1992/1993.
*
* sysdep1.c - system dependant routines.
*
* m_dtrtoggle - dropt dtr and raise it again
* m_break - send BREAK signal
* m_getdcd - get modem dcd status
* m_setdcd - set modem dcd status
* m_savestate - save modem state
* m_restorestate - restore saved modem state
* m_nohang - tell driver not to hang up at DTR drop
* m_hupcl - set hangup on close on/off (for Quit without reset)
* m_setparms - set baudrate, parity and number of bits.
* m_wait - wait for child to finish. System dependant too.
*
* If it's possible, Posix termios are preferred.
*/
#include <sys/types.h>
#if defined (_POSIX_SOURCE) || defined(_BSD43)
# include <stdlib.h>
# include <unistd.h>
#endif
#ifdef _NO_TERMIOS
# undef _POSIX_SOURCE
#endif
#ifndef _COH3
# include <sys/wait.h>
#endif
#if defined (_V7) && !defined(_POSIX_SOURCE)
# include <sgtty.h>
#endif
#if defined (_SYSV) && !defined(_POSIX_SOURCE)
# include <termio.h>
#endif
#ifdef _POSIX_SOURCE
# include <termios.h>
#endif
#ifdef _HPUX_SOURCE
# include <sys/modem.h>
#endif
#if defined(_BSD43) || defined (_SYSV)
# include <sys/ioctl.h>
#endif
#include <stdio.h>
#include <setjmp.h>
#include "window.h"
#include "minicom.h"
/* Be sure we know WEXITSTATUS and WTERMSIG */
#if !defined(_BSD43)
# ifndef WEXITSTATUS
# define WEXITSTATUS(s) (((s) >> 8) & 0377)
# endif
# ifndef WTERMSIG
# define WTERMSIG(s) ((s) & 0177)
# endif
#endif
/* Some ancient SysV systems don't define these */
#ifndef VMIN
# define VMIN 4
#endif
#ifndef VTIME
# define VTIME 5
#endif
#ifndef IUCLC
# define IUCLC 0
#endif
#ifndef IXANY
# define IXANY 0
#endif
/* Different names for the same beast. */
#ifndef TIOCMODG /* BSD 4.3 */
# ifdef TIOCMGET
# define TIOCMODG TIOCMGET /* Posix */
# else
# ifdef MCGETA
# define TIOCMODG MCGETA /* HP/UX */
# endif
# endif
#endif
#ifndef TIOCMODS
# ifdef TIOCMSET
# define TIOCMODS TIOCMSET
# else
# ifdef MCSETA
# define TIOCMODS MCSETA
# endif
# endif
#endif
#ifndef TIOCM_CAR /* BSD + Posix */
# ifdef MDCD
# define TIOCM_CAR MDCD /* HP/UX */
# endif
#endif
/* Define some thing that might not be there */
#ifndef TANDEM
# define TANDEM 0
#endif
#ifndef BITS8
# define BITS8 0
#endif
#ifndef PASS8
# ifdef LLITOUT
# define PASS8 LLITOUT
# else
# define PASS8 0
# endif
#endif
#ifndef CRTSCTS
# define CRTSCTS 0
#endif
/* If this is SysV without Posix, emulate Posix. */
#if defined(_SYSV) && !defined(_POSIX_SOURCE)
# define termio termios
# define _POSIX_SOURCE
# ifndef TCSANOW
# define TCSANOW 0
# endif
# define tcgetattr(fd, tty) ioctl(fd, TCGETA, tty)
# define tcsetattr(fd, flags, tty) ioctl(fd, TCSETA, tty)
# define tcsendbreak(fd, len) ioctl(fd, TCSBRK, 0)
# define speed_t int
# define cfsetispeed(xtty, xspd) \
((xtty)->c_cflag = ((xtty)->c_cflag & ~CBAUD) | (xspd))
# define cfsetospeed(tty, spd)
#endif
/*
* Drop DTR line and raise it again.
*/
void m_dtrtoggle(fd)
int fd;
{
#if defined (_POSIX_SOURCE) && !defined(_HPUX_SOURCE)
struct termios tty, old;
tcgetattr(fd, &tty);
tcgetattr(fd, &old);
cfsetospeed(&tty, B0);
cfsetispeed(&tty, B0);
tcsetattr(fd, TCSANOW, &tty);
sleep(1);
tcsetattr(fd, TCSANOW, &old);
#else
# ifdef _V7
# ifndef TIOCCDTR
/* Just drop speed to 0 and back to normal again */
struct sgttyb sg, ng;
ioctl(fd, TIOCGETP, &sg);
ioctl(fd, TIOCGETP, &ng);
ng.sg_ispeed = ng.sg_ospeed = 0;
ioctl(fd, TIOCSETP, &ng);
sleep(1);
ioctl(fd, TIOCSETP, &sg);
# else
/* Use the ioctls meant for this type of thing. */
ioctl(fd, TIOCCDTR, 0);
sleep(1);
ioctl(fd, TIOCSDTR, 0);
# endif
# endif
# ifdef _HPUX_SOURCE
unsigned long mflag = 0L;
ioctl(fd, MCSETAF, &mflag);
ioctl(fd, MCGETA, &mflag);
mflag = MRTS | MDTR;
sleep(1);
ioctl(fd, MCSETAF, &mflag);
# endif
#endif
}
/*
* Send a break
*/
void m_break(fd)
int fd;
{
#ifdef _POSIX_SOURCE
# ifdef linux
/* Linux kernels < .99pl8 don't support tcsendbreak() yet.. */
ioctl(fd, TCSBRK, 0);
# else
tcsendbreak(fd, 0);
# endif
#else
# ifdef _V7
# ifndef TIOCSBRK
struct sgttyb sg, ng;
ioctl(fd, TIOCGETP, &sg);
ioctl(fd, TIOCGETP, &ng);
ng.sg_ispeed = ng.sg_ospeed = B110;
ng.sg_flags = BITS8 | RAW;
ioctl(fd, TIOCSETP, &ng);
write(fd, "\0\0\0\0\0\0\0\0\0\0", 10);
ioctl(fd, TIOCSETP, &sg);
# else
ioctl(fd, TIOCSBRK, 0);
sleep(1);
ioctl(fd, TIOCCBRK, 0);
# endif
# endif
#endif
}
/*
* Get the dcd status
*/
int m_getdcd(fd)
int fd;
{
#ifdef _MINIX
struct sgttyb sg;
ioctl(fd, TIOCGETP, &sg);
return(sg.sg_flags & DCD ? 1 : 0);
#else
# ifdef TIOCMODG
int mcs;
ioctl(fd, TIOCMODG, &mcs);
return(mcs & TIOCM_CAR ? 1 : 0);
# else
return(0); /* Impossible!! */
# endif
#endif
}
/*
* Set the DCD status
*/
/*ARGSUSED*/
void m_setdcd(fd, what)
int fd, what;
{
#ifdef _MINIX
/* Just a kludge for my Minix rs 232 driver */
struct sgttyb sg;
ioctl(fd, TIOCGETP, &sg);
if (what)
sg.sg_flags |= DCD;
else
sg.sg_flags &= ~DCD;
ioctl(fd, TIOCSETP, &sg);
#endif
}
/* Variables to save states in */
#ifdef _POSIX_SOURCE
static struct termios savetty;
static int m_word;
#else
# if defined (_BSD43) || defined (_V7)
static struct sgttyb sg;
static struct tchars tch;
static int lsw;
static int m_word;
# endif
#endif
/*
* Save the state of a port
*/
void m_savestate(fd)
int fd;
{
#ifdef _POSIX_SOURCE
tcgetattr(fd, &savetty);
#else
# if defined(_BSD43) || defined(_V7)
ioctl(fd, TIOCGETP, &sg);
ioctl(fd, TIOCGETC, &tch);
# endif
# ifdef _BSD43
ioctl(fd, TIOCLGET, &lsw);
# endif
#endif
#ifdef TIOCMODG
ioctl(fd, TIOCMODG, &m_word);
#endif
}
/*
* Restore the state of a port
*/
void m_restorestate(fd)
int fd;
{
#ifdef _POSIX_SOURCE
tcsetattr(fd, TCSANOW, &savetty);
#else
# if defined(_BSD43) || defined(_V7)
ioctl(fd, TIOCSETP, &sg);
ioctl(fd, TIOCSETC, &tch);
# endif
# ifdef _BSD43
ioctl(fd, TIOCLSET, &lsw);
# endif
#endif
#ifdef TIOCMODS
ioctl(fd, TIOCMODS, &m_word);
#endif
}
/*
* Set the line status so that it will not kill our process
* if the line hangs up.
*/
/*ARGSUSED*/
void m_nohang(fd)
int fd;
{
#ifdef _POSIX_SOURCE
struct termios sgg;
tcgetattr(fd, &sgg);
sgg.c_cflag |= CLOCAL;
tcsetattr(fd, TCSANOW, &sgg);
#else
# if defined (_BSD43) && defined(LNOHANG)
int lsw;
ioctl(fd, TIOCLGET, &lsw);
lsw |= LNOHANG;
ioctl(fd, TIOCLSET, &lsw);
# endif
# ifdef _MINIX
/* So? What about 1.6 ? */
# endif
# ifdef _COHERENT
/* Doesn't know about this either, me thinks. */
# endif
#endif
}
/*
* Set hangup on close on/off.
*/
void m_hupcl(fd, on)
int fd;
int on;
{
/* Eh, I don't know how to do this under BSD (yet..) */
#ifdef _POSIX_SOURCE
struct termios sgg;
tcgetattr(fd, &sgg);
if (on)
sgg.c_cflag |= HUPCL;
else
sgg.c_cflag &= ~HUPCL;
tcsetattr(fd, TCSANOW, &sgg);
#endif
}
/*
* Flush the buffers
*/
void m_flush(fd)
int fd;
{
/* Should I Posixify this, or not? */
#ifdef TCFLSH
ioctl(fd, TCFLSH, 2);
#endif
#ifdef TIOCFLUSH
#ifdef _COHERENT
ioctl(fd, TIOCFLUSH, 0);
#else
ioctl(fd, TIOCFLUSH, (void *)0);
#endif
#endif
}
/*
* Set baudrate, parity and number of bits.
*/
void m_setparms(fd, baudr, par, bits)
int fd;
char *baudr;
char *par;
char *bits;
{
int spd = -1;
#ifdef _POSIX_SOURCE
struct termios tty;
tcgetattr(fd, &tty);
#else
struct sgttyb tty;
ioctl(fd, TIOCGETP, &tty);
#endif
switch(atoi(baudr)) {
case 0:
#ifdef B0
spd = B0; break;
#else
spd = 0; break;
#endif
case 300: spd = B300; break;
case 600: spd = B600; break;
case 1200: spd = B1200; break;
case 2400: spd = B2400; break;
case 4800: spd = B4800; break;
case 9600: spd = B9600; break;
#ifdef B19200
case 19200: spd = B19200; break;
#else
# ifdef EXTA
case 19200: spd = EXTA; break;
# else
case 19200: spd = B9600; break;
# endif
#endif
#ifdef B38400
case 38400: spd = B38400; break;
#else
# ifdef EXTA
case 38400: spd = EXTA; break;
# else
case 38400: spd = B9600; break;
# endif
#endif
}
#if defined (_BSD43) && !defined(_POSIX_SOURCE)
if (spd != -1) tty.sg_ispeed = tty.sg_ospeed = spd;
/* Number of bits is ignored */
tty.sg_flags = RAW | TANDEM;
if (par[0] == 'E')
tty.sg_flags |= EVENP;
else if (par[0] == 'O')
tty.sg_flags |= ODDP;
else
tty.sg_flags |= PASS8 | ANYP;
ioctl(fd, TIOCSETP, &tty);
# ifdef TIOCSDTR
ioctl(fd, TIOCSDTR, 0);
# endif
#endif
#if defined (_V7) && !defined(_POSIX_SOURCE)
if (spd != -1) tty.sg_ispeed = tty.sg_ospeed = spd;
#ifdef _MINIX
switch(bits[0]) {
case '5' : spd = BITS5; break;
case '6' : spd = BITS6; break;
case '7' : spd = BITS7; break;
case '8' :
default: spd = BITS8; break;
}
tty.sg_flags = RAW | spd;
#else
tty.sg_flags = RAW;
#endif
if (par[0] == 'E')
tty.sg_flags |= EVENP;
else if (par[0] == 'O')
tty.sg_flags |= ODDP;
ioctl(fd, TIOCSETP, &tty);
#endif
#ifdef _POSIX_SOURCE
cfsetospeed(&tty, (speed_t)spd);
cfsetispeed(&tty, (speed_t)spd);
switch (bits[0]) {
case '5':
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS5;
break;
case '6':
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS6;
break;
case '7':
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS7;
break;
case '8':
default:
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
break;
}
/* Set into raw, no echo mode */
tty.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | IUCLC |
IXANY | IXON | IXOFF | INPCK | ISTRIP);
tty.c_iflag |= (BRKINT | IGNPAR);
tty.c_oflag &= ~OPOST;
tty.c_lflag = ~(ICANON | ISIG | ECHO | ECHONL | ECHOE | ECHOK);
tty.c_cflag |= CREAD | CRTSCTS;
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 5;
tty.c_cflag &= ~(PARENB | PARODD);
if (par[0] == 'E')
tty.c_cflag |= PARENB;
else if (par[0] == 'O')
tty.c_cflag |= PARODD;
tcsetattr(fd, TCSANOW, &tty);
#endif
}
/*
* Wait for child and return pid + status
*/
int m_wait(stt)
int *stt;
{
#if defined (_BSD43) && !defined(_POSIX_SOURCE)
int pid;
union wait st1;
pid = wait((void *)&st1);
*stt = (unsigned)st1.w_retcode + 256 * (unsigned)st1.w_termsig;
return(pid);
#else
int pid;
int st1;
pid = wait(&st1);
*stt = (unsigned)WEXITSTATUS(st1) + 256 * (unsigned)WTERMSIG(st1);
return(pid);
#endif
}