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

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

void croak P_ ((char *));

256 257 258 259
#ifdef AIXHFT
void hft_init ();
void hft_reset ();
#endif
260

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

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

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

#ifdef SIGTSTP

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

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

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

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

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

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

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

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

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

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

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

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

#ifdef subprocesses

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

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

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

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

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

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

#else /* not HAVE_TERMIO */
Jim Blandy's avatar
Jim Blandy committed
630 631 632

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

Jim Blandy's avatar
Jim Blandy committed
638 639
#endif /* not HAVE_TERMIO */

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

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

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

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

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

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

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

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

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

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

/* Fork a subshell.  */

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

  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

767 768 769 770
  /* Mentioning current_buffer->buffer would mean including buffer.h,
     which somehow wedges the hp compiler.  So instead...  */

  dir = intern ("default-directory");
771
  if (NILP (Fboundp (dir)))
772 773
    goto xyzzy;
  dir = Fsymbol_value (dir);
774
  if (!STRINGP (dir))
775 776 777 778 779 780 781 782 783 784
    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:

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

Jim Blandy's avatar
Jim Blandy committed
797 798
  if (pid == 0)
    {
799
      char *sh = 0;
Jim Blandy's avatar
Jim Blandy committed
800

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

Jim Blandy's avatar
Jim Blandy committed
811
      /* Use our buffer's default directory for the subshell.  */
812
      if (str)
813
	chdir ((char *) str);
814

Jim Blandy's avatar
Jim Blandy committed
815 816 817
#ifdef subprocesses
      close_process_descs ();	/* Close Emacs's pipes/ptys */
#endif
818

819
#ifdef SET_EMACS_PRIORITY
820 821 822
      {
	extern int emacs_priority;

823
	if (emacs_priority < 0)
824 825 826 827
	  nice (-emacs_priority);
      }
#endif

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

850 851
  /* Do this now if we did not do it before.  */
#if !defined (MSDOS) || __DJGPP__ == 1
Jim Blandy's avatar
Jim Blandy committed
852
  save_signal_handlers (saved_handlers);
853
  synch_process_alive = 1;
854 855
#endif

856
#ifndef DOS_NT
Jim Blandy's avatar
Jim Blandy committed
857
  wait_for_termination (pid);
858
#endif
Jim Blandy's avatar
Jim Blandy committed
859
  restore_signal_handlers (saved_handlers);
860
  synch_process_alive = 0;
861
#endif /* !VMS */
862
#endif /* !macintosh */
Jim Blandy's avatar
Jim Blandy committed
863 864
}

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

Andreas Schwab's avatar
Andreas Schwab committed
877
static void
Jim Blandy's avatar
Jim Blandy committed
878 879 880 881 882 883 884 885 886 887 888 889 890 891
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;

892
void
893 894
init_sigio (fd)
     int fd;
Jim Blandy's avatar
Jim Blandy committed
895 896
{
#ifdef FASYNC
897 898
  old_fcntl_flags = fcntl (fd, F_GETFL, 0) & ~FASYNC;
  fcntl (fd, F_SETFL, old_fcntl_flags | FASYNC);
Jim Blandy's avatar
Jim Blandy committed
899
#endif
900
  interrupts_deferred = 0;
Jim Blandy's avatar
Jim Blandy committed
901 902
}

Andreas Schwab's avatar
Andreas Schwab committed
903
void
Jim Blandy's avatar
Jim Blandy committed
904 905 906 907 908
reset_sigio ()
{
  unrequest_sigio ();
}

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

911
void
Jim Blandy's avatar
Jim Blandy committed
912 913
request_sigio ()
{
914 915 916
  if (read_socket_hook)
    return;

Jim Blandy's avatar
Jim Blandy committed
917
#ifdef SIGWINCH
Jim Blandy's avatar
Jim Blandy committed
918
  sigunblock (sigmask (SIGWINCH));
Jim Blandy's avatar
Jim Blandy committed
919
#endif
920
  fcntl (input_fd, F_SETFL, old_fcntl_flags | FASYNC);
Jim Blandy's avatar
Jim Blandy committed
921 922 923 924

  interrupts_deferred = 0;
}

925
void
Jim Blandy's avatar
Jim Blandy committed
926 927
unrequest_sigio ()
{
928 929 930
  if (read_socket_hook)
    return;

Jim Blandy's avatar
Jim Blandy committed
931
#ifdef SIGWINCH
Jim Blandy's avatar
Jim Blandy committed
932
  sigblock (sigmask (SIGWINCH));
Jim Blandy's avatar
Jim Blandy committed
933
#endif
934
  fcntl (input_fd, F_SETFL, old_fcntl_flags);
Jim Blandy's avatar
Jim Blandy committed
935 936 937 938 939 940
  interrupts_deferred = 1;
}

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

941
void
Jim Blandy's avatar
Jim Blandy committed
942 943 944
request_sigio ()
{
  int on = 1;
945 946 947 948

  if (read_socket_hook)
    return;

949
  ioctl (input_fd, FIOASYNC, &on);
Jim Blandy's avatar
Jim Blandy committed
950 951 952
  interrupts_deferred = 0;
}

953
void
Jim Blandy's avatar
Jim Blandy committed
954 955 956 957
unrequest_sigio ()
{
  int off = 0;

958 959 960
  if (read_socket_hook)
    return;

961
  ioctl (input_fd, FIOASYNC, &off);
Jim Blandy's avatar
Jim Blandy committed
962 963 964 965 966
  interrupts_deferred = 1;
}

#else /* not FASYNC, not STRIDE */
 
967 968 969 970
#ifdef _CX_UX

#include <termios.h>

971
void
972 973 974 975 976
request_sigio ()
{
  int on = 1;
  sigset_t st;

977 978 979
  if (read_socket_hook)
    return;

980 981
  sigemptyset (&st);
  sigaddset (&st, SIGIO);
982 983
  ioctl (input_fd, FIOASYNC, &on);
  interrupts_deferred = 0;
984
  sigprocmask (SIG_UNBLOCK, &st, (sigset_t *)0);
985 986
}

987
void
988 989 990 991
unrequest_sigio ()
{
  int off = 0;

992 993 994
  if (read_socket_hook)
    return;

995 996 997 998 999 1000
  ioctl (input_fd, FIOASYNC, &off);
  interrupts_deferred = 1;
}

#else /* ! _CX_UX */

1001
void
Jim Blandy's avatar
Jim Blandy committed
1002 1003
request_sigio ()
{
1004 1005 1006
  if (read_socket_hook)
    return;

Jim Blandy's avatar
Jim Blandy committed
1007 1008 1009
  croak ("request_sigio");
}