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
#ifdef WINDOWSNT
51 52
#define read sys_read
#define write sys_write
53 54 55 56
#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
#ifdef HAVE_SETPGID
79
#if !defined (USG) || defined (BSD_PGRPS)
80 81
#define setpgrp setpgid
#endif
82
#endif
83

84 85 86 87 88
/* Get SI_SRPC_DOMAIN, if it is available.  */
#ifdef HAVE_SYS_SYSTEMINFO_H
#include <sys/systeminfo.h>
#endif

89 90 91 92 93
#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>
94 95 96 97 98

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

101
#ifndef errno
Jim Blandy's avatar
Jim Blandy committed
102
extern int errno;
103
#endif
Jim Blandy's avatar
Jim Blandy committed
104

105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
#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
125
#define MAXIOSIZE (32 * PAGESIZE) /* Don't I/O more than 32 blocks at a time */
126 127 128
#endif /* VMS */

#ifndef BSD4_1
129
#ifdef BSD_SYSTEM /* avoid writing defined (BSD_SYSTEM) || defined (USG)
130 131 132 133 134 135 136 137 138
	      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
139

140
#ifndef MSDOS
Jim Blandy's avatar
Jim Blandy committed
141
#include <sys/ioctl.h>
142
#endif
143

144
#include "systty.h"
Richard M. Stallman's avatar
Richard M. Stallman committed
145
#include "syswait.h"
Jim Blandy's avatar
Jim Blandy committed
146 147 148

#ifdef BROKEN_TIOCGWINSZ
#undef TIOCGWINSZ
149
#undef TIOCSWINSZ
Jim Blandy's avatar
Jim Blandy committed
150 151
#endif

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

extern int quit_char;

Jim Blandy's avatar
Jim Blandy committed
171
#include "frame.h"
Jim Blandy's avatar
Jim Blandy committed
172 173 174 175 176 177 178
#include "window.h"
#include "termhooks.h"
#include "termchar.h"
#include "termopts.h"
#include "dispextern.h"
#include "process.h"

179 180 181 182 183 184 185 186
#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
187 188 189 190
#ifdef NONSYSTEM_DIR_LIBRARY
#include "ndir.h"
#endif /* NONSYSTEM_DIR_LIBRARY */

Jim Blandy's avatar
Jim Blandy committed
191 192
#include "syssignal.h"
#include "systime.h"
193 194 195 196 197 198 199 200 201 202 203 204 205 206
#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
207

208 209 210 211
#ifndef VFORK_RETURN_TYPE
#define VFORK_RETURN_TYPE int
#endif

212 213 214 215 216 217 218 219 220
/* 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
221 222 223 224 225 226 227 228 229 230
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

231 232 233
#if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
extern short ospeed;
#else
Richard M. Stallman's avatar
Richard M. Stallman committed
234 235
#if defined (HAVE_TERMIOS_H) && defined (LINUX)
#include <termios.h>
236 237
/* 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.  */
238 239
extern speed_t ospeed;
#else
Karl Heuer's avatar
Karl Heuer committed
240
extern short ospeed;
241
#endif
242
#endif
Jim Blandy's avatar
Jim Blandy committed
243

Jim Blandy's avatar
Jim Blandy committed
244
/* The file descriptor for Emacs's input terminal.
245 246 247
   Under Unix, this is normally zero except when using X;
   under VMS, we place the input channel number here.  */
int input_fd;
248 249 250

void croak P_ ((char *));

251 252 253 254
#ifdef AIXHFT
void hft_init ();
void hft_reset ();
#endif
255

256 257 258 259 260 261 262 263 264 265 266

/* 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
267

268
void
Jim Blandy's avatar
Jim Blandy committed
269 270
discard_tty_input ()
{
271
#ifndef WINDOWSNT
Jim Blandy's avatar
Jim Blandy committed
272
  struct emacs_tty buf;
Jim Blandy's avatar
Jim Blandy committed
273 274 275 276 277 278 279 280 281 282 283

  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
284 285
  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
286 287 288 289 290
  queue_kbd_input ();
#else /* not VMS */
#ifdef APOLLO
  {
    int zero = 0;
291
    ioctl (input_fd, TIOCFLUSH, &zero);
Jim Blandy's avatar
Jim Blandy committed
292 293
  }
