sysdep.c 123 KB
Newer Older
Jim Blandy's avatar
Jim Blandy committed
1
/* Interfaces to system-dependent kernel and library entries.
Karl Heuer's avatar
Karl Heuer committed
2
   Copyright (C) 1985, 86, 87, 88, 93, 94, 95 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 23 24


#include <signal.h>
#include <setjmp.h>

25
#include <config.h>
26 27 28
#ifdef STDC_HEADERS
#include <stdlib.h>
#endif
Jim Blandy's avatar
Jim Blandy committed
29
#include "lisp.h"
30
#include "blockinput.h"
Jim Blandy's avatar
Jim Blandy committed
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
#undef NULL

#define min(x,y) ((x) > (y) ? (y) : (x))

/* In this file, open, read and write refer to the system calls,
   not our sugared interfaces  sys_open, sys_read and sys_write.
   Contrariwise, for systems where we use the system calls directly,
   define sys_read, etc. here as aliases for them.  */
#ifndef read
#define sys_read read
#define sys_write write
#endif /* `read' is not a macro */

#undef read
#undef write

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

Jim Blandy's avatar
Jim Blandy committed
54 55 56 57 58 59 60 61 62 63 64 65
#ifndef close
#define sys_close close
#else 
#undef close
#endif

#ifndef open
#define sys_open open
#else /* `open' is a macro */
#undef open
#endif /* `open' is a macro */

66 67 68 69 70 71 72
/* Does anyone other than VMS need this? */
#ifndef fwrite
#define sys_fwrite fwrite
#else
#undef fwrite
#endif

73 74 75 76
#ifndef HAVE_H_ERRNO
extern int h_errno;
#endif

Jim Blandy's avatar
Jim Blandy committed
77 78 79 80 81
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>

82 83 84 85 86
/* Get _POSIX_VDISABLE, if it is available.  */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

87 88 89 90 91
/* Get SI_SRPC_DOMAIN, if it is available.  */
#ifdef HAVE_SYS_SYSTEMINFO_H
#include <sys/systeminfo.h>
#endif

92 93 94 95 96
#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>
97 98 99 100 101

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

104
#ifndef errno
Jim Blandy's avatar
Jim Blandy committed
105
extern int errno;
106
#endif
Jim Blandy's avatar
Jim Blandy committed
107

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

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

143
#ifndef MSDOS
Jim Blandy's avatar
Jim Blandy committed
144
#include <sys/ioctl.h>
145
#endif
146

147
#include "systty.h"
Richard M. Stallman's avatar
Richard M. Stallman committed
148
#include "syswait.h"
Jim Blandy's avatar
Jim Blandy committed
149 150 151

#ifdef BROKEN_TIOCGWINSZ
#undef TIOCGWINSZ
152
#undef TIOCSWINSZ
Jim Blandy's avatar
Jim Blandy committed
153 154
#endif

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

extern int quit_char;

Jim Blandy's avatar
Jim Blandy committed
174
#include "frame.h"
Jim Blandy's avatar
Jim Blandy committed
175 176 177 178 179 180 181
#include "window.h"
#include "termhooks.h"
#include "termchar.h"
#include "termopts.h"
#include "dispextern.h"
#include "process.h"

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

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

211 212 213 214
#ifndef VFORK_RETURN_TYPE
#define VFORK_RETURN_TYPE int
#endif

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

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

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

void croak P_ ((char *));

254 255 256 257
#ifdef AIXHFT
void hft_init ();
void hft_reset ();
#endif
258

259 260 261 262 263 264 265 266 267 268 269

/* 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
270

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

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

#ifdef SIGTSTP

311 312 313
/* Arrange for character C to be read as the next input from
   the terminal.  */

Andreas Schwab's avatar
Andreas Schwab committed
314
void
Jim Blandy's avatar
Jim Blandy committed
315 316 317
stuff_char (c)
     char c;
{
318 319 320
  if (read_socket_hook)
    return;

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

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

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

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

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

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

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

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

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

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

#ifdef subprocesses

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

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

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

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

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

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

#else /* not HAVE_TERMIO */
Jim Blandy's avatar
Jim Blandy committed
628 629 630

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

Jim Blandy's avatar
Jim Blandy committed
636 637
#endif /* not HAVE_TERMIO */

Jim Blandy's avatar
Jim Blandy committed
638
  EMACS_SET_TTY (out, &s, 0);
Jim Blandy's avatar
Jim Blandy committed
639 640 641 642 643 644 645 646 647 648 649

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

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

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

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

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

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

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

#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.  */
729 730 731 732 733 734 735 736 737
  sys_subshell ();

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

/* Fork a subshell.  */

738
void
739 740 741
sys_subshell ()
{
#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 */
Jim Blandy's avatar
Jim Blandy committed
857 858
}

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

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

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

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

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

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

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

  interrupts_deferred = 0;
}

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

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

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

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

  if (read_socket_hook)
    return;

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

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

952 953 954
  if (read_socket_hook)
    return;

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

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

#include <termios.h>

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

971 972 973
  if (read_socket_hook)
    return;

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

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

986 987 988
  if (read_socket_hook)
    return;

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

#else /* ! _CX_UX */

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

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

Jim Blandy's avatar
Jim Blandy committed
1010 1011 1012
  croak ("unrequest_sigio");
}
 
1013
#endif /* _CX_UX */
Jim Blandy's avatar
Jim Blandy committed
1014 1015 1016
#endif /* STRIDE */
#endif /* FASYNC */
#endif /* F_SETFL */
1017

1018 1019
/* Saving and restoring the process group of Emacs's terminal.  */

1020
#ifdef BSD_PGRPS
1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040