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
#include <signal.h>
#include <setjmp.h>
25 26 27
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
Jim Blandy's avatar
Jim Blandy committed
28 29

#include "lisp.h"
30
#include "blockinput.h"
Jim Blandy's avatar
Jim Blandy committed
31 32
#undef NULL

33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
#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
51 52
#define min(x,y) ((x) > (y) ? (y) : (x))

53
#ifdef WINDOWSNT
54 55
#define read sys_read
#define write sys_write
56 57 58 59
#include <windows.h>
extern int errno;
#endif /* not WINDOWSNT */

60 61 62 63 64 65 66
/* Does anyone other than VMS need this? */
#ifndef fwrite
#define sys_fwrite fwrite
#else
#undef fwrite
#endif

67 68 69 70
#ifndef HAVE_H_ERRNO
extern int h_errno;
#endif

Jim Blandy's avatar
Jim Blandy committed
71 72 73 74 75
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>

76 77 78 79 80
/* Get _POSIX_VDISABLE, if it is available.  */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

81 82 83 84
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

85
#ifdef HAVE_SETPGID
86
#if !defined (USG) || defined (BSD_PGRPS)
87 88
#define setpgrp setpgid
#endif
89
#endif
90

91 92 93 94 95
/* Get SI_SRPC_DOMAIN, if it is available.  */
#ifdef HAVE_SYS_SYSTEMINFO_H
#include <sys/systeminfo.h>
#endif

96 97 98 99 100
#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>
101 102 103 104 105

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

108
#ifndef errno
Jim Blandy's avatar
Jim Blandy committed
109
extern int errno;
110
#endif
Jim Blandy's avatar
Jim Blandy committed
111

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

#ifndef BSD4_1
136
#ifdef BSD_SYSTEM /* avoid writing defined (BSD_SYSTEM) || defined (USG)
137 138 139 140 141 142 143 144 145
	      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
146

147
#ifndef MSDOS
Jim Blandy's avatar
Jim Blandy committed
148
#include <sys/ioctl.h>
149
#endif
150

151
#include "systty.h"
Richard M. Stallman's avatar
Richard M. Stallman committed
152
#include "syswait.h"
Jim Blandy's avatar
Jim Blandy committed
153 154 155

#ifdef BROKEN_TIOCGWINSZ
#undef TIOCGWINSZ
156
#undef TIOCSWINSZ
Jim Blandy's avatar
Jim Blandy committed
157 158
#endif

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

extern int quit_char;

Jim Blandy's avatar
Jim Blandy committed
178
#include "frame.h"
Jim Blandy's avatar
Jim Blandy committed
179 180 181 182 183 184 185
#include "window.h"
#include "termhooks.h"
#include "termchar.h"
#include "termopts.h"
#include "dispextern.h"
#include "process.h"

186 187 188 189 190 191 192 193
#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
194 195 196 197
#ifdef NONSYSTEM_DIR_LIBRARY
#include "ndir.h"
#endif /* NONSYSTEM_DIR_LIBRARY */

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

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

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

void croak P_ ((char *));

259 260 261 262
#ifdef AIXHFT
void hft_init ();
void hft_reset ();
#endif
263

264 265 266 267
/* Temporary used by `sigblock' when defined in terms of signprocmask.  */

SIGMASKTYPE sigprocmask_set;

268 269 270 271 272 273 274 275 276 277 278

/* 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
279

280
void
Jim Blandy's avatar
Jim Blandy committed
281 282
discard_tty_input ()
{
283
#ifndef WINDOWSNT
Jim Blandy's avatar
Jim Blandy committed
284
  struct emacs_tty buf;
Jim Blandy's avatar
Jim Blandy committed
285 286 287 288 289 290 291 292 293 294 295

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

#ifdef SIGTSTP

320 321 322
/* Arrange for character C to be read as the next input from
   the terminal.  */

Andreas Schwab's avatar
Andreas Schwab committed
323
void
Jim Blandy's avatar
Jim Blandy committed
324 325 326
stuff_char (c)
     char c;
{
327 328 329
  if (read_socket_hook)
    return;

Jim Blandy's avatar
Jim Blandy committed
330 331
/* Should perhaps error if in batch mode */
#ifdef TIOCSTI
332
  ioctl (input_fd, TIOCSTI, &c);
Jim Blandy's avatar
Jim Blandy committed
333
#else /* no TIOCSTI */
334
  error ("Cannot stuff terminal input characters in this version of Unix");
Jim Blandy's avatar
Jim Blandy committed
335 336 337 338
#endif /* no TIOCSTI */
}

