sysdep.c 83.6 KB
Newer Older
Jim Blandy's avatar
Jim Blandy committed
1
/* Interfaces to system-dependent kernel and library entries.
2
   Copyright (C) 1985-1988, 1993-1995, 1999-2012
Glenn Morris's avatar
Glenn Morris committed
3
                 Free Software Foundation, Inc.
Jim Blandy's avatar
Jim Blandy committed
4 5 6

This file is part of GNU Emacs.

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

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
18
along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
Jim Blandy's avatar
Jim Blandy committed
19

Pavel Janík's avatar
Pavel Janík committed
20
#include <config.h>
21
#include <ctype.h>
Jim Blandy's avatar
Jim Blandy committed
22
#include <signal.h>
23
#include <stdio.h>
Jim Blandy's avatar
Jim Blandy committed
24
#include <setjmp.h>
25 26 27 28 29
#ifdef HAVE_PWD_H
#include <pwd.h>
#include <grp.h>
#endif /* HAVE_PWD_H */
#include <limits.h>
30
#include <unistd.h>
Dan Nicolaescu's avatar
Dan Nicolaescu committed
31

32 33
#include <allocator.h>
#include <careadlinkat.h>
34
#include <ignore-value.h>
35
#include <utimens.h>
36

Jim Blandy's avatar
Jim Blandy committed
37
#include "lisp.h"
38
#include "sysselect.h"
39
#include "blockinput.h"
Jim Blandy's avatar
Jim Blandy committed
40

41 42 43
#ifdef __FreeBSD__
#include <sys/sysctl.h>
#include <sys/user.h>
44
#include <sys/resource.h>
45 46 47
#include <math.h>
#endif

48 49 50 51
#ifdef DARWIN_OS
#include <sys/sysctl.h>
#endif

52
#ifdef WINDOWSNT
53 54
#define read sys_read
#define write sys_write
55 56 57
#include <windows.h>
#endif /* not WINDOWSNT */

Jim Blandy's avatar
Jim Blandy committed
58 59 60 61
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>

62
#ifdef HAVE_SETPGID
Dan Nicolaescu's avatar
Dan Nicolaescu committed
63
#if !defined (USG)
64
#undef setpgrp
65 66
#define setpgrp setpgid
#endif
67
#endif
68

69 70 71 72 73
/* Get SI_SRPC_DOMAIN, if it is available.  */
#ifdef HAVE_SYS_SYSTEMINFO_H
#include <sys/systeminfo.h>
#endif

74 75 76 77 78
#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>
79
#endif
80

81 82
#include <sys/file.h>
#include <fcntl.h>
Jim Blandy's avatar
Jim Blandy committed
83

84
#include "systty.h"
Richard M. Stallman's avatar
Richard M. Stallman committed
85
#include "syswait.h"
Jim Blandy's avatar
Jim Blandy committed
86

Dan Nicolaescu's avatar
Dan Nicolaescu committed
87
#ifdef HAVE_SYS_UTSNAME_H
Jim Blandy's avatar
Jim Blandy committed
88 89
#include <sys/utsname.h>
#include <memory.h>
Dan Nicolaescu's avatar
Dan Nicolaescu committed
90
#endif /* HAVE_SYS_UTSNAME_H */
Jim Blandy's avatar
Jim Blandy committed
91

92
#include "keyboard.h"
Jim Blandy's avatar
Jim Blandy committed
93
#include "frame.h"
Jim Blandy's avatar
Jim Blandy committed
94 95 96 97 98 99
#include "window.h"
#include "termhooks.h"
#include "termchar.h"
#include "termopts.h"
#include "dispextern.h"
#include "process.h"
Karoly Lorentey's avatar
Karoly Lorentey committed
100
#include "cm.h"  /* for reset_sys_modes */
Jim Blandy's avatar
Jim Blandy committed
101

102 103 104 105
#ifdef WINDOWSNT
#include <direct.h>
/* In process.h which conflicts with the local copy.  */
#define _P_WAIT 0
106 107
int _cdecl _spawnlp (int, const char *, const char *, ...);
int _cdecl _getpid (void);
108
extern char *getwd (char *);
109 110
#endif

