sysdep.c 157 KB
Newer Older
Jim Blandy's avatar
Jim Blandy committed
1
/* Interfaces to system-dependent kernel and library entries.
2
   Copyright (C) 1985, 86,87,88,93,94,95, 1999 Free Software Foundation, Inc.
Jim Blandy's avatar
Jim Blandy committed
3 4 5 6 7

This file is part of GNU Emacs.

GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
Jim Blandy's avatar
Jim Blandy committed
9 10 11 12 13 14 15 16 17
any later version.

GNU Emacs 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 GNU Emacs; see the file COPYING.  If not, write to
18 19
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */
Jim Blandy's avatar
Jim Blandy committed
20 21


22
#include <config.h>
Jim Blandy's avatar
Jim Blandy committed
23 24 25 26
#include <signal.h>
#include <setjmp.h>

#include "lisp.h"
27
#include "blockinput.h"
Jim Blandy's avatar
Jim Blandy committed
28 29
#undef NULL

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
#ifdef macintosh
#ifdef __MRC__
__sigfun sys_signal (int signal, __sigfun signal_func);
#elif __MWERKS__
__signal_func_ptr sys_signal (int signal, __signal_func_ptr signal_func);
#else
You lose!!!
#endif
#ifndef subprocesses
/* Nonzero means delete a process right away if it exits (process.c).  */
static int delete_exited_processes;
#endif
#ifndef HAVE_X_WINDOWS
/* Search path for bitmap files (xfns.c).  */
Lisp_Object Vx_bitmap_file_path;
#endif
#endif  /* macintosh */

Jim Blandy's avatar
Jim Blandy committed
48 49
#define min(x,y) ((x) > (y) ? (y) : (x))

50 51 52 53 54 55 56
#ifdef WINDOWSNT
#define read _read
#define write _write
#include <windows.h>
extern int errno;
#endif /* not WINDOWSNT */

57 58 59 60 61 62 63
/* Does anyone other than VMS need this? */
#ifndef fwrite
#define sys_fwrite fwrite
#else
#undef fwrite
#endif

64 65 66 67
#ifndef HAVE_H_ERRNO
extern int h_errno;
#endif

Jim Blandy's avatar
Jim Blandy committed
68 69 70 71 72
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>

73 74 75 76 77
/* Get _POSIX_VDISABLE, if it is available.  */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

78 79 80 81 82
/* Get SI_SRPC_DOMAIN, if it is available.  */
#ifdef HAVE_SYS_SYSTEMINFO_H
#include <sys/systeminfo.h>
#endif

83 84 85 86 87
#ifdef MSDOS	/* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
#include <dos.h>
#include "dosfns.h"
#include "msdos.h"
#include <sys/param.h>
88 89 90 91 92

#if __DJGPP__ > 1
extern int etext;
extern unsigned start __asm__ ("start");
#endif
93 94
#endif

95
#ifndef errno
Jim Blandy's avatar
Jim Blandy committed
96
extern int errno;
97
#endif
Jim Blandy's avatar
Jim Blandy committed
98

99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
#ifdef VMS
#include <rms.h>
#include <ttdef.h>
#include <tt2def.h>
#include <iodef.h>
#include <ssdef.h>
#include <descrip.h>
#include <fibdef.h>
#include <atrdef.h>
#include <ctype.h>
#include <string.h>
#ifdef __GNUC__
#include <sys/file.h>
#else
#include <file.h>
#endif
#undef F_SETFL
#ifndef RAB$C_BID
#include <rab.h>
#endif
119
#define MAXIOSIZE (32 * PAGESIZE) /* Don't I/O more than 32 blocks at a time */
120 121 122
#endif /* VMS */

#ifndef BSD4_1
123
#ifdef BSD_SYSTEM /* avoid writing defined (BSD_SYSTEM) || defined (USG)
124 125 126 127 128 129 130 131 132
	      because the vms compiler doesn't grok `defined' */
#include <fcntl.h>
#endif
#ifdef USG
#ifndef USG5
#include <fcntl.h>
#endif
#endif
#endif /* not 4.1 bsd */
Jim Blandy's avatar
Jim Blandy committed
133

134
#ifndef MSDOS
Jim Blandy's avatar
Jim Blandy committed
135
#include <sys/ioctl.h>
136
#endif
137

138
#include "systty.h"
Richard M. Stallman's avatar
Richard M. Stallman committed
139
#include "syswait.h"
Jim Blandy's avatar
Jim Blandy committed
140 141 142

#ifdef BROKEN_TIOCGWINSZ
#undef TIOCGWINSZ
143
#undef TIOCSWINSZ
Jim Blandy's avatar
Jim Blandy committed
144 145
#endif