#else /* not Apollo */
294
#ifdef MSDOS    /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
295
  while (dos_keyread () != -1)
296
    ;
297
#else /* not MSDOS */
Jim Blandy's avatar
Jim Blandy committed
298 299
  EMACS_GET_TTY (input_fd, &buf);
  EMACS_SET_TTY (input_fd, &buf, 0);
300
#endif /* not MSDOS */
Jim Blandy's avatar
Jim Blandy committed
301 302
#endif /* not Apollo */
#endif /* not VMS */
303
#endif /* not WINDOWSNT */
Jim Blandy's avatar
Jim Blandy committed
304 305 306 307
}

#ifdef SIGTSTP

308 309 310
/* Arrange for character C to be read as the next input from
   the terminal.  */

Andreas Schwab's avatar
Andreas Schwab committed
311
void
Jim Blandy's avatar
Jim Blandy committed
312 313 314
stuff_char (c)
     char c;
{
315 316 317
  if (read_socket_hook)
    return;

Jim Blandy's avatar
Jim Blandy committed
318 319
/* Should perhaps error if in batch mode */
#ifdef TIOCSTI
320
  ioctl (input_fd, TIOCSTI, &c);
Jim Blandy's avatar
Jim Blandy committed
321
#else /* no TIOCSTI */
322
  error ("Cannot stuff terminal input characters in this version of Unix");
Jim Blandy's avatar
Jim Blandy committed
323 324 325 326
#endif /* no TIOCSTI */
}

#endif /* SIGTSTP */
327

