home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 313_01 / unix.c < prev    next >
C/C++ Source or Header  |  1990-04-22  |  6KB  |  375 lines

  1. /* $Header: /nw2/tony/src/stevie/src/RCS/unix.c,v 1.9 89/08/31 10:03:09 tony Exp $
  2.  *
  3.  * System-dependent routines for UNIX System V or Berkeley.
  4.  */
  5.  
  6. #include "stevie.h"
  7.  
  8. #ifdef    TERMCAP
  9. extern    int    ospeed;
  10. #endif
  11.  
  12. #ifdef BSD
  13.  
  14. /*
  15.  * We have to dork around here to avoid name space pollution on some
  16.  * systems that define their own version of CTRL within standard
  17.  * header files.
  18.  */
  19. #undef    CTRL
  20. #include <sgtty.h>
  21. #include <sys/time.h>
  22. #undef    CTRL
  23. #define    CTRL(x)    ((x) & 0x1f)
  24.  
  25. #else
  26. #include <termio.h>
  27. #endif
  28.  
  29. #include <signal.h>
  30.  
  31. #ifdef    BSD
  32. bool_t    got_stop = FALSE;    /* for job control */
  33. #endif
  34.  
  35. /*
  36.  * inchar() - get a character from the keyboard
  37.  */
  38. int
  39. inchar()
  40. {
  41.     char    c;
  42. #ifdef    BSD
  43.     void    set_tty(), reset_tty(), tsig();
  44.     int    rv;
  45.     int    rfds;
  46. #endif
  47.  
  48.     flushbuf();        /* flush any pending output */
  49.  
  50.     do {
  51. #ifdef    BSD
  52.         /*
  53.          * Much of the following deals with job control issues.
  54.          * If the editor has received a stop signal, it resets
  55.          * tty modes, puts the cursor at the bottom of the screen,
  56.          * and suspends itself. When execution resumes, the modes
  57.          * are restored and the screen is redrawn.
  58.          *
  59.          * The select call below is used because an interrupted
  60.          * read is restarted after the stop signal is received. To
  61.          * avoid this problem, we use select instead which will
  62.          * return -1 (with errno == EINTR) if a signal is received.
  63.          */
  64.         do {
  65.             if (got_stop) {
  66.                 msg("");
  67.                 reset_tty();
  68.                 signal(SIGTSTP, SIG_DFL);
  69.                 kill(getpid(), SIGTSTP);
  70.  
  71.                 /* process stops here */
  72.  
  73.                 set_tty();
  74.                 signal(SIGTSTP, tsig);
  75.                 screenclear();
  76.                 updatescreen();
  77.                 windgoto(Cursrow, Curscol);
  78.                 flushbuf();
  79.                 got_stop = FALSE;
  80.             }
  81.             rfds = 1;    /* wait for input from stdin */
  82.             rv=select(32,&rfds,(int*)0,(int*)0,(struct timeval*)0);
  83.             if (rv == 1 && rfds == 1)
  84.                 rv = read(0, &c, 1);
  85.         } while (rv != 1);
  86. #else
  87.         while (read(0, &c, 1) != 1)
  88.             ;
  89. #endif
  90.     } while (c == NUL);
  91.  
  92.     got_int = FALSE;
  93.     return c;
  94. }
  95.  
  96. #define    BSIZE    2048
  97. static    char    outbuf[BSIZE];
  98. static    int    bpos = 0;
  99.  
  100. void
  101. flushbuf()
  102. {
  103.     if (bpos != 0)
  104.         write(1, outbuf, bpos);
  105.     bpos = 0;
  106. }
  107.  
  108. /*
  109.  * Macro to output a character. Used within this file for speed.
  110.  */
  111. #define    outone(c)    outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf()
  112.  
  113. /*
  114.  * Function version for use outside this file.
  115.  */
  116. void
  117. outchar(c)
  118. char    c;
  119. {
  120.     outone(c);
  121. }
  122.  
  123. void
  124. outstr(s)
  125. register char    *s;
  126. {
  127.     while (*s) {
  128.         outone(*s++);
  129.     }
  130. }
  131.  
  132. #ifdef    TERMCAP
  133. void
  134. outcstr(s)
  135. char    *s;
  136. {
  137.     tputs(s, 1, outchar);
  138. }
  139. #endif
  140.  
  141. void
  142. beep()
  143. {
  144.     outone('\007');
  145. }
  146.  
  147. /*
  148.  * remove(file) - remove a file
  149.  */
  150. void
  151. remove(file)
  152. char *file;
  153. {
  154.     unlink(file);
  155. }
  156.  
  157. /*
  158.  * rename(of, nf) - rename existing file 'of' to 'nf'
  159.  */
  160. void
  161. rename(of, nf)
  162. char    *of, *nf;
  163. {
  164.     unlink(nf);
  165.     link(of, nf);
  166.     unlink(of);
  167. }
  168.  
  169. void
  170. delay()
  171. {
  172.     /* not implemented */
  173. }
  174.  
  175. #ifdef BSD
  176. static    struct    sgttyb    ostate;
  177. static    struct    ltchars    oltchars;
  178. #else
  179. static    struct    termio    ostate;
  180. #endif
  181.  
  182. /*
  183.  * Go into cbreak mode
  184.  */
  185. void
  186. set_tty()
  187. {
  188. #ifdef BSD
  189.     struct    sgttyb    nstate;
  190.     struct    ltchars    nltchars;
  191.  
  192.     ioctl(0, TIOCGETP, &ostate);
  193.     nstate = ostate;
  194.     nstate.sg_flags &= ~(XTABS|CRMOD|ECHO);
  195.     nstate.sg_flags |= CBREAK;
  196.     ioctl(0, TIOCSETN, &nstate);
  197.  
  198.     /*
  199.      * If ^Y is being used as the "delayed suspend" character, we
  200.      * change it to be whatever the regular suspend character is
  201.      * (probably ^Z). Vi needs ^Y as a command character, and the
  202.      * delayed suspend isn't needed here.
  203.      */
  204.     ioctl(0, TIOCGLTC, &oltchars);
  205.     nltchars = oltchars;
  206.     if (nltchars.t_dsuspc == CTRL('Y'))
  207.         nltchars.t_dsuspc = nltchars.t_suspc;
  208.     ioctl(0, TIOCSLTC, &nltchars);
  209.  
  210. #ifdef    TERMCAP
  211.     ospeed = nstate.sg_ospeed;
  212. #endif
  213.  
  214. #else
  215.     struct    termio    nstate;
  216.  
  217.     ioctl(0, TCGETA, &ostate);
  218.     nstate = ostate;
  219.     nstate.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
  220.     nstate.c_cc[VMIN] = 1;
  221.     nstate.c_cc[VTIME] = 0;
  222.     ioctl(0, TCSETAW, &nstate);
  223.  
  224. #ifdef    TERMCAP
  225.     ospeed = nstate.c_cflag & CBAUD;
  226. #endif
  227.  
  228. #endif
  229. }
  230.  
  231. /*
  232.  * Restore original terminal modes
  233.  */
  234. void
  235. reset_tty()
  236. {
  237. #ifdef BSD
  238.     ioctl(0, TIOCSETP, &ostate);
  239.     ioctl(0, TIOCSLTC, &oltchars);
  240. #else
  241.     ioctl(0, TCSETAW, &ostate);
  242. #endif
  243. }
  244.  
  245. static void
  246. sig()
  247. {
  248.     signal(SIGINT, sig);
  249.     signal(SIGQUIT, sig);
  250.  
  251.     got_int = TRUE;
  252. }
  253.  
  254. #ifdef    BSD
  255. static void
  256. tsig()
  257. {
  258.     signal(SIGTSTP, tsig);
  259.  
  260.     got_stop = TRUE;
  261. }
  262. #endif
  263.  
  264. void
  265. windinit()
  266. {
  267. #ifdef    TERMCAP
  268.     if (t_init() != 1) {
  269.         fprintf(stderr, "unknown terminal type\n");
  270.         exit(1);
  271.     }
  272. #else
  273.     Columns = 80;
  274.     P(P_LI) = Rows = 24;
  275. #endif
  276.  
  277.     /*
  278.      * The code here makes sure that there isn't a window during which
  279.      * we could get interrupted and exit with the tty in a weird state.
  280.      */
  281.     signal(SIGINT, sig);
  282.     signal(SIGQUIT, sig);
  283. #ifdef    BSD
  284.     signal(SIGTSTP, tsig);
  285. #endif
  286.  
  287.     set_tty();
  288.  
  289.     if (got_int)
  290.         windexit(0);
  291. }
  292.  
  293. void
  294. windexit(r)
  295. int r;
  296. {
  297.     reset_tty();
  298.     exit(r);
  299. }
  300.  
  301. void
  302. windgoto(r, c)
  303. register int    r, c;
  304. {
  305. #ifdef    TERMCAP
  306.     char    *tgoto();
  307. #else
  308.     r += 1;
  309.     c += 1;
  310. #endif
  311.  
  312.     /*
  313.      * Check for overflow once, to save time.
  314.      */
  315.     if (bpos + 8 >= BSIZE)
  316.         flushbuf();
  317.  
  318. #ifdef    TERMCAP
  319.     outcstr(tgoto(T_CM, c, r));
  320. #else
  321.     outbuf[bpos++] = '\033';
  322.     outbuf[bpos++] = '[';
  323.     if (r >= 10)
  324.         outbuf[bpos++] = r/10 + '0';
  325.     outbuf[bpos++] = r%10 + '0';
  326.     outbuf[bpos++] = ';';
  327.     if (c >= 10)
  328.         outbuf[bpos++] = c/10 + '0';
  329.     outbuf[bpos++] = c%10 + '0';
  330.     outbuf[bpos++] = 'H';
  331. #endif
  332. }
  333.  
  334. FILE *
  335. fopenb(fname, mode)
  336. char    *fname;
  337. char    *mode;
  338. {
  339.     return fopen(fname, mode);
  340. }
  341.  
  342. char *
  343. fixname(s)
  344. char    *s;
  345. {
  346.     return s;
  347. }
  348.  
  349. /*
  350.  * doshell() - run a command or an interactive shell
  351.  */
  352. void
  353. doshell(cmd)
  354. char    *cmd;
  355. {
  356.     char    *getenv();
  357.     char    cline[128];
  358.  
  359.     outstr("\r\n");
  360.     flushbuf();
  361.  
  362.     if (cmd == NULL) {
  363.         if ((cmd = getenv("SHELL")) == NULL)
  364.             cmd = "/bin/sh";
  365.         sprintf(cline, "%s -i", cmd);
  366.         cmd = cline;
  367.     }
  368.  
  369.     reset_tty();
  370.     system(cmd);
  371.     set_tty();
  372.  
  373.     wait_return();
  374. }
  375.