sysdep2.c
上传用户:tianjinjs
上传日期:2007-01-05
资源大小:309k
文件大小:6k
源码类别:

Modem编程

开发平台:

Unix_Linux

  1. /*
  2.  * sysdep2.c System dependant routines
  3.  *
  4.  * getrowcols - get number of columns and rows.
  5.  * setcbreak - set tty mode to raw, cbreak or normal.
  6.  * enab_sig - enable / disable tty driver signals.
  7.  * strtok - for systems that don't have it.
  8.  * dup2 - for ancient systems like SVR2.
  9.  *
  10.  * This file is part of the minicom communications package,
  11.  * Copyright 1991-1995 Miquel van Smoorenburg.
  12.  *
  13.  * This program is free software; you can redistribute it and/or
  14.  * modify it under the terms of the GNU General Public License
  15.  * as published by the Free Software Foundation; either version
  16.  * 2 of the License, or (at your option) any later version.
  17.  */
  18. #include "sysdep.h"
  19. #ifdef _POSIX
  20. static struct termios savetty;
  21. #else
  22. static struct sgttyb savetty;
  23. static struct tchars savetty2;
  24. #endif
  25. /* Get the number of rows and columns for this screen. */
  26. void getrowcols(rows, cols)
  27. int *rows;
  28. int *cols;
  29. {
  30. char *p, *getenv();
  31. #ifdef TIOCGWINSZ
  32. struct winsize ws;
  33. if (ioctl(0, TIOCGWINSZ, &ws) >= 0) {
  34. *rows = ws.ws_row;
  35. *cols = ws.ws_col;
  36. }
  37. #else
  38. #  ifdef TIOCGSIZE
  39. struct ttysize ws;
  40. if (ioctl(0, TIOCGSIZE, &ws) >= 0) {
  41. *rows = ws.ts_lines;
  42. *cols = ws.ts_cols;
  43. }
  44. #  endif
  45. #endif
  46. /* An extra check here because eg. SCO does have TIOCGWINSZ
  47.  * defined but the support is not in the kernel (ioctl
  48.  * returns -1. Yeah :-(
  49.  */
  50. if (*rows == 0 && (p = getenv("LINES")) != NULL)
  51. *rows = atoi(p);
  52. if (*cols == 0 && (p = getenv("COLUMNS")) != NULL)
  53. *cols = atoi(p);
  54. }
  55. /*
  56.  * Set cbreak mode.
  57.  * Mode 0 = normal.
  58.  * Mode 1 = cbreak, no echo
  59.  * Mode 2 = raw, no echo.
  60.  * Mode 3 = only return erasechar (for wkeys.c)
  61.  *
  62.  * Returns: the current erase character.
  63.  */  
  64. int setcbreak(mode)
  65. int mode;
  66. {
  67. #ifdef _POSIX
  68.   struct termios tty;
  69.   static int init = 0;
  70.   static int erasechar;
  71. #ifdef _HPUX_SOURCE
  72.   static int lastmode = -1;
  73. #endif
  74. #ifndef XCASE
  75. #  ifdef _XCASE
  76. #    define XCASE _XCASE
  77. #  else
  78. #    define XCASE 0
  79. #  endif
  80. #endif
  81.   if (init == 0) {
  82. tcgetattr(0, &savetty);
  83. erasechar = savetty.c_cc[VERASE];
  84. init++;
  85.   }
  86.   if (mode == 3) return(erasechar);
  87. #ifdef _HPUX_SOURCE
  88.   /* In HP/UX, TCSADRAIN does not work for me. So we use only RAW
  89.    * or NORMAL mode, so we never have to switch from cbreak <--> raw
  90.    */
  91.   if (mode == 1) mode = 2;
  92. #endif
  93.   /* Avoid overhead */
  94. #ifdef _HPUX_SOURCE
  95.   if (mode == lastmode) return(erasechar);
  96.   lastmode = mode;
  97. #endif
  98.   /* Always return to default settings first */
  99.   tcsetattr(0, TCSADRAIN, &savetty);
  100.   if (mode == 0) {
  101.    return(erasechar);
  102.   }
  103.   tcgetattr(0, &tty);
  104.   if (mode == 1) {
  105. tty.c_oflag &= ~OPOST;
  106. tty.c_lflag &= ~(XCASE|ECHONL|NOFLSH);
  107.    tty.c_lflag &= ~(ICANON | ISIG | ECHO);
  108. tty.c_iflag &= ~(ICRNL|INLCR);
  109.    tty.c_cflag |= CREAD;
  110.    tty.c_cc[VTIME] = 5;
  111.    tty.c_cc[VMIN] = 1;
  112.   }
  113.   if (mode == 2) { /* raw */
  114.    tty.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | IUCLC | 
  115.    IXANY | IXON | IXOFF | INPCK | ISTRIP);
  116.    tty.c_iflag |= (BRKINT | IGNPAR);
  117. tty.c_oflag &= ~OPOST;
  118. tty.c_lflag &= ~(XCASE|ECHONL|NOFLSH);
  119.    tty.c_lflag &= ~(ICANON | ISIG | ECHO);
  120.    tty.c_cflag |= CREAD;
  121.    tty.c_cc[VTIME] = 5;
  122.    tty.c_cc[VMIN] = 1;
  123.   }
  124.   tcsetattr(0, TCSADRAIN, &tty);
  125.   return(erasechar);
  126. #else
  127.   struct sgttyb args;
  128.   static int init = 0;
  129.   static int erasechar;
  130. #ifdef _BSD43  
  131.   static struct ltchars ltchars;
  132. #endif
  133.   
  134.   if (init == 0) {
  135. (void) ioctl(0, TIOCGETP, &savetty);
  136. (void) ioctl(0, TIOCGETC, &savetty2);
  137. #ifdef _BSD43
  138. (void) ioctl(0, TIOCGLTC, &ltchars);
  139. #endif
  140. erasechar = savetty.sg_erase;
  141. init++;
  142.   }
  143.   if (mode == 3) return(erasechar);
  144.   if (mode == 0) {
  145.    (void) ioctl(0, TIOCSETP, &savetty);
  146. (void) ioctl(0, TIOCSETC, &savetty2);
  147. #ifdef _BSD43
  148. (void) ioctl(0, TIOCSLTC, &ltchars);
  149. #endif
  150.    return(erasechar);
  151.   }
  152.   (void) ioctl(0, TIOCGETP, &args);
  153.   if (mode == 1) {
  154. args.sg_flags |= CBREAK;
  155. args.sg_flags &= ~(ECHO|RAW);
  156.   }
  157.   if (mode == 2) {
  158.    args.sg_flags |= RAW;
  159.    args.sg_flags &= ~(ECHO|CBREAK);
  160.   }
  161.   (void) ioctl(0, TIOCSETP, &args);
  162.   return(erasechar);
  163. #endif
  164. }
  165. /* Enable / disable signals from tty driver */
  166. void enab_sig(onoff, intchar)
  167. int onoff;
  168. int intchar;
  169. {
  170. #ifdef _POSIX
  171.   struct termios tty;
  172.   
  173.   (void) tcgetattr(0, &tty);
  174.   if (onoff)
  175. tty.c_lflag |= ISIG;
  176.   else
  177. tty.c_lflag &= ~ISIG;
  178.   /* Set interrupt etc. characters: Zmodem support. */
  179.   if (onoff && intchar) {
  180. tty.c_cc[VINTR] = intchar;
  181. tty.c_cc[VQUIT] = -1;
  182. #ifdef VSUSP
  183. tty.c_cc[VSUSP] = -1;
  184. #endif
  185.   }
  186.   (void) tcsetattr(0, TCSADRAIN, &tty);
  187. #endif
  188. #ifdef _V7
  189.   struct tchars tch;
  190.   struct sgttyb sg;
  191.   (void) ioctl(0, TIOCGETP, &sg);
  192.   (void) ioctl(0, TIOCGETC, &tch);
  193.   if (onoff) {
  194. sg.sg_flags &= ~RAW;
  195. sg.sg_flags |= CBREAK;
  196.   } else {
  197. sg.sg_flags &= ~CBREAK;
  198. sg.sg_flags |= RAW;
  199.   }
  200.   if (onoff && intchar) {
  201. tch.t_intrc = intchar;
  202. tch.t_quitc = -1;
  203.   }
  204.   (void) ioctl(0, TIOCSETP, &sg);
  205.   (void) ioctl(0, TIOCSETC, &tch);
  206. #endif
  207. }
  208. #ifdef _SVR2
  209. /* Fake the dup2() system call */
  210. int dup2(from, to)
  211. int from, to;
  212. {
  213.   int files[20];
  214.   int n, f, exstat = -1;
  215.   extern int errno;
  216.   /* Ignore if the same */
  217.   if (from == to) return(to);
  218.   /* Initialize file descriptor table */
  219.   for(f = 0; f < 20; f++) files[f] = 0;
  220.   /* Close "to" file descriptor, if open */
  221.   close(to);
  222.   /* Keep opening files until we reach "to" */
  223.   while((n = open("/dev/null", 0)) < to && n >= 0) {
  224.    if (n == from) break;
  225.    files[n] = 1;
  226.   }
  227.   if (n == to) {
  228.    /* Close "to" again, and perform dup() */
  229.    close(n);
  230.    exstat = dup(from);
  231.   } else {
  232.    /* We failed. Set exit status and errno. */
  233.    if (n > 0) close(n);
  234.    exstat = -1;
  235.    errno = EBADF;
  236.   }
  237.   /* Close all temporarily opened file descriptors */
  238.   for(f = 0; f < 20; f++) if (files[f]) close(f);
  239.   /* We're done. */
  240.   return(exstat);
  241. }
  242. #endif