328
void
Jim Blandy's avatar
Jim Blandy committed
329 330 331 332 333 334
init_baud_rate ()
{
  if (noninteractive)
    ospeed = 0;
  else
    {
335 336 337
#ifdef INIT_BAUD_RATE
      INIT_BAUD_RATE ();
#else
338
#ifdef DOS_NT
339
    ospeed = 15;
340
#else  /* not DOS_NT */
Jim Blandy's avatar
Jim Blandy committed
341
#ifdef VMS
Jim Blandy's avatar
Jim Blandy committed
342 343 344
      struct sensemode sg;

      SYS$QIOW (0, input_fd, IO$_SENSEMODE, &sg, 0, 0,
Jim Blandy's avatar
Jim Blandy committed
345
		&sg.class, 12, 0, 0, 0, 0 );
Jim Blandy's avatar
Jim Blandy committed
346 347
      ospeed = sg.xmit_baud;
#else /* not VMS */
348 349
#ifdef HAVE_TERMIOS
      struct termios sg;
Jim Blandy's avatar
Jim Blandy committed
350

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

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

/*ARGSUSED*/
Andreas Schwab's avatar
Andreas Schwab committed
391
void
Jim Blandy's avatar
Jim Blandy committed
392 393 394 395 396 397 398 399
set_exclusive_use (fd)
     int fd;
{
#ifdef FIOCLEX
  ioctl (fd, FIOCLEX, 0);
#endif
  /* Ok to do nothing if this feature does not exist */
}
400

Jim Blandy's avatar
Jim Blandy committed
401 402 403 404
#ifndef subprocesses

wait_without_blocking ()
{
405
#ifdef BSD_SYSTEM
Jim Blandy's avatar
Jim Blandy committed
406 407 408 409 410 411 412 413 414 415
  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
416
			 (at least for bsd).  */
Jim Blandy's avatar
Jim Blandy committed
417 418 419 420 421 422 423 424

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) */

425
void
Jim Blandy's avatar
Jim Blandy committed
426 427 428 429 430 431 432 433 434
wait_for_termination (pid)
     int pid;
{
  while (1)
    {
#ifdef subprocesses
#ifdef VMS
      int status;

435
      status = SYS$FORCEX (&pid, 0, 0);
Jim Blandy's avatar
Jim Blandy committed
436 437
      break;
#else /* not VMS */
438
#if defined (BSD_SYSTEM) || (defined (HPUX) && !defined (HPUX_5))
439 440 441 442 443 444 445 446 447
      /* 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))
448
	{
449 450 451 452 453 454 455 456
	  sigsetmask (SIGEMPTYMASK);
	  kill (getpid (), SIGCHLD);
	  break;
	}
      if (wait_debugging)
	sleep (1);
      else
	sigpause (SIGEMPTYMASK);
457
#else /* not BSD_SYSTEM, and not HPUX version >= 6 */
458
#if defined (UNIPLUS)
459 460 461
      if (0 > kill (pid, 0))
	break;
      wait (0);
462
#else /* neither BSD_SYSTEM nor UNIPLUS: random sysV */
463
#ifdef POSIX_SIGNALS    /* would this work for LINUX as well? */
464 465 466 467 468 469
      sigblock (sigmask (SIGCHLD));
      if (0 > kill (pid, 0))
	{
	  sigunblock (sigmask (SIGCHLD));
	  break;
	}
470
      sigpause (SIGEMPTYMASK);
471
#else /* not POSIX_SIGNALS */
472 473 474 475 476 477 478 479 480
#ifdef HAVE_SYSV_SIGPAUSE
      sighold (SIGCHLD);
      if (0 > kill (pid, 0))
	{
	  sigrelse (SIGCHLD);
	  break;
	}
      sigpause (SIGCHLD);
#else /* not HAVE_SYSV_SIGPAUSE */
481 482 483 484
#ifdef WINDOWSNT
      wait (0);
      break;
#else /* not WINDOWSNT */
485
      if (0 > kill (pid, 0))
Jim Blandy's avatar
Jim Blandy committed
486
	break;
487 488 489 490
      /* Using sleep instead of pause avoids timing error.
	 If the inferior dies just before the sleep,
	 we lose just one second.  */
      sleep (1);
491
#endif /* not WINDOWSNT */
492
#endif /* not HAVE_SYSV_SIGPAUSE */
493
#endif /* not POSIX_SIGNALS */
494
#endif /* not UNIPLUS */
495
#endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
Jim Blandy's avatar
Jim Blandy committed
496 497
#endif /* not VMS */
#else /* not subprocesses */
498 499 500
#if __DJGPP__ > 1
      break;
#else /* not __DJGPP__ > 1 */
Jim Blandy's avatar
Jim Blandy committed
501 502 503 504 505 506 507 508 509 510
#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 */
511
#endif /* not __DJGPP__ > 1*/
Jim Blandy's avatar
Jim Blandy committed
512 513 514 515 516 517 518 519 520 521 522
#endif /* not subprocesses */
    }
}

#ifdef subprocesses

/*
 *	flush any pending output
 *      (may flush input as well; it does not matter the way we use it)
 */
 
523
void
Jim Blandy's avatar
Jim Blandy committed
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543
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
}
544

Jim Blandy's avatar
Jim Blandy committed
545 546 547 548 549 550
#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.  */

551
void
Jim Blandy's avatar
Jim Blandy committed
552 553 554
child_setup_tty (out)
     int out;
{
555
#ifndef DOS_NT
Jim Blandy's avatar
Jim Blandy committed
556 557 558
  struct emacs_tty s;

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

560
#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
Jim Blandy's avatar
Jim Blandy committed
561 562
  s.main.c_oflag |= OPOST;	/* Enable output postprocessing */
  s.main.c_oflag &= ~ONLCR;	/* Disable map of NL to CR-NL on output */
563
#ifdef NLDLY
Jim Blandy's avatar
Jim Blandy committed
564 565
  s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
  				/* No output delays */
566
#endif
Jim Blandy's avatar
Jim Blandy committed
567 568
  s.main.c_lflag &= ~ECHO;	/* Disable echo */
  s.main.c_lflag |= ISIG;	/* Enable signals */
569 570 571
#ifdef IUCLC
  s.main.c_iflag &= ~IUCLC;	/* Disable downcasing on input.  */
#endif
572 573 574
#ifdef ISTRIP
  s.main.c_iflag &= ~ISTRIP;	/* don't strip 8th bit on input */
#endif
575
#ifdef OLCUC
576 577
  s.main.c_oflag &= ~OLCUC;	/* Disable upcasing on output.  */
#endif
578
  s.main.c_oflag &= ~TAB3;	/* Disable tab expansion */
579
  s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */
Jim Blandy's avatar
Jim Blandy committed
580
#if 0
581
  /* Said to be unnecessary:  */
Jim Blandy's avatar
Jim Blandy committed
582 583 584 585 586 587
  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 */
588 589
  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
590

Jim Blandy's avatar
Jim Blandy committed
591
#ifdef HPUX
Jim Blandy's avatar
Jim Blandy committed
592
  s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
Jim Blandy's avatar
Jim Blandy committed
593
#endif /* HPUX */
Jim Blandy's avatar
Jim Blandy committed
594

Jim Blandy's avatar
Jim Blandy committed
595 596 597
#ifdef AIX
/* AIX enhanced edit loses NULs, so disable it */
#ifndef IBMR2AIX
Jim Blandy's avatar
Jim Blandy committed
598 599
  s.main.c_line = 0;
  s.main.c_iflag &= ~ASCEDIT;
Jim Blandy's avatar
Jim Blandy committed
600 601 602
#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
603 604 605 606
  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;
607 608 609 610 611 612 613 614 615 616 617
#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
618
  s.main.c_lflag &= ~ISIG;
619 620
#endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
  s.main.c_cc[VEOL] = 0377;
Jim Blandy's avatar
Jim Blandy committed
621
  s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
Jim Blandy's avatar
Jim Blandy committed
622 623 624
#endif /* AIX */

#else /* not HAVE_TERMIO */
Jim Blandy's avatar
Jim Blandy committed
625 626 627

  s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE
		       | CBREAK | TANDEM);
628
  s.main.sg_flags |= LPASS8;
Jim Blandy's avatar
Jim Blandy committed
629 630
  s.main.sg_erase = 0377;
  s.main.sg_kill = 0377;
631
  s.lmode = LLITOUT | s.lmode;        /* Don't strip 8th bit */
Jim Blandy's avatar
Jim Blandy committed
632

Jim Blandy's avatar
Jim Blandy committed
633 634
#endif /* not HAVE_TERMIO */

Jim Blandy's avatar
Jim Blandy committed
635
  EMACS_SET_TTY (out, &s, 0);
Jim Blandy's avatar
Jim Blandy committed
636 637 638 639 640 641 642 643 644 645 646

#ifdef BSD4_1
  if (interrupt_input)
    reset_sigio ();
#endif /* BSD4_1 */
#ifdef RTU
  {
    int zero = 0;
    ioctl (out, FIOASYNC, &zero);
  }
#endif /* RTU */
647
#endif /* not DOS_NT */
Jim Blandy's avatar
Jim Blandy committed
648 649 650 651
}
#endif /* not VMS */