Jim Blandy's avatar
Jim Blandy committed
111 112
#include "syssignal.h"
#include "systime.h"
Jim Blandy's avatar
Jim Blandy committed
113

114 115
static int emacs_get_tty (int, struct emacs_tty *);
static int emacs_set_tty (int, struct emacs_tty *, int);
116 117 118
#if defined TIOCNOTTY || defined USG5 || defined CYGWIN
static void croak (char *) NO_RETURN;
#endif
119

Dan Nicolaescu's avatar
Dan Nicolaescu committed
120 121 122
/* Declare here, including term.h is problematic on some systems.  */
extern void tputs (const char *, int, int (*)(int));

123
static const int baud_convert[] =
Jim Blandy's avatar
Jim Blandy committed
124 125 126 127 128
  {
    0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
    1800, 2400, 4800, 9600, 19200, 38400
  };

129

130
#if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME)
131

132
/* Return the current working directory.  Returns NULL on errors.
133 134 135
   Any other returned value must be freed with free. This is used
   only when get_current_dir_name is not defined on the system.  */
char*
136
get_current_dir_name (void)
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
{
  char *buf;
  char *pwd;
  struct stat dotstat, pwdstat;
  /* If PWD is accurate, use it instead of calling getwd.  PWD is
     sometimes a nicer name, and using it may avoid a fatal error if a
     parent directory is searchable but not readable.  */
    if ((pwd = getenv ("PWD")) != 0
      && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1])))
      && stat (pwd, &pwdstat) == 0
      && stat (".", &dotstat) == 0
      && dotstat.st_ino == pwdstat.st_ino
      && dotstat.st_dev == pwdstat.st_dev
#ifdef MAXPATHLEN
      && strlen (pwd) < MAXPATHLEN
#endif
      )
    {
      buf = (char *) malloc (strlen (pwd) + 1);
      if (!buf)
        return NULL;
      strcpy (buf, pwd);
    }
#ifdef HAVE_GETCWD
  else
    {
      size_t buf_size = 1024;
164
      buf = (char *) malloc (buf_size);
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
      if (!buf)
        return NULL;
      for (;;)
        {
          if (getcwd (buf, buf_size) == buf)
            break;
          if (errno != ERANGE)
            {
              int tmp_errno = errno;
              free (buf);
              errno = tmp_errno;
              return NULL;
            }
          buf_size *= 2;
          buf = (char *) realloc (buf, buf_size);
          if (!buf)
            return NULL;
        }
    }
#else
  else
    {
      /* We need MAXPATHLEN here.  */
      buf = (char *) malloc (MAXPATHLEN + 1);
      if (!buf)
        return NULL;
      if (getwd (buf) == NULL)
        {
          int tmp_errno = errno;
          free (buf);
          errno = tmp_errno;
          return NULL;
        }
    }
#endif
  return buf;
}
#endif

204

205
/* Discard pending input on all input descriptors.  */
Jim Blandy's avatar
Jim Blandy committed
206

207
void
208
discard_tty_input (void)
Jim Blandy's avatar
Jim Blandy committed
209
{
210
#ifndef WINDOWSNT
Jim Blandy's avatar
Jim Blandy committed
211
  struct emacs_tty buf;
Jim Blandy's avatar
Jim Blandy committed
212 213 214 215

  if (noninteractive)
    return;

216
#ifdef MSDOS    /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
217
  while (dos_keyread () != -1)
218
    ;
219
#else /* not MSDOS */
220
  {
221
    struct tty_display_info *tty;
222 223
    for (tty = tty_list; tty; tty = tty->next)
      {
224 225
        if (tty->input)         /* Is the device suspended? */
          {
Dan Nicolaescu's avatar
Dan Nicolaescu committed
226 227
            emacs_get_tty (fileno (tty->input), &buf);
            emacs_set_tty (fileno (tty->input), &buf, 0);
228
          }
229 230
      }
  }
231
#endif /* not MSDOS */
232
#endif /* not WINDOWSNT */
Jim Blandy's avatar
Jim Blandy committed
233 234
}

235

Jim Blandy's avatar
Jim Blandy committed
236 237
#ifdef SIGTSTP