146
#if defined (USG) || defined (DGUX)
Jim Blandy's avatar
Jim Blandy committed
147 148 149 150 151
#include <sys/utsname.h>
#include <string.h>
#ifndef MEMORY_IN_STRING_H
#include <memory.h>
#endif
152
#if defined (TIOCGWINSZ) || defined (ISC4_0)
Jim Blandy's avatar
Jim Blandy committed
153 154 155 156 157 158 159
#ifdef NEED_SIOCTL
#include <sys/sioctl.h>
#endif
#ifdef NEED_PTEM_H
#include <sys/stream.h>
#include <sys/ptem.h>
#endif
160
#endif /* TIOCGWINSZ or ISC4_0 */
Karl Heuer's avatar
Karl Heuer committed
161
#endif /* USG or DGUX */
Jim Blandy's avatar
Jim Blandy committed
162 163 164

extern int quit_char;

Jim Blandy's avatar
Jim Blandy committed
165
#include "frame.h"
Jim Blandy's avatar
Jim Blandy committed
166 167 168 169 170 171 172
#include "window.h"
#include "termhooks.h"
#include "termchar.h"
#include "termopts.h"
#include "dispextern.h"
#include "process.h"

173 174 175 176 177 178 179 180
#ifdef WINDOWSNT
#include <direct.h>
/* In process.h which conflicts with the local copy.  */
#define _P_WAIT 0
int _CRTAPI1 _spawnlp (int, const char *, const char *, ...);
int _CRTAPI1 _getpid (void);
#endif

Jim Blandy's avatar
Jim Blandy committed
181 182 183 184
#ifdef NONSYSTEM_DIR_LIBRARY
#include "ndir.h"
#endif /* NONSYSTEM_DIR_LIBRARY */

Jim Blandy's avatar
Jim Blandy committed
185 186
#include "syssignal.h"
#include "systime.h"
187 188 189 190 191 192 193 194 195 196 197 198 199 200
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif

#ifndef HAVE_UTIMES
#ifndef HAVE_STRUCT_UTIMBUF
/* We want to use utime rather than utimes, but we couldn't find the
   structure declaration.  We'll use the traditional one.  */
struct utimbuf {
  long actime;
  long modtime;
};
#endif
#endif
Jim Blandy's avatar
Jim Blandy committed
201

202 203 204 205
#ifndef VFORK_RETURN_TYPE
#define VFORK_RETURN_TYPE int
#endif

206 207 208 209 210 211 212 213 214
/* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits.  */
#ifndef LPASS8
#define LPASS8 0
#endif

#ifdef BSD4_1
#define LNOFLSH 0100000
#endif

Jim Blandy's avatar
Jim Blandy committed
215 216 217 218 219 220 221 222 223 224
static int baud_convert[] =
#ifdef BAUD_CONVERT
  BAUD_CONVERT;
#else
  {
    0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
    1800, 2400, 4800, 9600, 19200, 38400
  };
#endif

225 226 227
#if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
extern short ospeed;
#else
Richard M. Stallman's avatar
Richard M. Stallman committed
228 229
#if defined (HAVE_TERMIOS_H) && defined (LINUX)
#include <termios.h>
230 231
/* HJL's version of libc is said to need this on the Alpha.
   On the other hand, DEC OSF1 on the Alpha needs ospeed to be a short.  */
232 233
extern speed_t ospeed;
#else
Karl Heuer's avatar
Karl Heuer committed
234
extern short ospeed;
235
#endif
236
#endif
Jim Blandy's avatar
Jim Blandy committed
237

Jim Blandy's avatar
Jim Blandy committed
238
/* The file descriptor for Emacs's input terminal.
239 240 241
   Under Unix, this is normally zero except when using X;
   under VMS, we place the input channel number here.  */
int input_fd;
242 243 244

void croak P_ ((char *));

245 246 247 248
#ifdef AIXHFT
void hft_init ();
void hft_reset ();
#endif
249

250 251 252 253 254 255 256 257 258 259 260

/* Specify a different file descriptor for further input operations.  */

void
change_input_fd (fd)
     int fd;
{
  input_fd = fd;
}

/* Discard pending input on descriptor input_fd.  */
Jim Blandy's avatar
Jim Blandy committed
261

262
void
Jim Blandy's avatar
Jim Blandy committed
263 264
discard_tty_input ()
{
265
#ifndef WINDOWSNT
Jim Blandy's avatar
Jim Blandy committed
266
  struct emacs_tty buf;
Jim Blandy's avatar
Jim Blandy committed
267 268 269 270 271 272 273 274 275 276 277

  if (noninteractive)
    return;

  /* Discarding input is not safe when the input could contain
     replies from the X server.  So don't do it.  */
  if (read_socket_hook)
    return;

#ifdef VMS
  end_kbd_input ();
Jim Blandy's avatar
Jim Blandy committed
278 279
  SYS$QIOW (0, input_fd, IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0,
	    &buf.main, 0, 0, terminator_mask, 0, 0);
Jim Blandy's avatar
Jim Blandy committed
280 281 282 283 284
  queue_kbd_input ();
#else /* not VMS */
#ifdef APOLLO
  {
    int zero = 0;
285
    ioctl (input_fd, TIOCFLUSH, &zero);
Jim Blandy's avatar
Jim Blandy committed
286 287
  }
#else /* not Apollo */
288
#ifdef MSDOS    /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
289
  while (dos_keyread () != -1)
290
    ;
291
#else /* not MSDOS */
Jim Blandy's avatar
Jim Blandy committed
292 293
  EMACS_GET_TTY (input_fd, &buf);
  EMACS_SET_TTY (input_fd, &buf, 0);
294
#endif /* not MSDOS */
Jim Blandy's avatar
Jim Blandy committed
295 296
#endif /* not Apollo */
#endif /* not VMS */
297
#endif /* not WINDOWSNT */
Jim Blandy's avatar
Jim Blandy committed
298 299 300 301
}

