[10333] | 1 | #ifndef lint |
---|
| 2 | static char Rcs_Id[] = |
---|
[22598] | 3 | "$Id: term.c,v 1.1.1.2 2007-02-01 19:50:05 ghudson Exp $"; |
---|
[10333] | 4 | #endif |
---|
| 5 | |
---|
| 6 | /* |
---|
| 7 | * term.c - deal with termcap, and unix terminal mode settings |
---|
| 8 | * |
---|
| 9 | * Pace Willisson, 1983 |
---|
| 10 | * |
---|
[22598] | 11 | * Copyright 1987, 1988, 1989, 1992, 1993, 1999, 2001, 2005, Geoff Kuenning, |
---|
| 12 | * Claremont, CA. |
---|
[10333] | 13 | * All rights reserved. |
---|
| 14 | * |
---|
| 15 | * Redistribution and use in source and binary forms, with or without |
---|
| 16 | * modification, are permitted provided that the following conditions |
---|
| 17 | * are met: |
---|
| 18 | * |
---|
| 19 | * 1. Redistributions of source code must retain the above copyright |
---|
| 20 | * notice, this list of conditions and the following disclaimer. |
---|
| 21 | * 2. Redistributions in binary form must reproduce the above copyright |
---|
| 22 | * notice, this list of conditions and the following disclaimer in the |
---|
| 23 | * documentation and/or other materials provided with the distribution. |
---|
| 24 | * 3. All modifications to the source code must be clearly marked as |
---|
| 25 | * such. Binary redistributions based on modified source code |
---|
| 26 | * must be clearly marked as modified versions in the documentation |
---|
| 27 | * and/or other materials provided with the distribution. |
---|
[22598] | 28 | * 4. The code that causes the 'ispell -v' command to display a prominent |
---|
| 29 | * link to the official ispell Web site may not be removed. |
---|
[10333] | 30 | * 5. The name of Geoff Kuenning may not be used to endorse or promote |
---|
| 31 | * products derived from this software without specific prior |
---|
| 32 | * written permission. |
---|
| 33 | * |
---|
| 34 | * THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND |
---|
| 35 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
| 36 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
| 37 | * ARE DISCLAIMED. IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE |
---|
| 38 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
---|
| 39 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
---|
| 40 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
| 41 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
---|
| 42 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
---|
| 43 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
---|
| 44 | * SUCH DAMAGE. |
---|
| 45 | */ |
---|
| 46 | |
---|
| 47 | /* |
---|
| 48 | * $Log: not supported by cvs2svn $ |
---|
[22598] | 49 | * Revision 1.54 2005/04/14 23:11:36 geoff |
---|
| 50 | * Correctly handle control-Z, including resetting the terminal. The |
---|
| 51 | * only remaining problem is that the screen isn't automatically |
---|
| 52 | * refreshed. (Doing the latter would either require major changes to |
---|
| 53 | * make the screen-refresh code callable from the signal handler, or |
---|
| 54 | * fixing GETKEYSTROKE to fail on signals. That's probably not hugely |
---|
| 55 | * hard but doing it portably probably is.) |
---|
| 56 | * |
---|
| 57 | * Revision 1.53 2005/04/14 14:38:23 geoff |
---|
| 58 | * Update license. Rename move/erase to avoid library conflicts. |
---|
| 59 | * |
---|
| 60 | * Revision 1.52 2001/09/06 00:30:28 geoff |
---|
| 61 | * Many changes from Eli Zaretskii to support DJGPP compilation. |
---|
| 62 | * |
---|
| 63 | * Revision 1.51 2001/07/25 21:51:46 geoff |
---|
| 64 | * Minor license update. |
---|
| 65 | * |
---|
| 66 | * Revision 1.50 2001/07/23 20:24:04 geoff |
---|
| 67 | * Update the copyright and the license. |
---|
| 68 | * |
---|
| 69 | * Revision 1.49 1999/01/07 01:22:53 geoff |
---|
| 70 | * Update the copyright. |
---|
| 71 | * |
---|
[10333] | 72 | * Revision 1.48 1994/10/25 05:46:11 geoff |
---|
| 73 | * Fix a couple of places where ifdefs were omitted, though apparently |
---|
| 74 | * harmlessly. |
---|
| 75 | * |
---|
| 76 | * Revision 1.47 1994/09/01 06:06:32 geoff |
---|
| 77 | * Change erasechar/killchar to uerasechar/ukillchar to avoid |
---|
| 78 | * shared-library problems on HP systems. |
---|
| 79 | * |
---|
| 80 | * Revision 1.46 1994/01/25 07:12:11 geoff |
---|
| 81 | * Get rid of all old RCS log lines in preparation for the 3.1 release. |
---|
| 82 | * |
---|
| 83 | */ |
---|
| 84 | |
---|
| 85 | #include "config.h" |
---|
| 86 | #include "ispell.h" |
---|
| 87 | #include "proto.h" |
---|
| 88 | #include "msgs.h" |
---|
| 89 | #ifdef USG |
---|
| 90 | #include <termio.h> |
---|
| 91 | #else |
---|
[22598] | 92 | #ifndef __DJGPP__ |
---|
[10333] | 93 | #include <sgtty.h> |
---|
| 94 | #endif |
---|
[22598] | 95 | #endif |
---|
[10333] | 96 | #include <signal.h> |
---|
| 97 | |
---|
[22598] | 98 | void ierase P ((void)); |
---|
| 99 | void imove P ((int row, int col)); |
---|
[10333] | 100 | void inverse P ((void)); |
---|
| 101 | void normal P ((void)); |
---|
| 102 | void backup P ((void)); |
---|
[22598] | 103 | static int iputch P ((int c)); |
---|
[10333] | 104 | void terminit P ((void)); |
---|
| 105 | SIGNAL_TYPE done P ((int signo)); |
---|
| 106 | #ifdef SIGTSTP |
---|
| 107 | static SIGNAL_TYPE onstop P ((int signo)); |
---|
| 108 | #endif /* SIGTSTP */ |
---|
| 109 | void stop P ((void)); |
---|
| 110 | int shellescape P ((char * buf)); |
---|
| 111 | #ifdef USESH |
---|
| 112 | void shescape P ((char * buf)); |
---|
| 113 | #endif /* USESH */ |
---|
| 114 | |
---|
[22598] | 115 | static int termchanged = 0; |
---|
| 116 | |
---|
| 117 | #ifdef __DJGPP__ |
---|
| 118 | #include "pc/djterm.c" |
---|
| 119 | #endif |
---|
| 120 | |
---|
| 121 | void ierase () |
---|
[10333] | 122 | { |
---|
| 123 | |
---|
| 124 | if (cl) |
---|
[22598] | 125 | tputs (cl, li, iputch); |
---|
[10333] | 126 | else |
---|
| 127 | { |
---|
| 128 | if (ho) |
---|
[22598] | 129 | tputs (ho, 100, iputch); |
---|
[10333] | 130 | else if (cm) |
---|
[22598] | 131 | tputs (tgoto (cm, 0, 0), 100, iputch); |
---|
| 132 | tputs (cd, li, iputch); |
---|
[10333] | 133 | } |
---|
| 134 | } |
---|
| 135 | |
---|
[22598] | 136 | void imove (row, col) |
---|
[10333] | 137 | int row; |
---|
| 138 | int col; |
---|
| 139 | { |
---|
[22598] | 140 | tputs (tgoto (cm, col, row), 100, iputch); |
---|
[10333] | 141 | } |
---|
| 142 | |
---|
| 143 | void inverse () |
---|
| 144 | { |
---|
[22598] | 145 | tputs (so, 10, iputch); |
---|
[10333] | 146 | } |
---|
| 147 | |
---|
| 148 | void normal () |
---|
| 149 | { |
---|
[22598] | 150 | tputs (se, 10, iputch); |
---|
[10333] | 151 | } |
---|
| 152 | |
---|
| 153 | void backup () |
---|
| 154 | { |
---|
| 155 | if (BC) |
---|
[22598] | 156 | tputs (BC, 1, iputch); |
---|
[10333] | 157 | else |
---|
| 158 | (void) putchar ('\b'); |
---|
| 159 | } |
---|
| 160 | |
---|
[22598] | 161 | static int iputch (c) |
---|
[10333] | 162 | int c; |
---|
| 163 | { |
---|
| 164 | |
---|
| 165 | return putchar (c); |
---|
| 166 | } |
---|
| 167 | |
---|
| 168 | #ifdef USG |
---|
| 169 | static struct termio sbuf; |
---|
| 170 | static struct termio osbuf; |
---|
| 171 | #else |
---|
| 172 | static struct sgttyb sbuf; |
---|
| 173 | static struct sgttyb osbuf; |
---|
| 174 | #ifdef TIOCSLTC |
---|
| 175 | static struct ltchars ltc; |
---|
| 176 | static struct ltchars oltc; |
---|
| 177 | #endif |
---|
| 178 | #endif |
---|
| 179 | static SIGNAL_TYPE (*oldint) (); |
---|
| 180 | static SIGNAL_TYPE (*oldterm) (); |
---|
| 181 | #ifdef SIGTSTP |
---|
| 182 | static SIGNAL_TYPE (*oldttin) (); |
---|
| 183 | static SIGNAL_TYPE (*oldttou) (); |
---|
| 184 | static SIGNAL_TYPE (*oldtstp) (); |
---|
| 185 | #endif |
---|
| 186 | |
---|
| 187 | void terminit () |
---|
| 188 | { |
---|
| 189 | #ifdef TIOCPGRP |
---|
| 190 | int tpgrp; |
---|
| 191 | #else |
---|
| 192 | #ifdef TIOCGPGRP |
---|
| 193 | int tpgrp; |
---|
| 194 | #endif |
---|
| 195 | #endif |
---|
| 196 | #ifdef TIOCGWINSZ |
---|
| 197 | struct winsize wsize; |
---|
| 198 | #endif /* TIOCGWINSZ */ |
---|
| 199 | |
---|
| 200 | tgetent (termcap, getenv ("TERM")); |
---|
| 201 | termptr = termstr; |
---|
| 202 | BC = tgetstr ("bc", &termptr); |
---|
| 203 | cd = tgetstr ("cd", &termptr); |
---|
| 204 | cl = tgetstr ("cl", &termptr); |
---|
| 205 | cm = tgetstr ("cm", &termptr); |
---|
| 206 | ho = tgetstr ("ho", &termptr); |
---|
| 207 | nd = tgetstr ("nd", &termptr); |
---|
| 208 | so = tgetstr ("so", &termptr); /* inverse video on */ |
---|
| 209 | se = tgetstr ("se", &termptr); /* inverse video off */ |
---|
| 210 | if ((sg = tgetnum ("sg")) < 0) /* space taken by so/se */ |
---|
| 211 | sg = 0; |
---|
| 212 | ti = tgetstr ("ti", &termptr); /* terminal initialization */ |
---|
| 213 | te = tgetstr ("te", &termptr); /* terminal termination */ |
---|
| 214 | co = tgetnum ("co"); |
---|
| 215 | li = tgetnum ("li"); |
---|
| 216 | #ifdef TIOCGWINSZ |
---|
| 217 | if (ioctl (0, TIOCGWINSZ, (char *) &wsize) >= 0) |
---|
| 218 | { |
---|
| 219 | if (wsize.ws_col != 0) |
---|
| 220 | co = wsize.ws_col; |
---|
| 221 | if (wsize.ws_row != 0) |
---|
| 222 | li = wsize.ws_row; |
---|
| 223 | } |
---|
| 224 | #endif /* TIOCGWINSZ */ |
---|
| 225 | /* |
---|
| 226 | * Let the variables "LINES" and "COLUMNS" override the termcap |
---|
| 227 | * entry. Technically, this is a terminfo-ism, but I think the |
---|
| 228 | * vast majority of users will find it pretty handy. |
---|
| 229 | */ |
---|
| 230 | if (getenv ("COLUMNS") != NULL) |
---|
| 231 | co = atoi (getenv ("COLUMNS")); |
---|
| 232 | if (getenv ("LINES") != NULL) |
---|
| 233 | li = atoi (getenv ("LINES")); |
---|
| 234 | #if MAX_SCREEN_SIZE > 0 |
---|
| 235 | if (li > MAX_SCREEN_SIZE) |
---|
| 236 | li = MAX_SCREEN_SIZE; |
---|
| 237 | #endif /* MAX_SCREEN_SIZE > 0 */ |
---|
| 238 | #if MAXCONTEXT == MINCONTEXT |
---|
| 239 | contextsize = MINCONTEXT; |
---|
| 240 | #else /* MAXCONTEXT == MINCONTEXT */ |
---|
| 241 | if (contextsize == 0) |
---|
| 242 | #ifdef CONTEXTROUNDUP |
---|
| 243 | contextsize = (li * CONTEXTPCT + 99) / 100; |
---|
| 244 | #else /* CONTEXTROUNDUP */ |
---|
| 245 | contextsize = (li * CONTEXTPCT) / 100; |
---|
| 246 | #endif /* CONTEXTROUNDUP */ |
---|
| 247 | if (contextsize > MAXCONTEXT) |
---|
| 248 | contextsize = MAXCONTEXT; |
---|
| 249 | else if (contextsize < MINCONTEXT) |
---|
| 250 | contextsize = MINCONTEXT; |
---|
| 251 | #endif /* MAX_CONTEXT == MIN_CONTEXT */ |
---|
| 252 | /* |
---|
| 253 | * Insist on 2 lines for the screen header, 2 for blank lines |
---|
| 254 | * separating areas of the screen, 2 for word choices, and 2 for |
---|
| 255 | * the minimenu, plus however many are needed for context. If |
---|
| 256 | * possible, make the context smaller to fit on the screen. |
---|
| 257 | */ |
---|
| 258 | if (li < contextsize + 8 && contextsize > MINCONTEXT) |
---|
| 259 | { |
---|
| 260 | contextsize = li - 8; |
---|
| 261 | if (contextsize < MINCONTEXT) |
---|
| 262 | contextsize = MINCONTEXT; |
---|
| 263 | } |
---|
| 264 | if (li < MINCONTEXT + 8) |
---|
| 265 | (void) fprintf (stderr, TERM_C_SMALL_SCREEN, MINCONTEXT + 8); |
---|
| 266 | |
---|
| 267 | #ifdef SIGTSTP |
---|
| 268 | #ifdef TIOCPGRP |
---|
| 269 | retry: |
---|
| 270 | #endif /* SIGTSTP */ |
---|
| 271 | #endif /* TIOCPGRP */ |
---|
| 272 | |
---|
| 273 | #ifdef USG |
---|
| 274 | if (!isatty (0)) |
---|
| 275 | { |
---|
| 276 | (void) fprintf (stderr, TERM_C_NO_BATCH); |
---|
| 277 | exit (1); |
---|
| 278 | } |
---|
| 279 | (void) ioctl (0, TCGETA, (char *) &osbuf); |
---|
| 280 | termchanged = 1; |
---|
| 281 | |
---|
| 282 | sbuf = osbuf; |
---|
| 283 | sbuf.c_lflag &= ~(ECHO | ECHOK | ECHONL | ICANON); |
---|
| 284 | sbuf.c_oflag &= ~(OPOST); |
---|
| 285 | sbuf.c_iflag &= ~(INLCR | IGNCR | ICRNL); |
---|
| 286 | sbuf.c_cc[VMIN] = 1; |
---|
| 287 | sbuf.c_cc[VTIME] = 1; |
---|
| 288 | (void) ioctl (0, TCSETAW, (char *) &sbuf); |
---|
| 289 | |
---|
| 290 | uerasechar = osbuf.c_cc[VERASE]; |
---|
| 291 | ukillchar = osbuf.c_cc[VKILL]; |
---|
| 292 | |
---|
| 293 | #endif |
---|
| 294 | |
---|
| 295 | #ifdef SIGTSTP |
---|
| 296 | #ifndef USG |
---|
| 297 | (void) sigsetmask (1<<(SIGTSTP-1) | 1<<(SIGTTIN-1) | 1<<(SIGTTOU-1)); |
---|
| 298 | #endif |
---|
| 299 | #endif |
---|
| 300 | #ifdef TIOCGPGRP |
---|
| 301 | if (ioctl (0, TIOCGPGRP, (char *) &tpgrp) != 0) |
---|
| 302 | { |
---|
| 303 | (void) fprintf (stderr, TERM_C_NO_BATCH); |
---|
| 304 | exit (1); |
---|
| 305 | } |
---|
| 306 | #endif |
---|
| 307 | #ifdef SIGTSTP |
---|
| 308 | #ifdef TIOCPGRP |
---|
| 309 | if (tpgrp != getpgrp(0)) /* not in foreground */ |
---|
| 310 | { |
---|
| 311 | #ifndef USG |
---|
| 312 | (void) sigsetmask (1 << (SIGTSTP - 1) | 1 << (SIGTTIN - 1)); |
---|
| 313 | #endif |
---|
| 314 | (void) signal (SIGTTOU, SIG_DFL); |
---|
| 315 | (void) kill (0, SIGTTOU); |
---|
| 316 | /* job stops here waiting for SIGCONT */ |
---|
| 317 | goto retry; |
---|
| 318 | } |
---|
| 319 | #endif |
---|
| 320 | #endif |
---|
| 321 | |
---|
| 322 | #ifndef USG |
---|
| 323 | (void) ioctl (0, TIOCGETP, (char *) &osbuf); |
---|
| 324 | #ifdef TIOCGLTC |
---|
| 325 | (void) ioctl (0, TIOCGLTC, (char *) &oltc); |
---|
| 326 | #endif |
---|
| 327 | termchanged = 1; |
---|
| 328 | |
---|
| 329 | sbuf = osbuf; |
---|
| 330 | sbuf.sg_flags &= ~ECHO; |
---|
| 331 | sbuf.sg_flags |= TERM_MODE; |
---|
| 332 | (void) ioctl (0, TIOCSETP, (char *) &sbuf); |
---|
| 333 | |
---|
| 334 | uerasechar = sbuf.sg_erase; |
---|
| 335 | ukillchar = sbuf.sg_kill; |
---|
| 336 | |
---|
| 337 | #ifdef TIOCSLTC |
---|
| 338 | ltc = oltc; |
---|
| 339 | ltc.t_suspc = -1; |
---|
| 340 | (void) ioctl (0, TIOCSLTC, (char *) <c); |
---|
| 341 | #endif |
---|
| 342 | |
---|
| 343 | #endif /* USG */ |
---|
| 344 | |
---|
| 345 | if ((oldint = signal (SIGINT, SIG_IGN)) != SIG_IGN) |
---|
| 346 | (void) signal (SIGINT, done); |
---|
| 347 | if ((oldterm = signal (SIGTERM, SIG_IGN)) != SIG_IGN) |
---|
| 348 | (void) signal (SIGTERM, done); |
---|
| 349 | |
---|
| 350 | #ifdef SIGTSTP |
---|
| 351 | #ifndef USG |
---|
| 352 | (void) sigsetmask (0); |
---|
| 353 | #endif |
---|
| 354 | if ((oldttin = signal (SIGTTIN, SIG_IGN)) != SIG_IGN) |
---|
| 355 | (void) signal (SIGTTIN, onstop); |
---|
| 356 | if ((oldttou = signal (SIGTTOU, SIG_IGN)) != SIG_IGN) |
---|
| 357 | (void) signal (SIGTTOU, onstop); |
---|
| 358 | if ((oldtstp = signal (SIGTSTP, SIG_IGN)) != SIG_IGN) |
---|
| 359 | (void) signal (SIGTSTP, onstop); |
---|
| 360 | #endif |
---|
| 361 | if (ti) |
---|
[22598] | 362 | tputs (ti, 1, iputch); |
---|
[10333] | 363 | } |
---|
| 364 | |
---|
| 365 | /* ARGSUSED */ |
---|
| 366 | SIGNAL_TYPE done (signo) |
---|
| 367 | int signo; |
---|
| 368 | { |
---|
| 369 | if (tempfile[0] != '\0') |
---|
| 370 | (void) unlink (tempfile); |
---|
| 371 | if (termchanged) |
---|
| 372 | { |
---|
| 373 | if (te) |
---|
[22598] | 374 | tputs (te, 1, iputch); |
---|
[10333] | 375 | #ifdef USG |
---|
| 376 | (void) ioctl (0, TCSETAW, (char *) &osbuf); |
---|
| 377 | #else |
---|
| 378 | (void) ioctl (0, TIOCSETP, (char *) &osbuf); |
---|
| 379 | #ifdef TIOCSLTC |
---|
| 380 | (void) ioctl (0, TIOCSLTC, (char *) &oltc); |
---|
| 381 | #endif |
---|
| 382 | #endif |
---|
| 383 | } |
---|
| 384 | exit (0); |
---|
| 385 | } |
---|
| 386 | |
---|
| 387 | #ifdef SIGTSTP |
---|
| 388 | static SIGNAL_TYPE onstop (signo) |
---|
| 389 | int signo; |
---|
| 390 | { |
---|
[22598] | 391 | if (termchanged) |
---|
| 392 | { |
---|
| 393 | imove (li - 1, 0); |
---|
| 394 | if (te) |
---|
| 395 | tputs (te, 1, iputch); |
---|
[10333] | 396 | #ifdef USG |
---|
[22598] | 397 | (void) ioctl (0, TCSETAW, (char *) &osbuf); |
---|
[10333] | 398 | #else |
---|
[22598] | 399 | (void) ioctl (0, TIOCSETP, (char *) &osbuf); |
---|
[10333] | 400 | #ifdef TIOCSLTC |
---|
[22598] | 401 | (void) ioctl (0, TIOCSLTC, (char *) &oltc); |
---|
[10333] | 402 | #endif |
---|
| 403 | #endif |
---|
[22598] | 404 | } |
---|
| 405 | (void) fflush (stdout); |
---|
[10333] | 406 | (void) signal (signo, SIG_DFL); |
---|
| 407 | #ifndef USG |
---|
| 408 | (void) sigsetmask (sigblock (0) & ~(1 << (signo - 1))); |
---|
| 409 | #endif |
---|
[22598] | 410 | (void) kill (0, SIGSTOP); |
---|
[10333] | 411 | /* stop here until continued */ |
---|
| 412 | (void) signal (signo, onstop); |
---|
[22598] | 413 | if (termchanged) |
---|
| 414 | { |
---|
[10333] | 415 | #ifdef USG |
---|
[22598] | 416 | (void) ioctl (0, TCSETAW, (char *) &sbuf); |
---|
[10333] | 417 | #else |
---|
[22598] | 418 | (void) ioctl (0, TIOCSETP, (char *) &sbuf); |
---|
[10333] | 419 | #ifdef TIOCSLTC |
---|
[22598] | 420 | (void) ioctl (0, TIOCSLTC, (char *) <c); |
---|
[10333] | 421 | #endif |
---|
| 422 | #endif |
---|
[22598] | 423 | if (ti) |
---|
| 424 | tputs (ti, 1, iputch); |
---|
| 425 | } |
---|
[10333] | 426 | } |
---|
| 427 | #endif |
---|
| 428 | |
---|
[22598] | 429 | #ifndef USESH |
---|
| 430 | #define NEED_SHELLESCAPE |
---|
| 431 | #endif /* USESH */ |
---|
| 432 | #ifndef REGEX_LOOKUP |
---|
| 433 | #define NEED_SHELLESCAPE |
---|
| 434 | #endif /* REGEX_LOOKUP */ |
---|
| 435 | |
---|
[10333] | 436 | void stop () |
---|
| 437 | { |
---|
| 438 | #ifdef SIGTSTP |
---|
| 439 | onstop (SIGTSTP); |
---|
| 440 | #else |
---|
[22598] | 441 | /* for System V and MSDOS */ |
---|
| 442 | imove (li - 1, 0); |
---|
[10333] | 443 | (void) fflush (stdout); |
---|
[22598] | 444 | #ifdef NEED_SHELLESCAPE |
---|
[10333] | 445 | if (getenv ("SHELL")) |
---|
| 446 | (void) shellescape (getenv ("SHELL")); |
---|
| 447 | else |
---|
| 448 | (void) shellescape ("sh"); |
---|
[22598] | 449 | #else |
---|
| 450 | shescape (""); |
---|
| 451 | #endif /* NEED_SHELLESCAPE */ |
---|
| 452 | #endif /* SIGTSTP */ |
---|
[10333] | 453 | } |
---|
| 454 | |
---|
| 455 | /* Fork and exec a process. Returns NZ if command found, regardless of |
---|
| 456 | ** command's return status. Returns zero if command was not found. |
---|
| 457 | ** Doesn't use a shell. |
---|
| 458 | */ |
---|
| 459 | #ifdef NEED_SHELLESCAPE |
---|
| 460 | int shellescape (buf) |
---|
| 461 | char * buf; |
---|
| 462 | { |
---|
| 463 | char * argv[100]; |
---|
| 464 | char * cp = buf; |
---|
| 465 | int i = 0; |
---|
| 466 | int termstat; |
---|
| 467 | |
---|
| 468 | /* parse buf to args (destroying it in the process) */ |
---|
| 469 | while (*cp != '\0') |
---|
| 470 | { |
---|
| 471 | while (*cp == ' ' || *cp == '\t') |
---|
| 472 | ++cp; |
---|
| 473 | if (*cp == '\0') |
---|
| 474 | break; |
---|
| 475 | argv[i++] = cp; |
---|
| 476 | while (*cp != ' ' && *cp != '\t' && *cp != '\0') |
---|
| 477 | ++cp; |
---|
| 478 | if (*cp != '\0') |
---|
| 479 | *cp++ = '\0'; |
---|
| 480 | } |
---|
| 481 | argv[i] = NULL; |
---|
| 482 | |
---|
| 483 | #ifdef USG |
---|
| 484 | (void) ioctl (0, TCSETAW, (char *) &osbuf); |
---|
| 485 | #else |
---|
| 486 | (void) ioctl (0, TIOCSETP, (char *) &osbuf); |
---|
| 487 | #ifdef TIOCSLTC |
---|
| 488 | (void) ioctl (0, TIOCSLTC, (char *) &oltc); |
---|
| 489 | #endif /* TIOCSLTC */ |
---|
| 490 | #endif |
---|
| 491 | (void) signal (SIGINT, oldint); |
---|
| 492 | (void) signal (SIGTERM, oldterm); |
---|
| 493 | #ifdef SIGTSTP |
---|
| 494 | (void) signal (SIGTTIN, oldttin); |
---|
| 495 | (void) signal (SIGTTOU, oldttou); |
---|
| 496 | (void) signal (SIGTSTP, oldtstp); |
---|
| 497 | #endif |
---|
| 498 | if ((i = fork ()) == 0) |
---|
| 499 | { |
---|
| 500 | (void) execvp (argv[0], (char **) argv); |
---|
| 501 | _exit (123); /* Command not found */ |
---|
| 502 | } |
---|
| 503 | else if (i > 0) |
---|
| 504 | { |
---|
| 505 | while (wait (&termstat) != i) |
---|
| 506 | ; |
---|
| 507 | termstat = (termstat == (123 << 8)) ? 0 : -1; |
---|
| 508 | } |
---|
| 509 | else |
---|
| 510 | { |
---|
[22598] | 511 | (void) printf (TERM_C_CANT_FORK, MAYBE_CR (stderr)); |
---|
[10333] | 512 | termstat = -1; /* Couldn't fork */ |
---|
| 513 | } |
---|
| 514 | |
---|
| 515 | if (oldint != SIG_IGN) |
---|
| 516 | (void) signal (SIGINT, done); |
---|
| 517 | if (oldterm != SIG_IGN) |
---|
| 518 | (void) signal (SIGTERM, done); |
---|
| 519 | |
---|
| 520 | #ifdef SIGTSTP |
---|
| 521 | if (oldttin != SIG_IGN) |
---|
| 522 | (void) signal (SIGTTIN, onstop); |
---|
| 523 | if (oldttou != SIG_IGN) |
---|
| 524 | (void) signal (SIGTTOU, onstop); |
---|
| 525 | if (oldtstp != SIG_IGN) |
---|
| 526 | (void) signal (SIGTSTP, onstop); |
---|
| 527 | #endif |
---|
| 528 | |
---|
| 529 | #ifdef USG |
---|
| 530 | (void) ioctl (0, TCSETAW, (char *) &sbuf); |
---|
| 531 | #else |
---|
| 532 | (void) ioctl (0, TIOCSETP, (char *) &sbuf); |
---|
| 533 | #ifdef TIOCSLTC |
---|
| 534 | (void) ioctl (0, TIOCSLTC, (char *) <c); |
---|
| 535 | #endif /* TIOCSLTC */ |
---|
| 536 | #endif |
---|
| 537 | if (termstat) |
---|
| 538 | { |
---|
| 539 | (void) printf (TERM_C_TYPE_SPACE); |
---|
| 540 | (void) fflush (stdout); |
---|
| 541 | #ifdef COMMANDFORSPACE |
---|
| 542 | i = GETKEYSTROKE (); |
---|
| 543 | if (i != ' ' && i != '\n' && i != '\r') |
---|
| 544 | (void) ungetc (i, stdin); |
---|
| 545 | #else |
---|
| 546 | while (GETKEYSTROKE () != ' ') |
---|
| 547 | ; |
---|
| 548 | #endif |
---|
| 549 | } |
---|
| 550 | return (termstat); |
---|
| 551 | } |
---|
| 552 | #endif /* NEED_SHELLESCAPE */ |
---|
| 553 | |
---|
| 554 | #ifdef USESH |
---|
| 555 | void shescape (buf) |
---|
| 556 | char * buf; |
---|
| 557 | { |
---|
| 558 | #ifdef COMMANDFORSPACE |
---|
| 559 | int ch; |
---|
| 560 | #endif |
---|
[22598] | 561 | #ifdef __DJGPP__ |
---|
| 562 | char curdir[MAXPATHLEN]; |
---|
| 563 | #endif |
---|
[10333] | 564 | |
---|
| 565 | #ifdef USG |
---|
| 566 | (void) ioctl (0, TCSETAW, (char *) &osbuf); |
---|
| 567 | #else |
---|
| 568 | (void) ioctl (0, TIOCSETP, (char *) &osbuf); |
---|
| 569 | #ifdef TIOCSLTC |
---|
| 570 | (void) ioctl (0, TIOCSLTC, (char *) &oltc); |
---|
| 571 | #endif |
---|
| 572 | #endif |
---|
[22598] | 573 | #ifdef __DJGPP__ |
---|
| 574 | /* Don't erase the screen if they want to run a single command, |
---|
| 575 | * otherwise they will be unable to see its output. |
---|
| 576 | */ |
---|
| 577 | if (buf[0] == '\0') |
---|
| 578 | djgpp_restore_screen (); |
---|
| 579 | /* Change and restore the current directory, because it's a global |
---|
| 580 | * notion on MS-DOS/MS-Windows. |
---|
| 581 | */ |
---|
| 582 | getcwd (curdir, MAXPATHLEN); |
---|
| 583 | #endif |
---|
[10333] | 584 | (void) signal (SIGINT, oldint); |
---|
| 585 | (void) signal (SIGTERM, oldterm); |
---|
| 586 | #ifdef SIGTSTP |
---|
| 587 | (void) signal (SIGTTIN, oldttin); |
---|
| 588 | (void) signal (SIGTTOU, oldttou); |
---|
| 589 | (void) signal (SIGTSTP, oldtstp); |
---|
| 590 | #endif |
---|
| 591 | |
---|
| 592 | (void) system (buf); |
---|
| 593 | |
---|
| 594 | if (oldint != SIG_IGN) |
---|
| 595 | (void) signal (SIGINT, done); |
---|
| 596 | if (oldterm != SIG_IGN) |
---|
| 597 | (void) signal (SIGTERM, done); |
---|
| 598 | |
---|
| 599 | #ifdef SIGTSTP |
---|
| 600 | if (oldttin != SIG_IGN) |
---|
| 601 | (void) signal (SIGTTIN, onstop); |
---|
| 602 | if (oldttou != SIG_IGN) |
---|
| 603 | (void) signal (SIGTTOU, onstop); |
---|
| 604 | if (oldtstp != SIG_IGN) |
---|
| 605 | (void) signal (SIGTSTP, onstop); |
---|
| 606 | #endif |
---|
[22598] | 607 | #ifdef __DJGPP__ |
---|
| 608 | if (buf[0] == '\0') |
---|
| 609 | djgpp_ispell_screen (); |
---|
| 610 | chdir (curdir); |
---|
| 611 | #endif |
---|
[10333] | 612 | |
---|
| 613 | #ifdef USG |
---|
| 614 | (void) ioctl (0, TCSETAW, (char *) &sbuf); |
---|
| 615 | #else |
---|
| 616 | (void) ioctl (0, TIOCSETP, (char *) &sbuf); |
---|
| 617 | #ifdef TIOCSLTC |
---|
| 618 | (void) ioctl (0, TIOCSLTC, (char *) <c); |
---|
| 619 | #endif |
---|
| 620 | #endif |
---|
| 621 | (void) printf (TERM_C_TYPE_SPACE); |
---|
| 622 | (void) fflush (stdout); |
---|
| 623 | #ifdef COMMANDFORSPACE |
---|
| 624 | ch = GETKEYSTROKE (); |
---|
| 625 | if (ch != ' ' && ch != '\n' && ch != '\r') |
---|
| 626 | (void) ungetc (ch, stdin); |
---|
| 627 | #else |
---|
| 628 | while (GETKEYSTROKE () != ' ') |
---|
| 629 | ; |
---|
| 630 | #endif |
---|
| 631 | } |
---|
| 632 | #endif |
---|