238
/* Arrange for character C to be read as the next input from
239 240 241
   the terminal.
   XXX What if we have multiple ttys?
*/
242

Andreas Schwab's avatar
Andreas Schwab committed
243
void
244
stuff_char (char c)
Jim Blandy's avatar
Jim Blandy committed
245
{
246
  if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
247 248
    return;

Jim Blandy's avatar
Jim Blandy committed
249 250
/* Should perhaps error if in batch mode */
#ifdef TIOCSTI
251
  ioctl (fileno (CURTTY()->input), TIOCSTI, &c);
Jim Blandy's avatar
Jim Blandy committed
252
#else /* no TIOCSTI */
253
  error ("Cannot stuff terminal input characters in this version of Unix");
Jim Blandy's avatar
Jim Blandy committed
254 255 256 257
#endif /* no TIOCSTI */
}

#endif /* SIGTSTP */
258

259
void
260
init_baud_rate (int fd)
Jim Blandy's avatar
Jim Blandy committed
261
{
Dan Nicolaescu's avatar
Dan Nicolaescu committed
262
  int emacs_ospeed;
263

Jim Blandy's avatar
Jim Blandy committed
264
  if (noninteractive)
Gerd Moellmann's avatar
Gerd Moellmann committed
265
    emacs_ospeed = 0;
Jim Blandy's avatar
Jim Blandy committed
266 267
  else
    {
268
#ifdef DOS_NT
Gerd Moellmann's avatar
Gerd Moellmann committed
269
    emacs_ospeed = 15;
270
#else  /* not DOS_NT */
271
      struct termios sg;
Jim Blandy's avatar
Jim Blandy committed
272

273
      sg.c_cflag = B9600;
274
      tcgetattr (fd, &sg);
Gerd Moellmann's avatar
Gerd Moellmann committed
275
      emacs_ospeed = cfgetospeed (&sg);
276
#endif /* not DOS_NT */
Jim Blandy's avatar
Jim Blandy committed
277
    }
278

Gerd Moellmann's avatar
Gerd Moellmann committed
279 280
  baud_rate = (emacs_ospeed < sizeof baud_convert / sizeof baud_convert[0]
	       ? baud_convert[emacs_ospeed] : 9600);
Jim Blandy's avatar
Jim Blandy committed
281 282 283 284
  if (baud_rate == 0)
    baud_rate = 1200;
}

285

Jim Blandy's avatar
Jim Blandy committed
286

287 288 289
/* Set nonzero to make following function work under dbx
   (at least for bsd).  */
int wait_debugging EXTERNALLY_VISIBLE;
Jim Blandy's avatar
Jim Blandy committed
290

291
#ifndef MSDOS
Jim Blandy's avatar
Jim Blandy committed
292

293
static void
294
wait_for_termination_1 (pid_t pid, int interruptible)
Jim Blandy's avatar
Jim Blandy committed
295 296 297
{
  while (1)
    {
Juanma Barranquero's avatar
Juanma Barranquero committed
298
#if (defined (BSD_SYSTEM) || defined (HPUX)) && !defined (__GNU__)
299 300 301 302 303 304 305 306 307
      /* 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))
308
	{
309 310 311 312 313 314 315 316
	  sigsetmask (SIGEMPTYMASK);
	  kill (getpid (), SIGCHLD);
	  break;
	}
      if (wait_debugging)
	sleep (1);
      else
	sigpause (SIGEMPTYMASK);
317
#else /* not BSD_SYSTEM, and not HPUX version >= 6 */
318 319 320 321
#ifdef WINDOWSNT
      wait (0);
      break;
#else /* not WINDOWSNT */
322
      sigblock (sigmask (SIGCHLD));
323 324
      errno = 0;
      if (kill (pid, 0) == -1 && errno == ESRCH)
325 326 327 328
	{
	  sigunblock (sigmask (SIGCHLD));
	  break;
	}
329

330
      sigsuspend (&empty_mask);
331
#endif /* not WINDOWSNT */
332
#endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
333 334
      if (interruptible)
	QUIT;
Jim Blandy's avatar
Jim Blandy committed
335 336 337
    }
}

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

void
342
wait_for_termination (pid_t pid)
343 344 345 346 347 348
{
  wait_for_termination_1 (pid, 0);
}