#ifdef SIGTSTP

302 303 304
/* Arrange for character C to be read as the next input from
   the terminal.  */

Andreas Schwab's avatar
Andreas Schwab committed
305
void
Jim Blandy's avatar
Jim Blandy committed
306 307 308
stuff_char (c)
     char c;
{
309 310 311
  if (read_socket_hook)
    return;

Jim Blandy's avatar
Jim Blandy committed
312 313
/* Should perhaps error if in batch mode */
#ifdef TIOCSTI
314
  ioctl (input_fd, TIOCSTI, &c);
Jim Blandy's avatar
Jim Blandy committed
315
#else /* no TIOCSTI */
316
  error ("Cannot stuff terminal input characters in this version of Unix");
Jim Blandy's avatar
Jim Blandy committed
317 318 319 320
#endif /* no TIOCSTI */
}

#endif /* SIGTSTP */
321

322
void
Jim Blandy's avatar
Jim Blandy committed
323 324 325 326 327 328
init_baud_rate ()
{
  if (noninteractive)
    ospeed = 0;
  else
    {
329 330 331
#ifdef INIT_BAUD_RATE
      INIT_BAUD_RATE ();
#else
332
#ifdef DOS_NT
333
    ospeed = 15;
334
#else  /* not DOS_NT */
Jim Blandy's avatar
Jim Blandy committed
335
#ifdef VMS
Jim Blandy's avatar
Jim Blandy committed
336 337 338
      struct sensemode sg;

      SYS$QIOW (0, input_fd, IO$_SENSEMODE, &sg, 0, 0,
Jim Blandy's avatar
Jim Blandy committed
339
		&sg.class, 12, 0, 0, 0, 0 );
Jim Blandy's avatar
Jim Blandy committed
340 341
      ospeed = sg.xmit_baud;
#else /* not VMS */
342 343
#ifdef HAVE_TERMIOS
      struct termios sg;
Jim Blandy's avatar
Jim Blandy committed
344

345
      sg.c_cflag = B9600;
346
      tcgetattr (input_fd, &sg);
347
      ospeed = cfgetospeed (&sg);
348
#if defined (USE_GETOBAUD) && defined (getobaud)
349 350 351 352
      /* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */
      if (ospeed == 0)
        ospeed = getobaud (sg.c_cflag);
#endif
353 354 355
#else /* neither VMS nor TERMIOS */
#ifdef HAVE_TERMIO
      struct termio sg;
Jim Blandy's avatar
Jim Blandy committed
356

357
      sg.c_cflag = B9600;
358
#ifdef HAVE_TCATTR
359
      tcgetattr (input_fd, &sg);
360
#else
361
      ioctl (input_fd, TCGETA, &sg);
362
#endif
Jim Blandy's avatar
Jim Blandy committed
363
      ospeed = sg.c_cflag & CBAUD;
364
#else /* neither VMS nor TERMIOS nor TERMIO */
Jim Blandy's avatar
Jim Blandy committed
365 366 367
      struct sgttyb sg;
      
      sg.sg_ospeed = B9600;
368
      if (ioctl (input_fd, TIOCGETP, &sg) < 0)
369
	abort ();
Jim Blandy's avatar
Jim Blandy committed
370 371
      ospeed = sg.sg_ospeed;
#endif /* not HAVE_TERMIO */
372
#endif /* not HAVE_TERMIOS */
Jim Blandy's avatar
Jim Blandy committed
373
#endif /* not VMS */
374
#endif /* not DOS_NT */
375
#endif /* not INIT_BAUD_RATE */
Jim Blandy's avatar
Jim Blandy committed
376 377 378
    }
   
  baud_rate = (ospeed < sizeof baud_convert / sizeof baud_convert[0]
379
	       ? baud_convert[ospeed] : 9600);
Jim Blandy's avatar
Jim Blandy committed
380 381 382 383 384
  if (baud_rate == 0)
    baud_rate = 1200;
}

/*ARGSUSED*/
Andreas Schwab's avatar
Andreas Schwab committed
385
void
Jim Blandy's avatar
Jim Blandy committed
386 387 388 389 390 391 392 393
set_exclusive_use (fd)
     int fd;
{
#ifdef FIOCLEX
  ioctl (fd, FIOCLEX, 0);
#endif
  /* Ok to do nothing if this feature does not exist */
}
394

Jim Blandy's avatar
Jim Blandy committed
395 396 397 398
#ifndef subprocesses

wait_without_blocking ()
{
399
#ifdef BSD_SYSTEM
Jim Blandy's avatar
Jim Blandy committed
400 401 402 403 404 405 406 407 408 409
  wait3 (0, WNOHANG | WUNTRACED, 0);
#else
  croak ("wait_without_blocking");
#endif
  synch_process_alive = 0;
}