#endif /* subprocesses */
652

Jim Blandy's avatar
Jim Blandy committed
653 654 655 656
/* Record a signal code and the handler for it.  */
struct save_signal
{
  int code;
Andreas Schwab's avatar
Andreas Schwab committed
657
  SIGTYPE (*handler) P_ ((int));
Jim Blandy's avatar
Jim Blandy committed
658 659
};

Andreas Schwab's avatar
Andreas Schwab committed
660 661 662
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
663 664
/* Suspend the Emacs process; give terminal to its superior.  */

665
void
Jim Blandy's avatar
Jim Blandy committed
666 667 668
sys_suspend ()
{
#ifdef VMS
669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686
  /* "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 ();

687
  xfree (fpid_string);		/* On VMS, this was malloc'd */
Jim Blandy's avatar
Jim Blandy committed
688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703

  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 */
704
      LIB$SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt, 0);
Jim Blandy's avatar
Jim Blandy committed
705 706 707 708
      return 1;
    }
  return -1;
#else
709
#if defined (SIGTSTP) && !defined (MSDOS)
Jim Blandy's avatar
Jim Blandy committed
710

711
  {
712
    int pgrp = EMACS_GETPGRP (0);
713 714
    EMACS_KILLPG (pgrp, SIGTSTP);
  }
