home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD2.bin
/
bbs
/
gnu
/
ispell-4.0-src.lha
/
ispell-4.0
/
term.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-04
|
7KB
|
382 lines
/* Copyright (C) 1990, 1993 Free Software Foundation, Inc.
This file is part of GNU ISPELL.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#if defined (HAVE_TERMIO_H)
#include <termio.h>
#else
/* Assume BSD if all else fails */
#include <sgtty.h>
#endif /* not HAVE_TERMIO_H */
#include <signal.h>
#include "ispell.h"
extern int reading_interactive_command;
extern jmp_buf command_loop;
int erasechar, killchar;
/* termcap variables */
static char *BC, *cd, *cl, *so, *se;
#ifndef VENIX
static char *cm, *ho, termcap[1024], termstr[1024];
#endif
static int li;
void
gettermcap ()
{
#ifdef NO_TERMCAP
/* IBM pc ansi escape codes */
BC = "\b";
cl = "\033[0;0H\033[0J";
cd = "\033[0J";
so = "\033[47;30m";
se = "\033[37;40m";
li = 25;
#else
char *termptr;
char *tgetstr ();
tgetent (termcap, getenv ("TERM"));
termptr = termstr;
BC = tgetstr ("bc", &termptr);/* backspace */
if (BC == NULL)
BC = "\b";
cd = tgetstr ("cd", &termptr);/* clear to end of screen */
cl = tgetstr ("cl", &termptr);/* clear screen */
cm = tgetstr ("cm", &termptr);/* cursor motion */
ho = tgetstr ("ho", &termptr);/* home */
so = tgetstr ("so", &termptr);/* inverse video on */
se = tgetstr ("se", &termptr);/* inverse video off */
li = tgetnum ("li"); /* number of lines on screen */
#endif
}
#ifdef NO_TERMCAP
/* ARGSUSED */
void
tputs (str, lines, put)
char *str;
int (*put) ();
{
while (*str)
(*put) (*str++);
}
#endif
void
putch (c)
int c;
{
putchar (c);
}
void
termflush ()
{
(void) fflush (stdout);
}
void
erase ()
{
if (cl)
tputs (cl, li, putch);
else
{
move (0, 0);
tputs (cd, li, putch);
}
}
void
move (row, col)
int row, col;
{
#ifdef NO_TERMCAP
(void) printf ("\033[%d;%dH", row, col);
#else
char *tgoto ();
tputs (tgoto (cm, col, row), 100, putch);
#endif
}
void
inverse ()
{
tputs (so, 10, putch);
}
void
normal ()
{
tputs (se, 10, putch);
}
void
backup ()
{
tputs (BC, 1, putch);
}
static int termchanged = 0;
#if !defined (HAVE_TERMIOS_H) && !defined (HAVE_TERMIO_H)
static struct sgttyb sbuf, osbuf;
void
terminit ()
{
int tpgrp;
RETSIGTYPE onstop ();
retry:
sigsetmask (1 << SIGTSTP | 1 << SIGTTIN | 1 << SIGTTOU);
/* apparently tpgrp was a short on 4.1, but is now a long -
* set the high bits to zero in case the ioctl doesn't write them.
*/
tpgrp = 0;
if (ioctl (0, TIOCGPGRP, &tpgrp) != 0)
{
(void) fprintf (stderr, "must run from tty in interactive mode\n");
exit (1);
}
if (tpgrp != getpgrp (0))
{ /* not in foreground */
(void) sigsetmask (1 << SIGTSTP | 1 << SIGTTIN);
(void) signal (SIGTTOU, SIG_DFL);
(void) kill (0, SIGTTOU);
/* job stops here waiting for SIGCONT */
goto retry;
}
(void) ioctl (0, TIOCGETP, &osbuf);
termchanged = 1;
sbuf = osbuf;
sbuf.sg_flags &= ~ECHO;
sbuf.sg_flags |= CBREAK;
ioctl (0, TIOCSETP, &sbuf);
erasechar = sbuf.sg_erase;
killchar = sbuf.sg_kill;
(void) signal (SIGTTIN, onstop);
(void) signal (SIGTTOU, onstop);
(void) signal (SIGTSTP, onstop);
(void) sigsetmask (0);
gettermcap ();
}
void
termuninit ()
{
if (termchanged)
{
(void) ioctl (0, TIOCSETP, (char *) &osbuf);
termchanged = 0;
}
}
void
termreinit ()
{
if (termchanged == 0)
{
(void) ioctl (0, TIOCSETP, (char *) &sbuf);
termchanged = 1;
}
}
#endif /* !HAVE_TERMIO_H && !HAVE_TERMIOS_H */
#if defined (HAVE_TERMIO_H) || defined (HAVE_TERMIOS_H)
struct termio termio, otermio;
void
terminit ()
{
if (ioctl (0, TCGETA, (char *) &otermio) < 0)
{
(void) fprintf (stderr, "must run from tty in interactive mode\n");
exit (1);
}
termchanged = 1;
termio = otermio;
termio.c_lflag &= ~(ICANON | ECHO);
termio.c_cc[VMIN] = 1;
termio.c_cc[VTIME] = 0;
erasechar = termio.c_cc[VERASE];
killchar = termio.c_cc[VKILL];
(void) ioctl (0, TCSETA, (char *) &termio);
gettermcap ();
}
void
termuninit ()
{
if (termchanged)
{
(void) ioctl (0, TCSETA, (char *) &otermio);
termchanged = 0;
}
}
void
termreinit ()
{
if (termchanged == 0)
{
(void) ioctl (0, TCSETA, (char *) &termio);
termchanged = 1;
}
}
#endif /* USG */
#ifdef MSDOS
void terminit () { ; }
void termuninit () { ; }
void termreinit () { ; }
#endif
#ifdef SIGTTIN
RETSIGTYPE
onstop (signo)
int signo;
{
(void) signal (signo, SIG_DFL);
termuninit ();
sigsetmask (0);
(void) killpg (getpgrp (0), signo);
/* stop here */
signal (signo, onstop);
termreinit ();
if (reading_interactive_command)
longjmp (command_loop, 1);
}
void
stop ()
{
onstop (SIGTSTP);
}
#else
void
stop ()
{
shellescape ((char *) NULL);
}
#endif
static char *shellcmd, *shellsh;;
void
shellfun ()
{
if (shellcmd == (char *) 0)
execlp (shellsh, shellsh, (char *) 0);
else
execlp (shellsh, shellsh, "-c", shellcmd, (char *) 0);
}
void
shellescape (buf)
char *buf;
{
shellsh = (char *) getenv ("SHELL");
if (shellsh == NULL)
shellsh = "/bin/sh";
shellcmd = buf;
(void) dochild (shellfun);
(void) printf ("\n-- Type space to continue --");
getchar ();
}
int
dochild (fun)
void (*fun) (NOARGS);
{
int pid, w;
int status, val = 1;
RETSIGTYPE (*oldf) (NOARGS);
termuninit ();
oldf = (RETSIGTYPE (*)()) signal (SIGINT, SIG_IGN);
(void) signal (SIGQUIT, SIG_IGN);
#ifdef SIGTTIN
(void) signal (SIGTTIN, SIG_DFL);
(void) signal (SIGTTOU, SIG_DFL);
(void) signal (SIGTSTP, SIG_DFL);
#endif
pid = fork ();
if (pid < 0)
{
perror ("fork");
goto ret;
}
if (pid == 0)
{
(void) signal (SIGINT, SIG_DFL);
(void) signal (SIGQUIT, SIG_DFL);
(*fun) ();
_exit (1);
}
while ((w = wait (&status)) >= 0)
if (w == pid)
break;
val = (status >> 8) & 0xff;
ret:
#ifdef SIGTTIN
signal (SIGTTIN, onstop);
signal (SIGTTOU, onstop);
signal (SIGTSTP, onstop);
#endif
signal (SIGINT, (RETSIGTYPE (*)()) oldf);
signal (SIGQUIT, SIG_DFL);
termreinit ();
return (val);
}
void
termbeep ()
{
(void) putchar (7);
(void) fflush (stdout);
}