#endif /* not subprocesses */

int wait_debugging;   /* Set nonzero to make following function work under dbx
410
			 (at least for bsd).  */
Jim Blandy's avatar
Jim Blandy committed
411 412 413 414 415 416 417 418

SIGTYPE
wait_for_termination_signal ()
{}

/* Wait for subprocess with process id `pid' to terminate and
   make sure it will get eliminated (not remain forever as a zombie) */

419
void
Jim Blandy's avatar
Jim Blandy committed
420 421 422 423 424 425 426 427 428
wait_for_termination (pid)
     int pid;
{
  while (1)
    {
#ifdef subprocesses
#ifdef VMS
      int status;

429
      status = SYS$FORCEX (&pid, 0, 0);
Jim Blandy's avatar
Jim Blandy committed
430 431
      break;
#else /* not VMS */
432
#if defined (BSD_SYSTEM) || (defined (HPUX) && !defined (HPUX_5))
433 434 435 436 437 438 439 440 441
      /* Note that kill returns -1 even if the process is just a zombie now.
	 But inevitably a SIGCHLD interrupt should be generated
	 and child_sig will do wait3 and make the process go away. */
      /* There is some indication that there is a bug involved with
	 termination of subprocesses, perhaps involving a kernel bug too,
	 but no idea what it is.  Just as a hunch we signal SIGCHLD to see
	 if that causes the problem to go away or get worse.  */
      sigsetmask (sigmask (SIGCHLD));
      if (0 > kill (pid, 0))
442
	{
443 444 445 446 447 448 449 450
	  sigsetmask (SIGEMPTYMASK);
	  kill (getpid (), SIGCHLD);
	  break;
	}
      if (wait_debugging)
	sleep (1);
      else
	sigpause (SIGEMPTYMASK);
451
#else /* not BSD_SYSTEM, and not HPUX version >= 6 */
452
#if defined (UNIPLUS)
453 454 455
      if (0 > kill (pid, 0))
	break;
      wait (0);
456
#else /* neither BSD_SYSTEM nor UNIPLUS: random sysV */
457
#ifdef POSIX_SIGNALS    /* would this work for LINUX as well? */
458 459 460 461 462 463
      sigblock (sigmask (SIGCHLD));
      if (0 > kill (pid, 0))
	{
	  sigunblock (sigmask (SIGCHLD));
	  break;
	}
464
      sigpause (SIGEMPTYMASK);
465
#else /* not POSIX_SIGNALS */
466 467 468 469 470 471 472 473 474
#ifdef HAVE_SYSV_SIGPAUSE
      sighold (SIGCHLD);
      if (0 > kill (pid, 0))
	{
	  sigrelse (SIGCHLD);
	  break;
	}
      sigpause (SIGCHLD);
#else /* not HAVE_SYSV_SIGPAUSE */
475 476 477 478
#ifdef WINDOWSNT
      wait (0);
      break;
#else /* not WINDOWSNT */
479
      if (0 > kill (pid, 0))
Jim Blandy's avatar
Jim Blandy committed
480
	break;
481 482 483 484
      /* Using sleep instead of pause avoids timing error.
	 If the inferior dies just before the sleep,
	 we lose just one second.  */
      sleep (1);
485
#endif /* not WINDOWSNT */
486
#endif /* not HAVE_SYSV_SIGPAUSE */
487
#endif /* not POSIX_SIGNALS */
488
#endif /* not UNIPLUS */
489
#endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
Jim Blandy's avatar
Jim Blandy committed
490 491
#endif /* not VMS */
#else /* not subprocesses */
492 493 494
#if __DJGPP__ > 1
      break;
#else /* not __DJGPP__ > 1 */
Jim Blandy's avatar
Jim Blandy committed
495 496 497 498 499 500 501 502 503 504
#ifndef BSD4_1
      if (kill (pid, 0) < 0)
	break;
      wait (0);
#else /* BSD4_1 */
      int status;
      status = wait (0);
      if (status == pid || status == -1)
	break;
#endif /* BSD4_1 */
505
#endif /* not __DJGPP__ > 1*/
Jim Blandy's avatar
Jim Blandy committed
506 507 508 509 510 511 512 513 514 515 516
#endif /* not subprocesses */
    }
}

#ifdef subprocesses

/*
 *	flush any pending output
 *      (may flush input as well; it does not matter the way we use it)
 */
 
517
void
Jim Blandy's avatar
Jim Blandy committed
518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537
flush_pending_output (channel)
     int channel;
{
#ifdef HAVE_TERMIOS
  /* If we try this, we get hit with SIGTTIN, because
     the child's tty belongs to the child's pgrp. */
#else
#ifdef TCFLSH
  ioctl (channel, TCFLSH, 1);
#else
#ifdef TIOCFLUSH
  int zero = 0;
  /* 3rd arg should be ignored
     but some 4.2 kernels actually want the address of an int
     and nonzero means something different.  */
  ioctl (channel, TIOCFLUSH, &zero);
#endif
#endif
#endif
}
538