/* Like the above, but allow keyboard interruption. */
void
349
interruptible_wait_for_termination (pid_t pid)
350 351 352 353
{
  wait_for_termination_1 (pid, 1);
}

Jim Blandy's avatar
Jim Blandy committed
354 355 356 357
/*
 *	flush any pending output
 *      (may flush input as well; it does not matter the way we use it)
 */
358

359
void
360
flush_pending_output (int channel)
Jim Blandy's avatar
Jim Blandy committed
361
{
362
  /* FIXME: maybe this function should be removed */
Jim Blandy's avatar
Jim Blandy committed
363
}
364

Jim Blandy's avatar
Jim Blandy committed
365 366 367 368 369
/*  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.  */

370
void
371
child_setup_tty (int out)
Jim Blandy's avatar
Jim Blandy committed
372
{
373
#ifndef WINDOWSNT
Jim Blandy's avatar
Jim Blandy committed
374 375
  struct emacs_tty s;

Dan Nicolaescu's avatar
Dan Nicolaescu committed
376
  emacs_get_tty (out, &s);
Jim Blandy's avatar
Jim Blandy committed
377 378
  s.main.c_oflag |= OPOST;	/* Enable output postprocessing */
  s.main.c_oflag &= ~ONLCR;	/* Disable map of NL to CR-NL on output */
379
#ifdef NLDLY
380 381 382
  /* http://lists.gnu.org/archive/html/emacs-devel/2008-05/msg00406.html
     Some versions of GNU Hurd do not have FFDLY?  */
#ifdef FFDLY
Jim Blandy's avatar
Jim Blandy committed
383 384
  s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
  				/* No output delays */
385 386 387 388
#else
  s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY);
  				/* No output delays */
#endif
389
#endif
Jim Blandy's avatar
Jim Blandy committed
390 391
  s.main.c_lflag &= ~ECHO;	/* Disable echo */
  s.main.c_lflag |= ISIG;	/* Enable signals */
392 393 394
#ifdef IUCLC
  s.main.c_iflag &= ~IUCLC;	/* Disable downcasing on input.  */
#endif
395 396 397
#ifdef ISTRIP
  s.main.c_iflag &= ~ISTRIP;	/* don't strip 8th bit on input */
#endif
398
#ifdef OLCUC
399 400
  s.main.c_oflag &= ~OLCUC;	/* Disable upcasing on output.  */
#endif
401
  s.main.c_oflag &= ~TAB3;	/* Disable tab expansion */
402
  s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */
403 404
  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
405

Jim Blandy's avatar
Jim Blandy committed
406
#ifdef HPUX
Jim Blandy's avatar
Jim Blandy committed
407
  s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
Jim Blandy's avatar
Jim Blandy committed
408
#endif /* HPUX */
Jim Blandy's avatar
Jim Blandy committed
409

410 411 412
#ifdef SIGNALS_VIA_CHARACTERS
  /* the QUIT and INTR character are used in process_send_signal
     so set them here to something useful.  */
413
  if (s.main.c_cc[VQUIT] == CDISABLE)
414
    s.main.c_cc[VQUIT] = '\\'&037;	/* Control-\ */
415
  if (s.main.c_cc[VINTR] == CDISABLE)
416 417 418
    s.main.c_cc[VINTR] = 'C'&037;	/* Control-C */
#endif /* not SIGNALS_VIA_CHARACTERS */

Jim Blandy's avatar
Jim Blandy committed
419 420 421
#ifdef AIX
  /* 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
422 423
  s.main.c_iflag &= ~IGNBRK;
  s.main.c_iflag &= ~BRKINT;
424 425 426
  /* rms: Formerly it set s.main.c_cc[VINTR] to 0377 here
     unconditionally.  Then a SIGNALS_VIA_CHARACTERS conditional
     would force it to 0377.  That looks like duplicated code.  */
Jim Blandy's avatar
Jim Blandy committed
427
  s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
Jim Blandy's avatar
Jim Blandy committed
428 429
#endif /* AIX */