#endif /* SIGTSTP */
339

340
void
Jim Blandy's avatar
Jim Blandy committed
341 342 343 344 345 346
init_baud_rate ()
{
  if (noninteractive)
    ospeed = 0;
  else
    {
347 348 349
#ifdef INIT_BAUD_RATE
      INIT_BAUD_RATE ();
#else
350
#ifdef DOS_NT
351
    ospeed = 15;
352
#else  /* not DOS_NT */
Jim Blandy's avatar
Jim Blandy committed
353
#ifdef VMS
Jim Blandy's avatar
Jim Blandy committed
354 355 356
      struct sensemode sg;

      SYS$QIOW (0, input_fd, IO$_SENSEMODE, &sg, 0, 0,
Jim Blandy's avatar
Jim Blandy committed
357
		&sg.class, 12, 0, 0, 0, 0 );
Jim Blandy's avatar
Jim Blandy committed
358 359
      ospeed = sg.xmit_baud;
#else /* not VMS */
360 361
#ifdef HAVE_TERMIOS
      struct termios sg;
Jim Blandy's avatar
Jim Blandy committed
362

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

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

/*ARGSUSED*/
Andreas Schwab's avatar
Andreas Schwab committed
403
void
Jim Blandy's avatar
Jim Blandy committed
404 405 406 407 408 409 410 411
set_exclusive_use (fd)
     int fd;
{
#ifdef FIOCLEX
  ioctl (fd, FIOCLEX, 0);
#endif
  /* Ok to do nothing if this feature does not exist */
}
412

Jim Blandy's avatar
Jim Blandy committed
413 414 415 416
#ifndef subprocesses

wait_without_blocking ()
{
417
#ifdef BSD_SYSTEM
Jim Blandy's avatar
Jim Blandy committed
418 419 420 421 422 423 424 425 426 427
  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
428
			 (at least for bsd).  */
Jim Blandy's avatar
Jim Blandy committed
429 430 431 432 433 434 435 436

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

437
void
Jim Blandy's avatar
Jim Blandy committed
438 439 440 441 442 443 444 445 446
wait_for_termination (pid)
     int pid;
{
  while (1)
    {
#ifdef subprocesses
#ifdef VMS
      int status;

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

#ifdef subprocesses

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

563
void
Jim Blandy's avatar
Jim Blandy committed
564 565 566
child_setup_tty (out)
     int out;
{
567
#ifndef DOS_NT
Jim Blandy's avatar
Jim Blandy committed
568 569 570
  struct emacs_tty s;

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

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

Jim Blandy's avatar
Jim Blandy committed
603
#ifdef HPUX
Jim Blandy's avatar
Jim Blandy committed
604
  s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
Jim Blandy's avatar
Jim Blandy committed
605
#endif /* HPUX */
Jim Blandy's avatar
Jim Blandy committed
606

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

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

  s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE
		       | CBREAK | TANDEM);
640
  s.main.sg_flags |= LPASS8;
Jim Blandy's avatar
Jim Blandy committed
641 642
  s.main.sg_erase = 0377;
  s.main.sg_kill = 0377;
643
  s.lmode = LLITOUT | s.lmode;        /* Don't strip 8th bit */
Jim Blandy's avatar
Jim Blandy committed
644

Jim Blandy's avatar
Jim Blandy committed
645 646
#endif /* not HAVE_TERMIO */

Jim Blandy's avatar
Jim Blandy committed
647
  EMACS_SET_TTY (out, &s, 0);
Jim Blandy's avatar
Jim Blandy committed
648 649 650 651 652 653 654 655 656 657 658

#ifdef BSD4_1
  if (interrupt_input)
    reset_sigio ();
#endif /* BSD4_1 */
#ifdef RTU
  {
    int zero = 0;
    ioctl (out, FIOASYNC, &zero);
  }
#endif /* RTU */
659
#endif /* not DOS_NT */
Jim Blandy's avatar
Jim Blandy committed
660 661 662 663
}
#endif /* not VMS */

#endif /* subprocesses */
664

Jim Blandy's avatar
Jim Blandy committed
665 666 667 668
/* Record a signal code and the handler for it.  */
struct save_signal
{
  int code;
Andreas Schwab's avatar
Andreas Schwab committed
669
  SIGTYPE (*handler) P_ ((int));
Jim Blandy's avatar
Jim Blandy committed
670 671
};

Andreas Schwab's avatar
Andreas Schwab committed
672 673 674
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
675 676
/* Suspend the Emacs process; give terminal to its superior.  */

677
void
Jim Blandy's avatar
Jim Blandy committed
678 679 680
sys_suspend ()
{
#ifdef VMS
681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698
  /* "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 ();

699
  xfree (fpid_string);		/* On VMS, this was malloc'd */
Jim Blandy's avatar
Jim Blandy committed
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715

  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 */
716
      LIB$SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt, 0);
Jim Blandy's avatar
Jim Blandy committed
717 718 719 720
      return 1;
    }
  return -1;
#else
721
#if defined (SIGTSTP) && !defined (MSDOS)
Jim Blandy's avatar
Jim Blandy committed
722

723
  {
724
    int pgrp = EMACS_GETPGRP (0);
725 726
    EMACS_KILLPG (pgrp, SIGTSTP);
  }
Jim Blandy's avatar
Jim Blandy committed
727 728 729 730 731 732 733 734 735 736 737

#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.  */
738 739 740 741 742 743 744 745 746
  sys_subshell ();

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

/* Fork a subshell.  */

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

  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

774 775 776 777
  /* Mentioning current_buffer->buffer would mean including buffer.h,
     which somehow wedges the hp compiler.  So instead...  */

  dir = intern ("default-directory");
778
  if (NILP (Fboundp (dir)))
779 780
    goto xyzzy;
  dir = Fsymbol_value (dir);
781
  if (!STRINGP (dir))
782 783 784 785 786 787 788 789 790 791
    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:

792
#ifdef DOS_NT
793
  pid = 0;
794 795 796 797
#if __DJGPP__ > 1
  save_signal_handlers (saved_handlers);
  synch_process_alive = 1;
#endif /* __DJGPP__ > 1 */
798
#else  
799
  pid = vfork ();
Jim Blandy's avatar
Jim Blandy committed
800 801
  if (pid == -1)
    error ("Can't spawn subshell");
802 803
#endif

Jim Blandy's avatar
Jim Blandy committed
804 805
  if (pid == 0)
    {
806
      char *sh = 0;
Jim Blandy's avatar
Jim Blandy committed
807

808
#ifdef DOS_NT    /* MW, Aug 1993 */
809
      getwd (oldwd);
810 811
      if (sh == 0)
	sh = (char *) egetenv ("SUSPEND");	/* KFS, 1994-12-14 */
812
#endif
813 814
      if (sh == 0)
	sh = (char *) egetenv ("SHELL");
Jim Blandy's avatar
Jim Blandy committed
815 816
      if (sh == 0)
	sh = "sh";
817

Jim Blandy's avatar
Jim Blandy committed
818
      /* Use our buffer's default directory for the subshell.  */
819
      if (str)
820
	chdir ((char *) str);
821

Jim Blandy's avatar
Jim Blandy committed
822 823 824
#ifdef subprocesses
      close_process_descs ();	/* Close Emacs's pipes/ptys */
#endif
825

826
#ifdef SET_EMACS_PRIORITY
827 828 829
      {
	extern int emacs_priority;

830
	if (emacs_priority < 0)
831 832 833 834
	  nice (-emacs_priority);
      }
#endif

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

857 858
  /* Do this now if we did not do it before.  */
#if !defined (MSDOS) || __DJGPP__ == 1
Jim Blandy's avatar
Jim Blandy committed
859
  save_signal_handlers (saved_handlers);
860
  synch_process_alive = 1;
861 862
#endif

863
#ifndef DOS_NT
Jim Blandy's avatar
Jim Blandy committed
864
  wait_for_termination (pid);
865
#endif
Jim Blandy's avatar
Jim Blandy committed
866
  restore_signal_handlers (saved_handlers);
867
  synch_process_alive = 0;
868
#endif /* !VMS */
869
#endif /* !macintosh */
Jim Blandy's avatar
Jim Blandy committed
870 871
}

Andreas Schwab's avatar
Andreas Schwab committed
872
static void
Jim Blandy's avatar
Jim Blandy committed
873 874 875 876 877
save_signal_handlers (saved_handlers)
     struct save_signal *saved_handlers;
{
  while (saved_handlers->code)
    {
Joseph Arceneaux's avatar
Joseph Arceneaux committed
878
      saved_handlers->handler
Andreas Schwab's avatar
Andreas Schwab committed
879
	= (SIGTYPE (*) P_ ((int))) signal (saved_handlers->code, SIG_IGN);
Jim Blandy's avatar
Jim Blandy committed
880 881 882 883
      saved_handlers++;
    }
}

Andreas Schwab's avatar
Andreas Schwab committed
884
static void
Jim Blandy's avatar
Jim Blandy committed
885 886 887 888 889 890 891 892 893 894 895 896 897 898
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;

899
void
900 901
init_sigio (fd)
     int fd;
Jim Blandy's avatar
Jim Blandy committed
902 903
{
#ifdef FASYNC
904 905
  old_fcntl_flags = fcntl (fd, F_GETFL, 0) & ~FASYNC;
  fcntl (fd, F_SETFL, old_fcntl_flags | FASYNC);
Jim Blandy's avatar
Jim Blandy committed
906
#endif
907
  interrupts_deferred = 0;
Jim Blandy's avatar
Jim Blandy committed
908 909
}

Andreas Schwab's avatar
Andreas Schwab committed
910
void
Jim Blandy's avatar
Jim Blandy committed
911 912 913 914 915
reset_sigio ()
{
  unrequest_sigio ();
}

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

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

Jim Blandy's avatar
Jim Blandy committed
924
#ifdef SIGWINCH
Jim Blandy's avatar
Jim Blandy committed
925
  sigunblock (sigmask (SIGWINCH));
Jim Blandy's avatar
Jim Blandy committed
926
#endif
927
  fcntl (input_fd, F_SETFL, old_fcntl_flags | FASYNC);
Jim Blandy's avatar
Jim Blandy committed
928 929 930 931

  interrupts_deferred = 0;
}

932
void
Jim Blandy's avatar
Jim Blandy committed
933 934
unrequest_sigio ()
{
935 936 937
  if (read_socket_hook)
    return;

Jim Blandy's avatar
Jim Blandy committed
938
#ifdef SIGWINCH
Jim Blandy's avatar
Jim Blandy committed
939
  sigblock (sigmask (SIGWINCH));
Jim Blandy's avatar
Jim Blandy committed
940
#endif
941
  fcntl (input_fd, F_SETFL, old_fcntl_flags);
Jim Blandy's avatar
Jim Blandy committed
942 943 944 945 946 947
  interrupts_deferred = 1;
}

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

948
void
Jim Blandy's avatar
Jim Blandy committed
949 950 951
request_sigio ()
{
  int on = 1;
952 953 954 955

  if (read_socket_hook)
    return;

956
  ioctl (input_fd, FIOASYNC, &on);
Jim Blandy's avatar
Jim Blandy committed
957 958 959
  interrupts_deferred = 0;
}

960
void
Jim Blandy's avatar
Jim Blandy committed
961 962 963 964
unrequest_sigio ()
{
  int off = 0;

965 966 967
  if (read_socket_hook)
    return;

968
  ioctl (input_fd, FIOASYNC, &off);
Jim Blandy's avatar
Jim Blandy committed
969 970 971 972 973
  interrupts_deferred = 1;
}

#else /* not FASYNC, not STRIDE */
 
974 975 976 977
#ifdef _CX_UX

#include <termios.h>

978
void
979 980 981 982 983
request_sigio ()
{
  int on = 1;
  sigset_t st;

984 985 986
  if (read_socket_hook)
    return;

987 988
  sigemptyset (&st);
  sigaddset (&st, SIGIO);
989 990
  ioctl (input_fd, FIOASYNC, &on);
  interrupts_deferred = 0;
991
  sigprocmask (SIG_UNBLOCK, &st, (sigset_t *)0);
992 993
}

994
void
995 996 997 998
unrequest_sigio ()
{
  int off = 0;

999 1000 1001
  if (read_socket_hook)
    return;

1002 1003 1004 1005 1006 1007
  ioctl (input_fd, FIOASYNC, &off);
  interrupts_deferred = 1;
}

#else /* ! _CX_UX */

1008
void
Jim Blandy's avatar
Jim Blandy committed
1009 1010