Jim Blandy's avatar
Jim Blandy committed
539 540 541 542 543 544
#ifndef VMS
/*  Set up the terminal at the other end of a pseudo-terminal that
    we will be controlling an inferior through.
    It should not echo or do line-editing, since that is done
    in Emacs.  No padding needed for insertion into an Emacs buffer.  */

545
void
Jim Blandy's avatar
Jim Blandy committed
546 547 548
child_setup_tty (out)
     int out;
{
549
#ifndef DOS_NT
Jim Blandy's avatar
Jim Blandy committed
550 551 552
  struct emacs_tty s;

  EMACS_GET_TTY (out, &s);
Jim Blandy's avatar
Jim Blandy committed
553

554
#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
Jim Blandy's avatar
Jim Blandy committed
555 556
  s.main.c_oflag |= OPOST;	/* Enable output postprocessing */
  s.main.c_oflag &= ~ONLCR;	/* Disable map of NL to CR-NL on output */
557
#ifdef NLDLY
Jim Blandy's avatar
Jim Blandy committed
558 559
  s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
  				/* No output delays */
560
#endif
Jim Blandy's avatar
Jim Blandy committed
561 562
  s.main.c_lflag &= ~ECHO;	/* Disable echo */
  s.main.c_lflag |= ISIG;	/* Enable signals */
563 564 565
#ifdef IUCLC
  s.main.c_iflag &= ~IUCLC;	/* Disable downcasing on input.  */
#endif
566 567 568
#ifdef ISTRIP
  s.main.c_iflag &= ~ISTRIP;	/* don't strip 8th bit on input */
#endif
569
#ifdef OLCUC
570 571
  s.main.c_oflag &= ~OLCUC;	/* Disable upcasing on output.  */
#endif
572
  s.main.c_oflag &= ~TAB3;	/* Disable tab expansion */
573
  s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */
Jim Blandy's avatar
Jim Blandy committed
574
#if 0
575
  /* Said to be unnecessary:  */
Jim Blandy's avatar
Jim Blandy committed
576 577 578 579 580 581
  s.main.c_cc[VMIN] = 1;	/* minimum number of characters to accept  */
  s.main.c_cc[VTIME] = 0;	/* wait forever for at least 1 character  */
#endif

  s.main.c_lflag |= ICANON;	/* Enable erase/kill and eof processing */
  s.main.c_cc[VEOF] = 04;	/* insure that EOF is Control-D */
582 583
  s.main.c_cc[VERASE] = CDISABLE;	/* disable erase processing */
  s.main.c_cc[VKILL] = CDISABLE;	/* disable kill processing */
Jim Blandy's avatar
Jim Blandy committed
584

Jim Blandy's avatar
Jim Blandy committed
585
#ifdef HPUX
Jim Blandy's avatar
Jim Blandy committed
586
  s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
Jim Blandy's avatar
Jim Blandy committed
587
#endif /* HPUX */
Jim Blandy's avatar
Jim Blandy committed
588

Jim Blandy's avatar
Jim Blandy committed
589 590 591
#ifdef AIX
/* AIX enhanced edit loses NULs, so disable it */
#ifndef IBMR2AIX
Jim Blandy's avatar
Jim Blandy committed
592 593
  s.main.c_line = 0;
  s.main.c_iflag &= ~ASCEDIT;
Jim Blandy's avatar
Jim Blandy committed
594 595 596
#endif
  /* Also, PTY overloads NUL and BREAK.
     don't ignore break, but don't signal either, so it looks like NUL.  */
Jim Blandy's avatar
Jim Blandy committed
597 598 599 600
  s.main.c_iflag &= ~IGNBRK;
  s.main.c_iflag &= ~BRKINT;
  /* QUIT and INTR work better as signals, so disable character forms */
  s.main.c_cc[VINTR] = 0377;
601 602 603 604 605 606 607 608 609 610 611
#ifdef SIGNALS_VIA_CHARACTERS
  /* the QUIT and INTR character are used in process_send_signal
     so set them here to something useful.  */
  if (s.main.c_cc[VQUIT] == 0377)
    s.main.c_cc[VQUIT] = '\\'&037;	/* Control-\ */
  if (s.main.c_cc[VINTR] == 0377)
    s.main.c_cc[VINTR] = 'C'&037;	/* Control-C */
#else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
  /* QUIT and INTR work better as signals, so disable character forms */
  s.main.c_cc[VQUIT] = 0377;
  s.main.c_cc[VINTR] = 0377;
Jim Blandy's avatar
Jim Blandy committed
612
  s.main.c_lflag &= ~ISIG;
613 614
#endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
  s.main.c_cc[VEOL] = 0377;
Jim Blandy's avatar
Jim Blandy committed
615
  s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
Jim Blandy's avatar
Jim Blandy committed
616 617 618
#endif /* AIX */

#else /* not HAVE_TERMIO */
Jim Blandy's avatar
Jim Blandy committed
619 620 621

  s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE
		       | CBREAK | TANDEM);
622
  s.main.sg_flags |= LPASS8;