Jim Blandy's avatar
Jim Blandy committed
715 716 717 718 719 720 721 722 723 724 725

#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.  */
726 727 728 729 730 731 732 733 734
  sys_subshell ();

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

/* Fork a subshell.  */

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

  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

762 763 764 765
  /* Mentioning current_buffer->buffer would mean including buffer.h,
     which somehow wedges the hp compiler.  So instead...  */

  dir = intern ("default-directory");
766
  if (NILP (Fboundp (dir)))
767 768
    goto xyzzy;
  dir = Fsymbol_value (dir);
769
  if (!STRINGP (dir))
770 771 772 773 774 775 776 777 778 779
    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:

780
#ifdef DOS_NT
781
  pid = 0;
782 783 784 785
#if __DJGPP__ > 1
  save_signal_handlers (saved_handlers);
  synch_process_alive = 1;
#endif /* __DJGPP__ > 1 */
786
#else  
787
  pid = vfork ();
Jim Blandy's avatar
Jim Blandy committed
788 789
  if (pid == -1)
    error ("Can't spawn subshell");
790 791
#endif

Jim Blandy's avatar
Jim Blandy committed
792 793
  if (pid == 0)
    {
794
      char *sh = 0;
Jim Blandy's avatar
Jim Blandy committed
795

796
#ifdef DOS_NT    /* MW, Aug 1993 */
797
      getwd (oldwd);
798 799
      if (sh == 0)
	sh = (char *) egetenv ("SUSPEND");	/* KFS, 1994-12-14 */
800
#endif
801 802
      if (sh == 0)
	sh = (char *) egetenv ("SHELL");
Jim Blandy's avatar
Jim Blandy committed
803 804
      if (sh == 0)
	sh = "sh";
805

Jim Blandy's avatar
Jim Blandy committed
806
      /* Use our buffer's default directory for the subshell.  */
807
      if (str)
808
	chdir ((char *) str);
809

Jim Blandy's avatar
Jim Blandy committed
810 811 812
#ifdef subprocesses
      close_process_descs ();	/* Close Emacs's pipes/ptys */
#endif
813

814
#ifdef SET_EMACS_PRIORITY
815 816 817
      {
	extern int emacs_priority;

818
	if (emacs_priority < 0)
819 820 821 822
	  nice (-emacs_priority);
      }
#endif

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

845 846
  /* Do this now if we did not do it before.  */
#if !defined (MSDOS) || __DJGPP__ == 1
Jim Blandy's avatar
Jim Blandy committed
847
  save_signal_handlers (saved_handlers);
848
  synch_process_alive = 1;
849 850
#endif

851
#ifndef DOS_NT
Jim Blandy's avatar
Jim Blandy committed
852
  wait_for_termination (pid);
853
#endif
Jim Blandy's avatar
Jim Blandy committed
854
  restore_signal_handlers (saved_handlers);
855
  synch_process_alive = 0;
856
#endif /* !VMS */
857
#endif /* !macintosh */
Jim Blandy's avatar
Jim Blandy committed
858 859
}

Andreas Schwab's avatar
Andreas Schwab committed
860
static void
Jim Blandy's avatar
Jim Blandy committed
861 862 863 864 865
save_signal_handlers (saved_handlers)
     struct save_signal *saved_handlers;
{
  while (saved_handlers->code)
    {
Joseph Arceneaux's avatar
Joseph Arceneaux committed
866
      saved_handlers->handler
Andreas Schwab's avatar
Andreas Schwab committed
867
	= (SIGTYPE (*) P_ ((int))) signal (saved_handlers->code, SIG_IGN);
Jim Blandy's avatar
Jim Blandy committed
868 869 870 871
      saved_handlers++;
    }
}

Andreas Schwab's avatar
Andreas Schwab committed
872
static void
Jim Blandy's avatar
Jim Blandy committed
873 874 875 876 877 878 879 880 881 882 883 884 885 886
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;