430
  /* We originally enabled ICANON (and set VEOF to 04), and then had
Paul Eggert's avatar
Paul Eggert committed
431
     process.c send additional EOF chars to flush the output when faced
432
     with long lines, but this leads to weird effects when the
433 434
     subprocess has disabled ICANON and ends up seeing those spurious
     extra EOFs.  So we don't send EOFs any more in
435 436 437 438 439 440 441 442 443 444 445
     process.c:send_process.  First we tried to disable ICANON by
     default, so if a subsprocess sets up ICANON, it's his problem (or
     the Elisp package that talks to it) to deal with lines that are
     too long.  But this disables some features, such as the ability
     to send EOF signals.  So we re-enabled ICANON but there is no
     more "send eof to flush" going on (which is wrong and unportable
     in itself).  The correct way to handle too much output is to
     buffer what could not be written and then write it again when
     select returns ok for writing.  This has it own set of
     problems.  Write is now asynchronous, is that a problem?  How much
     do we buffer, and what do we do when that limit is reached?  */
446 447 448

  s.main.c_lflag |= ICANON;	/* Enable line editing and eof processing */
  s.main.c_cc[VEOF] = 'D'&037;	/* Control-D */
Nick Roberts's avatar
Nick Roberts committed
449
#if 0	    /* These settings only apply to non-ICANON mode. */
450 451
  s.main.c_cc[VMIN] = 1;
  s.main.c_cc[VTIME] = 0;
452
#endif
453

Dan Nicolaescu's avatar
Dan Nicolaescu committed
454
  emacs_set_tty (out, &s, 0);
455
#endif /* not WINDOWSNT */
Jim Blandy's avatar
Jim Blandy committed
456
}
Dan Nicolaescu's avatar
Dan Nicolaescu committed
457
#endif	/* not MSDOS */
Jim Blandy's avatar
Jim Blandy committed
458

459

Jim Blandy's avatar
Jim Blandy committed
460 461 462 463
/* Record a signal code and the handler for it.  */
struct save_signal
{
  int code;
464
  void (*handler) (int);
Jim Blandy's avatar
Jim Blandy committed
465 466
};

467 468
static void save_signal_handlers (struct save_signal *);
static void restore_signal_handlers (struct save_signal *);
Andreas Schwab's avatar
Andreas Schwab committed
469

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

472
void
473
sys_suspend (void)
Jim Blandy's avatar
Jim Blandy committed
474
{
475
#if defined (SIGTSTP) && !defined (MSDOS)
Jim Blandy's avatar
Jim Blandy committed
476

477
  {
478
    int pgrp = EMACS_GETPGRP (0);
479 480
    EMACS_KILLPG (pgrp, SIGTSTP);
  }
Jim Blandy's avatar
Jim Blandy committed
481 482 483 484 485

#else /* No SIGTSTP */
/* On a system where suspending is not implemented,
   instead fork a subshell and let it talk directly to the terminal
   while we wait.  */
486 487 488 489 490 491 492
  sys_subshell ();

#endif /* no SIGTSTP */
}

/* Fork a subshell.  */

493
void
494
sys_subshell (void)
495
{
496
#ifdef DOS_NT	/* Demacs 1.1.2 91/10/20 Manabu Higashida */
497 498 499
  int st;
  char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS.  */
#endif
500
  int pid;
Jim Blandy's avatar
Jim Blandy committed
501
  struct save_signal saved_handlers[5];
502
  Lisp_Object dir;
Paul Eggert's avatar
Paul Eggert committed
503
  unsigned char *volatile str_volatile = 0;
504
  unsigned char *str;
505
  int len;
Jim Blandy's avatar
Jim Blandy committed
506 507 508 509 510 511 512 513 514 515 516

  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

517 518 519 520
  /* Mentioning current_buffer->buffer would mean including buffer.h,
     which somehow wedges the hp compiler.  So instead...  */

  dir = intern ("default-directory");
521
  if (NILP (Fboundp (dir)))
522 523
    goto xyzzy;
  dir = Fsymbol_value (dir);
524
  if (!STRINGP (dir))
525 526 527
    goto xyzzy;

  dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil);
Paul Eggert's avatar
Paul Eggert committed
528
  str_volatile = str = (unsigned char *) alloca (SCHARS (dir) + 2);