Jim Blandy's avatar
Jim Blandy committed
623 624
  s.main.sg_erase = 0377;
  s.main.sg_kill = 0377;
625
  s.lmode = LLITOUT | s.lmode;        /* Don't strip 8th bit */
Jim Blandy's avatar
Jim Blandy committed
626

Jim Blandy's avatar
Jim Blandy committed
627 628
#endif /* not HAVE_TERMIO */

Jim Blandy's avatar
Jim Blandy committed
629
  EMACS_SET_TTY (out, &s, 0);
Jim Blandy's avatar
Jim Blandy committed
630 631 632 633 634 635 636 637 638 639 640

#ifdef BSD4_1
  if (interrupt_input)
    reset_sigio ();
#endif /* BSD4_1 */
#ifdef RTU
  {
    int zero = 0;
    ioctl (out, FIOASYNC, &zero);
  }
#endif /* RTU */
641
#endif /* not DOS_NT */
Jim Blandy's avatar
Jim Blandy committed
642 643 644 645
}
#endif /* not VMS */

#endif /* subprocesses */
646

Jim Blandy's avatar
Jim Blandy committed
647 648 649 650
/* Record a signal code and the handler for it.  */
struct save_signal
{
  int code;
Andreas Schwab's avatar
Andreas Schwab committed
651
  SIGTYPE (*handler) P_ ((int));
Jim Blandy's avatar
Jim Blandy committed
652 653
};

Andreas Schwab's avatar
Andreas Schwab committed
654 655 656
static void save_signal_handlers P_ ((struct save_signal *));
static void restore_signal_handlers P_ ((struct save_signal *));

Jim Blandy's avatar
Jim Blandy committed
657 658
/* Suspend the Emacs process; give terminal to its superior.  */

659
void
Jim Blandy's avatar
Jim Blandy committed
660 661 662
sys_suspend ()
{
#ifdef VMS
663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
  /* "Foster" parentage allows emacs to return to a subprocess that attached
     to the current emacs as a cheaper than starting a whole new process.  This
     is set up by KEPTEDITOR.COM.  */
  unsigned long parent_id, foster_parent_id;
  char *fpid_string;

  fpid_string = getenv ("EMACS_PARENT_PID");
  if (fpid_string != NULL)
    {
      sscanf (fpid_string, "%x", &foster_parent_id);
      if (foster_parent_id != 0)
	parent_id = foster_parent_id;
      else
	parent_id = getppid ();
    }
  else
    parent_id = getppid ();

681
  xfree (fpid_string);		/* On VMS, this was malloc'd */
Jim Blandy's avatar
Jim Blandy committed
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697

  if (parent_id && parent_id != 0xffffffff)
    {
      SIGTYPE (*oldsig)() = (int) signal (SIGINT, SIG_IGN);
      int status = LIB$ATTACH (&parent_id) & 1;
      signal (SIGINT, oldsig);
      return status;
    }
  else
    {
      struct {
	int	l;
	char	*a;
      } d_prompt;
      d_prompt.l = sizeof ("Emacs: ");		/* Our special prompt */
      d_prompt.a = "Emacs: ";			/* Just a reminder */
698
      LIB$SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt, 0);
Jim Blandy's avatar
Jim Blandy committed
699 700 701 702
      return 1;
    }
  return -1;
#else
703
#if defined (SIGTSTP) && !defined (MSDOS)
Jim Blandy's avatar
Jim Blandy committed
704

705
  {
706
    int pgrp = EMACS_GETPGRP (0);
707 708
    EMACS_KILLPG (pgrp, SIGTSTP);
  }
Jim Blandy's avatar
Jim Blandy committed
709 710 711 712 713 714 715 716 717 718 719

#else /* No SIGTSTP */
#ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
  ptrace (0, 0, 0, 0);		/* set for ptrace - caught by csh */
  kill (getpid (), SIGQUIT);

#else /* No SIGTSTP or USG_JOBCTRL */

/* On a system where suspending is not implemented,
   instead fork a subshell and let it talk directly to the terminal
   while we wait.  */
720 721 722 723 724 725 726 727 728
  sys_subshell ();

#endif /* no USG_JOBCTRL */
#endif /* no SIGTSTP */
#endif /* not VMS */
}

/* Fork a subshell.  */

729
void
730 731
sys_subshell ()
{
732 733 734
#ifdef macintosh
    error ("Can't spawn subshell");
#else
735
#ifndef VMS
736
#ifdef DOS_NT	/* Demacs 1.1.2 91/10/20 Manabu Higashida */
737 738 739
  int st;
  char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS.  */
#endif
740
  int pid;
Jim Blandy's avatar
Jim Blandy committed
741
  struct save_signal saved_handlers[5];
742 743 744
  Lisp_Object dir;
  unsigned char *str = 0;
  int len;
Jim Blandy's avatar
Jim Blandy committed
745 746 747 748 749 750 751 752 753 754 755

  saved_handlers[0].code = SIGINT;
  saved_handlers[1].code = SIGQUIT;
  saved_handlers[2].code = SIGTERM;
#ifdef SIGIO
  saved_handlers[3].code = SIGIO;
  saved_handlers[4].code = 0;
#else
  saved_handlers[3].code = 0;
#endif

756 757 758 759
  /* Mentioning current_buffer->buffer would mean including buffer.h,
     which somehow wedges the hp compiler.  So instead...  */

  dir = intern ("default-directory");
760
  if (NILP (Fboundp (dir)))
761 762
    goto xyzzy;
  dir = Fsymbol_value (dir);
763
  if (!STRINGP (dir))
764 765 766 767 768 769 770 771 772 773
    goto xyzzy;

  dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil);
  str = (unsigned char *) alloca (XSTRING (dir)->size + 2);
  len = XSTRING (dir)->size;
  bcopy (XSTRING (dir)->data, str, len);
  if (str[len - 1] != '/') str[len++] = '/';
  str[len] = 0;
 xyzzy:

774
#ifdef DOS_NT
775
  pid = 0;
776 777 778 779
#if __DJGPP__ > 1
  save_signal_handlers (saved_handlers);
  synch_process_alive = 1;
#endif /* __DJGPP__ > 1 */
780
#else  
781
  pid = vfork ();
Jim Blandy's avatar
Jim Blandy committed
782 783
  if (pid == -1)
    error ("Can't spawn subshell");
784 785
#endif

Jim Blandy's avatar
Jim Blandy committed
786 787
  if (pid == 0)
    {
788
      char *sh = 0;
Jim Blandy's avatar
Jim Blandy committed
789

790
#ifdef DOS_NT    /* MW, Aug 1993 */
791
      getwd (oldwd);
792 793
      if (sh == 0)
	sh = (char *) egetenv ("SUSPEND");	/* KFS, 1994-12-14 */
794
#endif
795 796
      if (sh == 0)
	sh = (char *) egetenv ("SHELL");
Jim Blandy's avatar
Jim Blandy committed
797 798
      if (sh == 0)
	sh = "sh";
799

Jim Blandy's avatar
Jim Blandy committed
800
      /* Use our buffer's default directory for the subshell.  */
801
      if (str)
802
	chdir ((char *) str);
803

Jim Blandy's avatar
Jim Blandy committed
804 805 806
#ifdef subprocesses
      close_process_descs ();	/* Close Emacs's pipes/ptys */
#endif
807

808
#ifdef SET_EMACS_PRIORITY
809 810 811
      {
	extern int emacs_priority;

812
	if (emacs_priority < 0)
813 814 815 816
	  nice (-emacs_priority);
      }
#endif

817
#ifdef MSDOS    /* Demacs 1.1.2 91/10/20 Manabu Higashida */
818 819
      st = system (sh);
      chdir (oldwd);
820
#if 0	/* This is also reported if last command executed in subshell failed, KFS */
821
      if (st)
822
	report_file_error ("Can't execute subshell", Fcons (build_string (sh), Qnil));
823
#endif
824
#else /* not MSDOS */
825 826 827
#ifdef  WINDOWSNT
      /* Waits for process completion */
      pid = _spawnlp (_P_WAIT, sh, sh, NULL);
828
      chdir (oldwd);
829 830 831
      if (pid == -1)
	write (1, "Can't execute subshell", 22);
#else   /* not WINDOWSNT */
Jim Blandy's avatar
Jim Blandy committed
832 833 834
      execlp (sh, sh, 0);
      write (1, "Can't execute subshell", 22);
      _exit (1);
835
#endif  /* not WINDOWSNT */
836
#endif /* not MSDOS */
Jim Blandy's avatar
Jim Blandy committed
837 838
    }

839 840
  /* Do this now if we did not do it before.  */
#if !defined (MSDOS) || __DJGPP__ == 1
Jim Blandy's avatar
Jim Blandy committed
841
  save_signal_handlers (saved_handlers);
842
  synch_process_alive = 1;
843 844
#endif

845
#ifndef DOS_NT
Jim Blandy's avatar
Jim Blandy committed
846
  wait_for_termination (pid);
847
#endif
Jim Blandy's avatar
Jim Blandy committed
848
  restore_signal_handlers (saved_handlers);
849
  synch_process_alive = 0;
850
#endif /* !VMS */
851
#endif /* !macintosh */
Jim Blandy's avatar
Jim Blandy committed
852 853
}

Andreas Schwab's avatar
Andreas Schwab committed
854
static void
Jim Blandy's avatar
Jim Blandy committed
855 856 857 858 859
save_signal_handlers (saved_handlers)
     struct save_signal *saved_handlers;
{
  while (saved_handlers->code)
    {
Joseph Arceneaux's avatar
Joseph Arceneaux committed
860
      saved_handlers->handler
Andreas Schwab's avatar
Andreas Schwab committed
861
	= (SIGTYPE (*) P_ ((int))) signal (saved_handlers->code, SIG_IGN);
Jim Blandy's avatar
Jim Blandy committed
862 863 864 865
      saved_handlers++;
    }
}