887
void
888 889
init_sigio (fd)
     int fd;
Jim Blandy's avatar
Jim Blandy committed
890 891
{
#ifdef FASYNC
892 893
  old_fcntl_flags = fcntl (fd, F_GETFL, 0) & ~FASYNC;
  fcntl (fd, F_SETFL, old_fcntl_flags | FASYNC);
Jim Blandy's avatar
Jim Blandy committed
894
#endif
895
  interrupts_deferred = 0;
Jim Blandy's avatar
Jim Blandy committed
896 897
}

Andreas Schwab's avatar
Andreas Schwab committed
898
void
Jim Blandy's avatar
Jim Blandy committed
899 900 901 902 903
reset_sigio ()
{
  unrequest_sigio ();
}

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

906
void
Jim Blandy's avatar
Jim Blandy committed
907 908
request_sigio ()
{
909 910 911
  if (read_socket_hook)
    return;

Jim Blandy's avatar
Jim Blandy committed
912
#ifdef SIGWINCH
Jim Blandy's avatar
Jim Blandy committed
913
  sigunblock (sigmask (SIGWINCH));
Jim Blandy's avatar
Jim Blandy committed
914
#endif
915
  fcntl (input_fd, F_SETFL, old_fcntl_flags | FASYNC);
Jim Blandy's avatar
Jim Blandy committed
916 917 918 919

  interrupts_deferred = 0;
}

920
void
Jim Blandy's avatar
Jim Blandy committed
921 922
unrequest_sigio ()
{
923 924 925
  if (read_socket_hook)
    return;

Jim Blandy's avatar
Jim Blandy committed
926
#ifdef SIGWINCH
Jim Blandy's avatar
Jim Blandy committed
927
  sigblock (sigmask (SIGWINCH));
Jim Blandy's avatar
Jim Blandy committed
928
#endif
929
  fcntl (input_fd, F_SETFL, old_fcntl_flags);
Jim Blandy's avatar
Jim Blandy committed
930 931 932 933 934 935
  interrupts_deferred = 1;
}

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

936
void
Jim Blandy's avatar
Jim Blandy committed
937 938 939
request_sigio ()
{
  int on = 1;
940 941 942 943

  if (read_socket_hook)
    return;

944
  ioctl (input_fd, FIOASYNC, &on);
Jim Blandy's avatar
Jim Blandy committed
945 946 947
  interrupts_deferred = 0;
}

948
void
Jim Blandy's avatar
Jim Blandy committed
949 950 951 952
unrequest_sigio ()
{
  int off = 0;

953 954 955
  if (read_socket_hook)
    return;

956
  ioctl (input_fd, FIOASYNC, &off);
Jim Blandy's avatar
Jim Blandy committed
957 958 959 960 961
  interrupts_deferred = 1;
}

#else /* not FASYNC, not STRIDE */
 
962 963 964 965
#ifdef _CX_UX

#include <termios.h>

966
void
967 968 969 970 971
request_sigio ()
{
  int on = 1;
  sigset_t st;

972 973 974
  if (read_socket_hook)
    return;

975 976
  sigemptyset (&st);
  sigaddset (&st, SIGIO);
977 978
  ioctl (input_fd, FIOASYNC, &on);
  interrupts_deferred = 0;
979
  sigprocmask (SIG_UNBLOCK, &st, (sigset_t *)0);
980 981
}

982
void
983 984 985 986
unrequest_sigio ()
{
  int off = 0;

987 988 989
  if (read_socket_hook)
    return;

990 991 992 993 994 995
  ioctl (input_fd, FIOASYNC, &off);
  interrupts_deferred = 1;
}

#else /* ! _CX_UX */

996
void
Jim Blandy's avatar
Jim Blandy committed
997 998
request_sigio ()
{
999 1000 1001
  if (read_socket_hook)
    return;

Jim Blandy's avatar
Jim Blandy committed
1002 1003 1004
  croak ("request_sigio");
}
 
1005
void
Jim Blandy's avatar
Jim Blandy committed
1006 1007
unrequest_sigio ()
{
1008 1009 1010
  if (read_socket_hook)