529
  len = SCHARS (dir);
530
  memcpy (str, SDATA (dir), len);
531 532 533 534
  if (str[len - 1] != '/') str[len++] = '/';
  str[len] = 0;
 xyzzy:

535
#ifdef DOS_NT
536
  pid = 0;
537 538
  save_signal_handlers (saved_handlers);
  synch_process_alive = 1;
539
#else
540
  pid = vfork ();
Jim Blandy's avatar
Jim Blandy committed
541 542
  if (pid == -1)
    error ("Can't spawn subshell");
543 544
#endif

Jim Blandy's avatar
Jim Blandy committed
545 546
  if (pid == 0)
    {
547
      const char *sh = 0;
Jim Blandy's avatar
Jim Blandy committed
548

549
#ifdef DOS_NT    /* MW, Aug 1993 */
550
      getwd (oldwd);
551 552
      if (sh == 0)
	sh = (char *) egetenv ("SUSPEND");	/* KFS, 1994-12-14 */
553
#endif
554 555
      if (sh == 0)
	sh = (char *) egetenv ("SHELL");
Jim Blandy's avatar
Jim Blandy committed
556 557
      if (sh == 0)
	sh = "sh";
558

Jim Blandy's avatar
Jim Blandy committed
559
      /* Use our buffer's default directory for the subshell.  */
Paul Eggert's avatar
Paul Eggert committed
560
      str = str_volatile;
Paul Eggert's avatar
Paul Eggert committed
561 562 563 564 565 566 567
      if (str && chdir ((char *) str) != 0)
	{
#ifndef DOS_NT
	  ignore_value (write (1, "Can't chdir\n", 12));
	  _exit (1);
#endif
	}
568

Jim Blandy's avatar
Jim Blandy committed
569
      close_process_descs ();	/* Close Emacs's pipes/ptys */
570

571
#ifdef MSDOS    /* Demacs 1.1.2 91/10/20 Manabu Higashida */
572
      {
573 574
	char *epwd = getenv ("PWD");
	char old_pwd[MAXPATHLEN+1+4];
575 576

	/* If PWD is set, pass it with corrected value.  */
577
	if (epwd)
578
	  {
579
	    strcpy (old_pwd, epwd);
580 581 582 583 584
	    if (str[len - 1] == '/')
	      str[len - 1] = '\0';
	    setenv ("PWD", str, 1);
	  }
	st = system (sh);
Paul Eggert's avatar
Paul Eggert committed
585
	chdir (oldwd);	/* FIXME: Do the right thing on chdir failure.  */
586
	if (epwd)
587 588
	  putenv (old_pwd);	/* restore previous value */
      }
589
#else /* not MSDOS */
590 591 592
#ifdef  WINDOWSNT
      /* Waits for process completion */
      pid = _spawnlp (_P_WAIT, sh, sh, NULL);
Paul Eggert's avatar
Paul Eggert committed
593
      chdir (oldwd);	/* FIXME: Do the right thing on chdir failure.  */
594 595 596
      if (pid == -1)
	write (1, "Can't execute subshell", 22);
#else   /* not WINDOWSNT */
597
      execlp (sh, sh, (char *) 0);
598
      ignore_value (write (1, "Can't execute subshell", 22));
Jim Blandy's avatar
Jim Blandy committed
599
      _exit (1);
600
#endif  /* not WINDOWSNT */
601
#endif /* not MSDOS */
Jim Blandy's avatar
Jim Blandy committed
602 603
    }

604
  /* Do this now if we did not do it before.  */
605
#ifndef MSDOS
Jim Blandy's avatar
Jim Blandy committed
606
  save_signal_handlers (saved_handlers);
607
  synch_process_alive = 1;
608 609
#endif

610
#ifndef DOS_NT
Jim Blandy's avatar
Jim Blandy committed
611
  wait_for_termination (pid);
612
#endif
Jim Blandy's avatar
Jim Blandy committed
613
  restore_signal_handlers (saved_handlers);
614
  synch_process_alive = 0;
Jim Blandy's avatar
Jim Blandy committed
615 616
}