Andreas Schwab's avatar
Andreas Schwab committed
866
static void
Jim Blandy's avatar
Jim Blandy committed
867 868 869 870 871 872 873 874 875 876 877 878 879 880
restore_signal_handlers (saved_handlers)
     struct save_signal *saved_handlers;
{
  while (saved_handlers->code)
    {
      signal (saved_handlers->code, saved_handlers->handler);
      saved_handlers++;
    }
}

#ifdef F_SETFL

int old_fcntl_flags;

881
void
882 883
init_sigio (fd)
     int fd;
Jim Blandy's avatar
Jim Blandy committed
884 885
{
#ifdef FASYNC
886 887
  old_fcntl_flags = fcntl (fd, F_GETFL, 0) & ~FASYNC;
  fcntl (fd, F_SETFL, old_fcntl_flags | FASYNC);
Jim Blandy's avatar
Jim Blandy committed
888
#endif
889
  interrupts_deferred = 0;
Jim Blandy's avatar
Jim Blandy committed
890 891
}

Andreas Schwab's avatar
Andreas Schwab committed
892
void
Jim Blandy's avatar
Jim Blandy committed
893 894 895 896 897
reset_sigio ()
{
  unrequest_sigio ();
}

898
#ifdef FASYNC		/* F_SETFL does not imply existence of FASYNC */
Jim Blandy's avatar
Jim Blandy committed
899

900
void
Jim Blandy's avatar
Jim Blandy committed
901 902
request_sigio ()
{
903 904 905
  if (read_socket_hook)
    return;

Jim Blandy's avatar
Jim Blandy committed
906
#ifdef SIGWINCH
Jim Blandy's avatar
Jim Blandy committed
907
  sigunblock (sigmask (SIGWINCH));
Jim Blandy's avatar
Jim Blandy committed
908
#endif
909
  fcntl (input_fd, F_SETFL, old_fcntl_flags | FASYNC);
Jim Blandy's avatar
Jim Blandy committed
910 911 912 913

  interrupts_deferred = 0;
}

914
void
Jim Blandy's avatar
Jim Blandy committed
915 916
unrequest_sigio ()
{
917 918 919
  if (read_socket_hook)
    return;

Jim Blandy's avatar
Jim Blandy committed
920
#ifdef SIGWINCH
Jim Blandy's avatar
Jim Blandy committed
921
  sigblock (sigmask (SIGWINCH));
Jim Blandy's avatar
Jim Blandy committed
922
#endif
923
  fcntl (input_fd, F_SETFL, old_fcntl_flags);
Jim Blandy's avatar
Jim Blandy committed
924 925 926 927 928 929
  interrupts_deferred = 1;
}

#else /* no FASYNC */
#ifdef STRIDE		/* Stride doesn't have FASYNC - use FIOASYNC */

930
void
Jim Blandy's avatar
Jim Blandy committed
931 932 933
request_sigio ()
{
  int on = 1;
934 935 936 937

  if (read_socket_hook)
    return;

938
  ioctl (input_fd, FIOASYNC, &on);
Jim Blandy's avatar
Jim Blandy committed
939 940 941
  interrupts_deferred = 0;
}

942
void
Jim Blandy's avatar
Jim Blandy committed
943 944 945 946
unrequest_sigio ()
{
  int off = 0;

947 948 949
  if (read_socket_hook)
    return;

950
  ioctl (input_fd, FIOASYNC, &off);
Jim Blandy's avatar
Jim Blandy committed
951 952 953 954 955
  interrupts_deferred = 1;
}

#else /* not FASYNC, not STRIDE */
 
956 957 958 959
#ifdef _CX_UX

#include <termios.h>

960
void
961 962 963 964 965
request_sigio ()
{
  int on = 1;
  sigset_t st;

966 967 968
  if (read_socket_hook)
    return;

969 970
  sigemptyset (&st);
  sigaddset (&st, SIGIO);
971 972
  ioctl (input_fd, FIOASYNC, &on);
  interrupts_deferred = 0;
973
  sigprocmask (SIG_UNBLOCK, &st, (sigset_t *)0);
974 975
}

976
void
977 978 979 980
unrequest_sigio ()
{
  int off = 0;

981 982 983
  if (read_socket_hook)
    return;

984 985 986 987 988 989
  ioctl (input_fd, FIOASYNC, &off);
  interrupts_deferred = 1;
}

#else /* ! _CX_UX */

990
void
Jim Blandy's avatar
Jim Blandy committed
991 992
request_sigio ()
{
993 994 995
  if (read_socket_hook)
    return;

Jim Blandy's avatar
Jim Blandy committed
996 997 998
  croak ("request_sigio");
}
 
999
void
Jim Blandy's avatar
Jim Blandy committed
1000 1001
unrequest_sigio ()
{
1002 1003 1004
  if (read_socket_hook)
    return;

Jim Blandy's avatar
Jim Blandy committed
1005 1006 1007
  croak ("unrequest_sigio");
}
 
1008
#endif /* _CX_UX */
Jim Blandy's avatar
Jim Blandy committed
1009 1010 1011
#endif /* STRIDE */
#endif /* FASYNC */
#endif /* F_SETFL */
1012

1013 1014
/* Saving and restoring the process group of Emacs's terminal.  */