home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / mincom15.zip / sysdep2.c < prev    next >
C/C++ Source or Header  |  1993-09-04  |  7KB  |  340 lines

  1. /*
  2.  * This file is part of the Minicom Communications Program,
  3.  * written by Miquel van Smoorenburg 1991/1992/1993.
  4.  *
  5.  * sysdep2.c - system dependant routines
  6.  *
  7.  * getrowcols    - get number of columns and rows from the environment.
  8.  * setcbreak    - set tty mode to raw, cbreak or normal.
  9.  * enab_sig    - enable / disable tty driver signals.
  10.  * strtok    - for systems that don't have it.
  11.  * dup2        - for ancient systems like SVR2.
  12.  */
  13. #include <sys/types.h>
  14. #if defined (_POSIX_SOURCE) || defined(_BSD43)
  15. #  include <stdlib.h>
  16. #  include <unistd.h>
  17. #else
  18. extern char *getenv();
  19. #endif
  20. #ifdef _NO_TERMIOS
  21. #  undef _POSIX_SOURCE
  22. #endif
  23. #if defined (_V7) && !defined(_POSIX_SOURCE)
  24. #  include <sgtty.h>
  25. #endif
  26. #if defined (_SYSV) && !defined(_POSIX_SOURCE)
  27. #  include <termio.h>
  28. #endif
  29. #ifdef _POSIX_SOURCE
  30. #  include <termios.h>
  31. #endif
  32. #if defined(_BSD43) || defined (_SYSV)
  33. #  include <sys/ioctl.h>
  34. #endif
  35.  
  36. /* Some ancient SysV systems don't define these */
  37. #ifndef VMIN
  38. #  define VMIN 4
  39. #endif
  40. #ifndef VTIME
  41. #  define VTIME 5
  42. #endif
  43. #ifndef IUCLC
  44. #  define IUCLC 0
  45. #endif
  46. #ifndef IXANY
  47. #  define IXANY 0
  48. #endif
  49.  
  50. /* If this is SysV without Posix, emulate Posix. */
  51. #if defined(_SYSV) && !defined(_POSIX_SOURCE)
  52. #  define termio termios
  53. #  define _POSIX_SOURCE
  54. #  ifndef TCSANOW
  55. #    define TCSANOW   0
  56. #    define TCSADRAIN 1
  57. #  endif
  58. #  define tcgetattr(fd, tty)        ioctl(fd, TCGETA, tty)
  59. #  define tcsetattr(fd, flags, tty) ioctl(fd, \
  60.                     (flags == TCSANOW) ? TCSETA : TCSETAW, tty)
  61. #  define tcsendbreak(fd, len)      ioctl(fd, TCSBRK, 0)
  62. #endif
  63.  
  64. /* Get the number of rows and columns for this screen. */
  65. void getrowcols(rows, cols)
  66. int *rows;
  67. int *cols;
  68. {
  69. #ifdef TIOCGWINSZ
  70.     struct winsize ws;
  71.  
  72.     if (ioctl(0, TIOCGWINSZ, &ws) < 0) {
  73.         *rows = 0;
  74.         *cols = 0;
  75.     } else {
  76.         *rows = ws.ws_row;
  77.         *cols = ws.ws_col;
  78.     }    
  79. #else
  80. #  ifdef TIOCGSIZE
  81.     struct ttysize ws;
  82.  
  83.     if (ioctl(0, TIOCGSIZE, &ws) < 0) {
  84.         *rows = 0;
  85.         *cols = 0;
  86.     } else {
  87.         *rows = ws.ts_lines;
  88.         *cols = ws.ts_cols;
  89.     }
  90. #  else
  91.     char *p, *getenv();
  92.  
  93.     if (p = getenv("LINES"))
  94.         *rows = atoi(p);
  95.     else
  96.         *rows = 0;
  97.     if (p = getenv("COLUMNS"))
  98.         *cols = atoi(p);
  99.     else
  100.         *cols = 0;
  101. #  endif
  102. #endif    
  103. }
  104.  
  105. /*
  106.  * Set cbreak mode.
  107.  * Mode 0 = normal.
  108.  * Mode 1 = cbreak, no echo
  109.  * Mode 2 = raw, no echo.
  110.  * Mode 3 = only return erasechar (for wkeys.c)
  111.  *
  112.  * Returns: the current erase character.
  113.  */  
  114. int setcbreak(mode)
  115. int mode;
  116. {
  117. #ifdef _POSIX_SOURCE
  118.   struct termios tty;
  119.   static int init = 0;
  120.   static int erasechar;
  121.   static struct termios saveterm;
  122. #ifdef _HPUX_SOURCE
  123.   static int lastmode = -1;
  124. #endif
  125.  
  126. #ifndef XCASE
  127. #  ifdef _XCASE
  128. #    define XCASE _XCASE
  129. #  else
  130. #    define XCASE 0
  131. #  endif
  132. #endif
  133.  
  134.   if (init == 0) {
  135.     tcgetattr(0, &saveterm);
  136.     erasechar = saveterm.c_cc[VERASE];
  137.     init++;
  138.   }
  139.  
  140.   if (mode == 3) return(erasechar);
  141.  
  142. #ifdef _HPUX_SOURCE
  143.   /* In HP/UX, TCSADRAIN does not work for me. So we use only RAW
  144.    * or NORMAL mode, so we never have to switch from cbreak <--> raw
  145.    */
  146.   if (mode == 1) mode = 2;
  147. #endif
  148.  
  149.   /* Avoid overhead */
  150. #ifdef _HPUX_SOURCE
  151.   if (mode == lastmode) return(erasechar);
  152.   lastmode = mode;
  153. #endif
  154.  
  155.   /* Always return to default settings first */
  156.   tcsetattr(0, TCSADRAIN, &saveterm);
  157.  
  158.   if (mode == 0) {
  159.       return(erasechar);
  160.   }
  161.  
  162.   tcgetattr(0, &tty);
  163.   if (mode == 1) {
  164.     tty.c_oflag &= ~OPOST;
  165.     tty.c_lflag &= ~(XCASE|ECHONL|NOFLSH);
  166.       tty.c_lflag &= ~(ICANON | ISIG | ECHO);
  167.     tty.c_iflag &= ~(ICRNL|INLCR);
  168.       tty.c_cflag |= CREAD;
  169.       tty.c_cc[VTIME] = 5;
  170.       tty.c_cc[VMIN] = 1;
  171.   }
  172.   if (mode == 2) { /* raw */
  173.       tty.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | IUCLC | 
  174.           IXANY | IXON | IXOFF | INPCK | ISTRIP);
  175.       tty.c_iflag |= (BRKINT | IGNPAR);
  176.     tty.c_oflag &= ~OPOST;
  177.     tty.c_lflag &= ~(XCASE|ECHONL|NOFLSH);
  178.       tty.c_lflag &= ~(ICANON | ISIG | ECHO);
  179.       tty.c_cflag |= CREAD;
  180.       tty.c_cc[VTIME] = 5;
  181.       tty.c_cc[VMIN] = 1;
  182.   }    
  183.   tcsetattr(0, TCSADRAIN, &tty);
  184.   return(erasechar);
  185. #else
  186.   struct sgttyb args;
  187.   static int init = 0;
  188.   static int erasechar;
  189.   static struct sgttyb sgttyb;
  190.   static struct tchars tchars;
  191. #ifdef _BSD43  
  192.   static struct ltchars ltchars;
  193. #endif
  194.   
  195.   if (init == 0) {
  196.     (void) ioctl(0, TIOCGETP, &sgttyb);
  197.     (void) ioctl(0, TIOCGETC, &tchars);
  198. #ifdef _BSD43
  199.     (void) ioctl(0, TIOCGLTC, <chars);
  200. #endif
  201.     erasechar = sgttyb.sg_erase;
  202.     init++;
  203.   }
  204.  
  205.   if (mode == 3) return(erasechar);
  206.  
  207.   if (mode == 0) {
  208.       (void) ioctl(0, TIOCSETP, &sgttyb);
  209.     (void) ioctl(0, TIOCSETC, &tchars);
  210. #ifdef _BSD43
  211.     (void) ioctl(0, TIOCSLTC, <chars);
  212. #endif
  213.       return(erasechar);
  214.   }
  215.  
  216.   (void) ioctl(0, TIOCGETP, &args);
  217.   if (mode == 1) {
  218.     args.sg_flags |= CBREAK;
  219.     args.sg_flags &= ~(ECHO|RAW);
  220.   }
  221.   if (mode == 2) {
  222.       args.sg_flags |= RAW;
  223.       args.sg_flags &= ~(ECHO|CBREAK);
  224.   }
  225.   (void) ioctl(0, TIOCSETP, &args);
  226.   return(erasechar);
  227. #endif
  228.  
  229. }
  230.  
  231. /* Enable / disable signals from tty driver */
  232. void enab_sig(onoff)
  233. int onoff;
  234. {
  235. #ifdef _POSIX_SOURCE
  236.   struct termios tty;
  237.   
  238.   tcgetattr(0, &tty);
  239.   if (onoff)
  240.     tty.c_lflag |= ISIG;
  241.   else
  242.     tty.c_lflag &= ~ISIG;
  243.   tcsetattr(0, TCSADRAIN, &tty);
  244. #endif
  245. }
  246.  
  247. #if 0
  248. /*
  249.  * strtok taken from the Minix library - I suppose this one's PD.
  250.  *
  251.  * Get next token from string s (NULL on 2nd, 3rd, etc. calls),
  252.  * where tokens are nonempty strings separated by runs of
  253.  * chars from delim.  Writes NULs into s to end tokens.  delim need not
  254.  * remain constant from call to call.
  255.  */
  256.  
  257. char *strtok(s, delim)        /* NULL if no token left */
  258. char *s;
  259. register char *delim;
  260. {
  261.   register char *scan;
  262.   char *tok;
  263.   register char *dscan;
  264.  
  265.   if (s == (char *)0 && scanpoint == (char *)0) return((char *)0);
  266.   if (s != (char *)0)
  267.     scan = s;
  268.   else
  269.     scan = scanpoint;
  270.  
  271.   /* Scan leading delimiters. */
  272.   for (; *scan != '\0'; scan++) {
  273.     for (dscan = delim; *dscan != '\0'; dscan++)
  274.         if (*scan == *dscan) break;
  275.     if (*dscan == '\0') break;
  276.   }
  277.   if (*scan == '\0') {
  278.     scanpoint = (char *)0;
  279.     return((char *)0);
  280.   }
  281.   tok = scan;
  282.  
  283.   /* Scan token. */
  284.   for (; *scan != '\0'; scan++) {
  285.     for (dscan = delim; *dscan != '\0';)    /* ++ moved down. */
  286.         if (*scan == *dscan++) {
  287.             scanpoint = scan + 1;
  288.             *scan = '\0';
  289.             return(tok);
  290.         }
  291.   }
  292.  
  293.   /* Reached end of string. */
  294.   scanpoint = (char *)0;
  295.   return(tok);
  296. }
  297. #endif
  298.  
  299. #ifdef _SVR2
  300. /* Fake the dup2() system call */
  301. int dup2(from, to)
  302. int from, to;
  303. {
  304.   int files[20];
  305.   int n, f, exstat = -1;
  306.   extern int errno;
  307.  
  308.   /* Ignore if the same */
  309.   if (from == to) return(to);
  310.  
  311.   /* Initialize file descriptor table */
  312.   for(f = 0; f < 20; f++) files[f] = 0;
  313.  
  314.   /* Close "to" file descriptor, if open */
  315.   close(to);
  316.  
  317.   /* Keep opening files until we reach "to" */
  318.   while((n = open("/dev/null", 0)) < to && n >= 0) {
  319.       if (n == from) break;
  320.       files[n] = 1;
  321.   }
  322.   if (n == to) {
  323.       /* Close "to" again, and perform dup() */
  324.       close(n);
  325.       exstat = dup(from);
  326.   } else {
  327.       /* We failed. Set exit status and errno. */
  328.       if (n > 0) close(n);
  329.       exstat = -1;
  330.       errno = EBADF;
  331.   }
  332.   /* Close all temporarily opened file descriptors */
  333.   for(f = 0; f < 20; f++) if (files[f]) close(f);
  334.  
  335.   /* We're done. */
  336.   return(exstat);
  337. }
  338. #endif
  339.  
  340.