Andreas Schwab's avatar
Andreas Schwab committed
617
static void
618
save_signal_handlers (struct save_signal *saved_handlers)
Jim Blandy's avatar
Jim Blandy committed
619 620 621
{
  while (saved_handlers->code)
    {
Joseph Arceneaux's avatar
Joseph Arceneaux committed
622
      saved_handlers->handler
623
        = (void (*) (int)) signal (saved_handlers->code, SIG_IGN);
Jim Blandy's avatar
Jim Blandy committed
624 625 626 627
      saved_handlers++;
    }
}

Andreas Schwab's avatar
Andreas Schwab committed
628
static void
629
restore_signal_handlers (struct save_signal *saved_handlers)
Jim Blandy's avatar
Jim Blandy committed
630 631 632 633 634 635 636 637
{
  while (saved_handlers->code)
    {
      signal (saved_handlers->code, saved_handlers->handler);
      saved_handlers++;
    }
}

638 639 640 641 642 643 644
#ifndef SIGIO
/* If SIGIO is broken, don't do anything. */
void
init_sigio (int fd)
{
}

645
static void
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660
reset_sigio (int fd)
{
}

void
request_sigio (void)
{
}

void
unrequest_sigio (void)
{
}

#else
Jim Blandy's avatar
Jim Blandy committed
661 662
#ifdef F_SETFL

663
static int old_fcntl_flags[MAXDESC];
Jim Blandy's avatar
Jim Blandy committed
664

665
void
666
init_sigio (int fd)
Jim Blandy's avatar
Jim Blandy committed
667 668
{
#ifdef FASYNC
669 670
  old_fcntl_flags[fd] = fcntl (fd, F_GETFL, 0) & ~FASYNC;
  fcntl (fd, F_SETFL, old_fcntl_flags[fd] | FASYNC);
Jim Blandy's avatar
Jim Blandy committed
671
#endif
672
  interrupts_deferred = 0;
Jim Blandy's avatar
Jim Blandy committed
673 674
}

675
static void
676
reset_sigio (int fd)
Jim Blandy's avatar
Jim Blandy committed
677
{
678
#ifdef FASYNC
679
  fcntl (fd, F_SETFL, old_fcntl_flags[fd]);
680
#endif
Jim Blandy's avatar
Jim Blandy committed
681 682
}

683
#ifdef FASYNC		/* F_SETFL does not imply existence of FASYNC */
684
/* XXX Uhm, FASYNC is not used anymore here. */
685
/* XXX Yeah, but you need it for SIGIO, don't you? */
Jim Blandy's avatar
Jim Blandy committed
686

687
void
688
request_sigio (void)
Jim Blandy's avatar
Jim Blandy committed
689
{
690
  if (noninteractive)
691 692
    return;

Jim Blandy's avatar
Jim Blandy committed
693
#ifdef SIGWINCH
Jim Blandy's avatar
Jim Blandy committed
694
  sigunblock (sigmask (SIGWINCH));
Jim Blandy's avatar
Jim Blandy committed
695
#endif
Karoly Lorentey's avatar
Karoly Lorentey committed
696
  sigunblock (sigmask (SIGIO));
Jim Blandy's avatar
Jim Blandy committed
697 698 699 700

  interrupts_deferred = 0;
}

701
void
Karoly Lorentey's avatar
Karoly Lorentey committed
702
unrequest_sigio (void)
703
{
704 705 706 707 708
  if (noninteractive)
    return;

#if 0 /* XXX What's wrong with blocking SIGIO under X?  */
  if (x_display_list)
709
    return;
710
#endif
711

Jim Blandy's avatar
Jim Blandy committed
712
#ifdef SIGWINCH
Jim Blandy's avatar
Jim Blandy committed
713
  sigblock (sigmask (SIGWINCH));
Jim Blandy's avatar
Jim Blandy committed
714
#endif
Karoly Lorentey's avatar
Karoly Lorentey committed
715
  sigblock (sigmask (SIGIO));
Jim Blandy's avatar
Jim Blandy committed
716 717 718 719
  interrupts_deferred = 1;
}

#else /* no FASYNC */
720
#ifndef MSDOS
721

722
void
723
request_sigio (void)
Jim Blandy's avatar
Jim Blandy committed
724
{
725
  if (noninteractive || read_socket_hook)
726 727
    return;

Jim Blandy's avatar
Jim Blandy committed
728 729
  croak ("request_sigio");
}
730

