|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* sysdep2.c System dependant routines
|
|
Packit |
15a96c |
*
|
|
Packit |
15a96c |
* getrowcols - get number of columns and rows.
|
|
Packit |
15a96c |
* setcbreak - set tty mode to raw, cbreak or normal.
|
|
Packit |
15a96c |
* enab_sig - enable / disable tty driver signals.
|
|
Packit |
15a96c |
* strtok - for systems that don't have it.
|
|
Packit |
15a96c |
* dup2 - for ancient systems like SVR2.
|
|
Packit |
15a96c |
*
|
|
Packit |
15a96c |
* This file is part of the minicom communications package,
|
|
Packit |
15a96c |
* Copyright 1991-1995 Miquel van Smoorenburg.
|
|
Packit |
15a96c |
*
|
|
Packit |
15a96c |
* This program is free software; you can redistribute it and/or
|
|
Packit |
15a96c |
* modify it under the terms of the GNU General Public License
|
|
Packit |
15a96c |
* as published by the Free Software Foundation; either version
|
|
Packit |
15a96c |
* 2 of the License, or (at your option) any later version.
|
|
Packit |
15a96c |
*
|
|
Packit |
15a96c |
* You should have received a copy of the GNU General Public License along
|
|
Packit |
15a96c |
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
Packit |
15a96c |
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
#ifdef HAVE_CONFIG_H
|
|
Packit |
15a96c |
#include <config.h>
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
#include "port.h"
|
|
Packit |
15a96c |
#include "sysdep.h"
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
#ifdef POSIX_TERMIOS
|
|
Packit |
15a96c |
static struct termios savetty;
|
|
Packit |
15a96c |
#else
|
|
Packit |
15a96c |
static struct sgttyb savetty;
|
|
Packit |
15a96c |
static struct tchars savetty2;
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Get the number of rows and columns for this screen. */
|
|
Packit |
15a96c |
void getrowcols(int *rows, int *cols)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
char *p;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
#ifdef TIOCGWINSZ
|
|
Packit |
15a96c |
struct winsize ws;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
if (ioctl(0, TIOCGWINSZ, &ws) >= 0) {
|
|
Packit |
15a96c |
*rows = ws.ws_row;
|
|
Packit |
15a96c |
*cols = ws.ws_col;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
#else
|
|
Packit |
15a96c |
# ifdef TIOCGSIZE
|
|
Packit |
15a96c |
struct ttysize ws;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
if (ioctl(0, TIOCGSIZE, &ws) >= 0) {
|
|
Packit |
15a96c |
*rows = ws.ts_lines;
|
|
Packit |
15a96c |
*cols = ws.ts_cols;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
# endif
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
/* An extra check here because eg. SCO does have TIOCGWINSZ
|
|
Packit |
15a96c |
* defined but the support is not in the kernel (ioctl
|
|
Packit |
15a96c |
* returns -1. Yeah :-(
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
if (*rows == 0 && (p = getenv("LINES")) != NULL)
|
|
Packit |
15a96c |
*rows = atoi(p);
|
|
Packit |
15a96c |
if (*cols == 0 && (p = getenv("COLUMNS")) != NULL)
|
|
Packit |
15a96c |
*cols = atoi(p);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* Set cbreak mode.
|
|
Packit |
15a96c |
* Mode 0 = normal.
|
|
Packit |
15a96c |
* Mode 1 = cbreak, no echo
|
|
Packit |
15a96c |
* Mode 2 = raw, no echo.
|
|
Packit |
15a96c |
* Mode 3 = only return erasechar (for wkeys.c)
|
|
Packit |
15a96c |
*
|
|
Packit |
15a96c |
* Returns: the current erase character.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
int setcbreak(int mode)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
#ifdef POSIX_TERMIOS
|
|
Packit |
15a96c |
struct termios tty;
|
|
Packit |
15a96c |
static int init = 0;
|
|
Packit |
15a96c |
static int erasechar;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
#ifndef XCASE
|
|
Packit |
15a96c |
# ifdef _XCASE
|
|
Packit |
15a96c |
# define XCASE _XCASE
|
|
Packit |
15a96c |
# else
|
|
Packit |
15a96c |
# define XCASE 0
|
|
Packit |
15a96c |
# endif
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
if (init == 0) {
|
|
Packit |
15a96c |
tcgetattr(0, &savetty);
|
|
Packit |
15a96c |
erasechar = savetty.c_cc[VERASE];
|
|
Packit |
15a96c |
init++;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
if (mode == 3)
|
|
Packit |
15a96c |
return erasechar;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Always return to default settings first */
|
|
Packit |
15a96c |
tcsetattr(0, TCSADRAIN, &savetty);
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
if (mode == 0) {
|
|
Packit |
15a96c |
return erasechar;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
tcgetattr(0, &tty);
|
|
Packit |
15a96c |
if (mode == 1) {
|
|
Packit |
15a96c |
tty.c_oflag &= ~OPOST;
|
|
Packit |
15a96c |
tty.c_lflag &= ~(XCASE|ECHONL|NOFLSH);
|
|
Packit |
15a96c |
tty.c_lflag &= ~(ICANON | ISIG | ECHO);
|
|
Packit |
15a96c |
tty.c_iflag &= ~(ICRNL|INLCR);
|
|
Packit |
15a96c |
tty.c_cflag |= CREAD;
|
|
Packit |
15a96c |
tty.c_cc[VTIME] = 5;
|
|
Packit |
15a96c |
tty.c_cc[VMIN] = 1;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (mode == 2) { /* raw */
|
|
Packit |
15a96c |
tty.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | IUCLC |
|
|
Packit |
15a96c |
IXANY | IXON | IXOFF | INPCK | ISTRIP);
|
|
Packit |
15a96c |
tty.c_iflag |= (BRKINT | IGNPAR);
|
|
Packit |
15a96c |
tty.c_oflag &= ~OPOST;
|
|
Packit |
15a96c |
tty.c_lflag &= ~(XCASE|ECHONL|NOFLSH);
|
|
Packit |
15a96c |
tty.c_lflag &= ~(ICANON | ISIG | ECHO);
|
|
Packit |
15a96c |
tty.c_cflag |= CREAD;
|
|
Packit |
15a96c |
tty.c_cc[VTIME] = 5;
|
|
Packit |
15a96c |
tty.c_cc[VMIN] = 1;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
tcsetattr(0, TCSADRAIN, &tty);
|
|
Packit |
15a96c |
return erasechar;
|
|
Packit |
15a96c |
#else
|
|
Packit |
15a96c |
struct sgttyb args;
|
|
Packit |
15a96c |
static int init = 0;
|
|
Packit |
15a96c |
static int erasechar;
|
|
Packit |
15a96c |
#ifdef _BSD43
|
|
Packit |
15a96c |
static struct ltchars ltchars;
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
if (init == 0) {
|
|
Packit |
15a96c |
ioctl(0, TIOCGETP, &savetty);
|
|
Packit |
15a96c |
ioctl(0, TIOCGETC, &savetty2);
|
|
Packit |
15a96c |
#ifdef _BSD43
|
|
Packit |
15a96c |
ioctl(0, TIOCGLTC, <chars);
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
erasechar = savetty.sg_erase;
|
|
Packit |
15a96c |
init++;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
if (mode == 3)
|
|
Packit |
15a96c |
return erasechar;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
if (mode == 0) {
|
|
Packit |
15a96c |
ioctl(0, TIOCSETP, &savetty);
|
|
Packit |
15a96c |
ioctl(0, TIOCSETC, &savetty2);
|
|
Packit |
15a96c |
#ifdef _BSD43
|
|
Packit |
15a96c |
ioctl(0, TIOCSLTC, <chars);
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
return erasechar;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
ioctl(0, TIOCGETP, &args);
|
|
Packit |
15a96c |
if (mode == 1) {
|
|
Packit |
15a96c |
args.sg_flags |= CBREAK;
|
|
Packit |
15a96c |
args.sg_flags &= ~(ECHO|RAW);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (mode == 2) {
|
|
Packit |
15a96c |
args.sg_flags |= RAW;
|
|
Packit |
15a96c |
args.sg_flags &= ~(ECHO|CBREAK);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
ioctl(0, TIOCSETP, &args);
|
|
Packit |
15a96c |
return erasechar;
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Enable / disable signals from tty driver */
|
|
Packit |
15a96c |
void enab_sig(int onoff, int intchar)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
#ifdef POSIX_TERMIOS
|
|
Packit |
15a96c |
struct termios tty;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
tcgetattr(0, &tty);
|
|
Packit |
15a96c |
if (onoff)
|
|
Packit |
15a96c |
tty.c_lflag |= ISIG;
|
|
Packit |
15a96c |
else
|
|
Packit |
15a96c |
tty.c_lflag &= ~ISIG;
|
|
Packit |
15a96c |
/* Set interrupt etc. characters: Zmodem support. */
|
|
Packit |
15a96c |
if (onoff && intchar) {
|
|
Packit |
15a96c |
tty.c_cc[VINTR] = intchar;
|
|
Packit |
15a96c |
tty.c_cc[VQUIT] = -1;
|
|
Packit |
15a96c |
#ifdef VSUSP
|
|
Packit |
15a96c |
tty.c_cc[VSUSP] = -1;
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
tcsetattr(0, TCSADRAIN, &tty);
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
#ifdef _V7
|
|
Packit |
15a96c |
struct tchars tch;
|
|
Packit |
15a96c |
struct sgttyb sg;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
ioctl(0, TIOCGETP, &sg;;
|
|
Packit |
15a96c |
ioctl(0, TIOCGETC, &tch;;
|
|
Packit |
15a96c |
if (onoff) {
|
|
Packit |
15a96c |
sg.sg_flags &= ~RAW;
|
|
Packit |
15a96c |
sg.sg_flags |= CBREAK;
|
|
Packit |
15a96c |
} else {
|
|
Packit |
15a96c |
sg.sg_flags &= ~CBREAK;
|
|
Packit |
15a96c |
sg.sg_flags |= RAW;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (onoff && intchar) {
|
|
Packit |
15a96c |
tch.t_intrc = intchar;
|
|
Packit |
15a96c |
tch.t_quitc = -1;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
ioctl(0, TIOCSETP, &sg;;
|
|
Packit |
15a96c |
ioctl(0, TIOCSETC, &tch;;
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
#ifdef _SVR2
|
|
Packit |
15a96c |
/* Fake the dup2() system call */
|
|
Packit |
15a96c |
int dup2(int from, int to)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
int files[20];
|
|
Packit |
15a96c |
int n, f, exstat = -1;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Ignore if the same */
|
|
Packit |
15a96c |
if (from == to)
|
|
Packit |
15a96c |
return to;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Initialize file descriptor table */
|
|
Packit |
15a96c |
for (f = 0; f < 20; f++)
|
|
Packit |
15a96c |
files[f] = 0;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Close "to" file descriptor, if open */
|
|
Packit |
15a96c |
close(to);
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Keep opening files until we reach "to" */
|
|
Packit |
15a96c |
while ((n = open("/dev/null", 0)) < to && n >= 0) {
|
|
Packit |
15a96c |
if (n == from)
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
files[n] = 1;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (n == to) {
|
|
Packit |
15a96c |
/* Close "to" again, and perform dup() */
|
|
Packit |
15a96c |
close(n);
|
|
Packit |
15a96c |
exstat = dup(from);
|
|
Packit |
15a96c |
} else {
|
|
Packit |
15a96c |
/* We failed. Set exit status and errno. */
|
|
Packit |
15a96c |
if (n > 0)
|
|
Packit |
15a96c |
close(n);
|
|
Packit |
15a96c |
exstat = -1;
|
|
Packit |
15a96c |
errno = EBADF;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
/* Close all temporarily opened file descriptors */
|
|
Packit |
15a96c |
for (f = 0; f < 20; f++)
|
|
Packit |
15a96c |
if (files[f])
|
|
Packit |
15a96c |
close(f);
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* We're done. */
|
|
Packit |
15a96c |
return exstat;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
#endif
|