Blame src/sysdep2.c

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, &ltchars);
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, &ltchars);
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