731
void
732
unrequest_sigio (void)
Jim Blandy's avatar
Jim Blandy committed
733
{
734
  if (noninteractive || read_socket_hook)
735 736
    return;

Jim Blandy's avatar
Jim Blandy committed
737 738
  croak ("unrequest_sigio");
}
739 740

#endif /* MSDOS */
Jim Blandy's avatar
Jim Blandy committed
741 742
#endif /* FASYNC */
#endif /* F_SETFL */
743
#endif /* SIGIO */
744 745


746 747 748 749 750 751
/* Getting and setting emacs_tty structures.  */

/* Set *TC to the parameters associated with the terminal FD.
   Return zero if all's well, or -1 if we ran into an error we
   couldn't deal with.  */
int
752
emacs_get_tty (int fd, struct emacs_tty *settings)
753 754
{
  /* Retrieve the primary parameters - baud rate, character size, etcetera.  */
Dan Nicolaescu's avatar
Dan Nicolaescu committed
755
#ifndef DOS_NT
756
  /* We have those nifty POSIX tcmumbleattr functions.  */
757
  memset (&settings->main, 0, sizeof (settings->main));
758 759 760 761 762 763 764 765 766 767
  if (tcgetattr (fd, &settings->main) < 0)
    return -1;
#endif

  /* We have survived the tempest.  */
  return 0;
}


/* Set the parameters of the tty on FD according to the contents of
768
   *SETTINGS.  If FLUSHP is non-zero, we discard input.
769
   Return 0 if all went well, and -1 if anything failed.  */
770

771
int
772
emacs_set_tty (int fd, struct emacs_tty *settings, int flushp)
773 774
{
  /* Set the primary parameters - baud rate, character size, etcetera.  */
Dan Nicolaescu's avatar
Dan Nicolaescu committed
775
#ifndef DOS_NT
776
  int i;
777 778
  /* We have those nifty POSIX tcmumbleattr functions.
     William J. Smith <wjs@wiis.wang.com> writes:
779
     "POSIX 1003.1 defines tcsetattr to return success if it was
780 781 782 783
     able to perform any of the requested actions, even if some
     of the requested actions could not be performed.
     We must read settings back to ensure tty setup properly.
     AIX requires this to keep tty from hanging occasionally."  */
784
  /* This make sure that we don't loop indefinitely in here.  */
785
  for (i = 0 ; i < 10 ; i++)
786
    if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0)
787 788 789 790 791 792 793 794 795 796
      {
	if (errno == EINTR)
	  continue;
	else
	  return -1;
      }
    else
      {
	struct termios new;

797
	memset (&new, 0, sizeof (new));
798 799
	/* Get the current settings, and see if they're what we asked for.  */
	tcgetattr (fd, &new);
800 801 802 803 804 805 806 807
	/* We cannot use memcmp on the whole structure here because under
	 * aix386 the termios structure has some reserved field that may
	 * not be filled in.
	 */
	if (   new.c_iflag == settings->main.c_iflag
	    && new.c_oflag == settings->main.c_oflag
	    && new.c_cflag == settings->main.c_cflag
	    && new.c_lflag == settings->main.c_lflag
808
	    && memcmp (new.c_cc, settings->main.c_cc, NCCS) == 0)
809
	  break;
810 811
	else
	  continue;
812 813
      }
#endif
814

815 816 817 818
  /* We have survived the tempest.  */
  return 0;
}

Jim Blandy's avatar
Jim Blandy committed
819 820 821


#ifdef F_SETOWN
822
static int old_fcntl_owner[MAXDESC];
Jim Blandy's avatar
Jim Blandy committed
823 824 825 826 827 828
#endif /* F_SETOWN */

/* This may also be defined in stdio,
   but if so, this does no harm,
   and using the same name avoids wasting the other one's space.  */

829
#if defined (USG)
Jim Blandy's avatar
Jim Blandy committed
830 831 832 833
unsigned char _sobuf[BUFSIZ+8];
#else
char _sobuf[BUFSIZ];
#endif
Juanma Barranquero's avatar