root/src/sysdep.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. maybe_disable_address_randomization
  2. emacs_exec_file
  3. force_open
  4. init_standard_fds
  5. get_current_dir_name_or_unreachable
  6. emacs_get_current_dir_name
  7. discard_tty_input
  8. stuff_char
  9. init_baud_rate
  10. get_child_status
  11. wait_for_termination
  12. child_status_changed
  13. child_setup_tty
  14. sys_suspend
  15. sys_subshell
  16. save_signal_handlers
  17. restore_signal_handlers
  18. init_sigio
  19. reset_sigio
  20. request_sigio
  21. unrequest_sigio
  22. block_child_signal
  23. unblock_child_signal
  24. block_interrupt_signal
  25. restore_signal_mask
  26. init_foreground_group
  27. block_tty_out_signal
  28. unblock_tty_out_signal
  29. tcsetpgrp_without_stopping
  30. narrow_foreground_group
  31. widen_foreground_group
  32. emacs_get_tty
  33. emacs_set_tty
  34. init_all_sys_modes
  35. init_sys_modes
  36. tabs_safe_p
  37. suppress_echo_on_tty
  38. get_tty_size
  39. set_window_size
  40. reset_all_sys_modes
  41. reset_sys_modes
  42. setup_pty
  43. init_system_name
  44. emacs_sigaction_flags
  45. emacs_sigaction_init
  46. deliver_process_signal
  47. deliver_thread_signal
  48. handle_fatal_signal
  49. deliver_fatal_signal
  50. deliver_fatal_thread_signal
  51. handle_arith_signal
  52. stack_overflow
  53. handle_sigsegv
  54. init_sigsegv
  55. init_sigsegv
  56. deliver_arith_signal
  57. handle_danger_signal
  58. deliver_danger_signal
  59. maybe_fatal_sig
  60. init_signals
  61. set_random_seed
  62. set_random_seed
  63. set_random_seed
  64. seed_random
  65. init_random
  66. get_random
  67. get_random_ulong
  68. snprintf
  69. emacs_backtrace
  70. emacs_abort
  71. emacs_fstatat
  72. sys_openat
  73. emacs_openat
  74. emacs_open
  75. emacs_open_noquit
  76. emacs_fopen
  77. emacs_pipe
  78. posix_close
  79. emacs_close
  80. emacs_intr_read
  81. emacs_read
  82. emacs_read_quit
  83. emacs_full_write
  84. emacs_write
  85. emacs_write_sig
  86. emacs_write_quit
  87. emacs_perror
  88. renameat_noreplace
  89. safe_strsignal
  90. errstream
  91. errputc
  92. errwrite
  93. close_output_streams
  94. serial_open
  95. cfmakeraw
  96. cfsetspeed
  97. convert_speed
  98. serial_configure
  99. list_system_processes
  100. list_system_processes
  101. list_system_processes
  102. make_lisp_s_us
  103. make_lisp_timeval
  104. time_from_jiffies
  105. put_jiffies
  106. get_up_time
  107. procfs_ttyname
  108. procfs_get_total_memory
  109. system_process_attributes
  110. system_process_attributes
  111. system_process_attributes
  112. system_process_attributes
  113. system_process_attributes
  114. system_process_attributes
  115. DEFUN
  116. newlocale
  117. freelocale
  118. emacs_setlocale
  119. wcscoll_l
  120. towlower_l
  121. str_collate
  122. str_collate
  123. syms_of_sysdep

     1 /* Interfaces to system-dependent kernel and library entries.
     2    Copyright (C) 1985-1988, 1993-1995, 1999-2023 Free Software
     3    Foundation, Inc.
     4 
     5 This file is part of GNU Emacs.
     6 
     7 GNU Emacs is free software: you can redistribute it and/or modify
     8 it under the terms of the GNU General Public License as published by
     9 the Free Software Foundation, either version 3 of the License, or (at
    10 your option) any later version.
    11 
    12 GNU Emacs is distributed in the hope that it will be useful,
    13 but WITHOUT ANY WARRANTY; without even the implied warranty of
    14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15 GNU General Public License for more details.
    16 
    17 You should have received a copy of the GNU General Public License
    18 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    19 
    20 #include <config.h>
    21 
    22 #include <execinfo.h>
    23 #include "sysstdio.h"
    24 #ifdef HAVE_PWD_H
    25 #include <pwd.h>
    26 #include <grp.h>
    27 #endif /* HAVE_PWD_H */
    28 #include <limits.h>
    29 #include <stdlib.h>
    30 #include <sys/random.h>
    31 #include <unistd.h>
    32 
    33 #include <c-ctype.h>
    34 #include <close-stream.h>
    35 #include <pathmax.h>
    36 #include <utimens.h>
    37 
    38 #include "lisp.h"
    39 #include "sheap.h"
    40 #include "sysselect.h"
    41 #include "blockinput.h"
    42 
    43 #ifdef HAVE_LINUX_FS_H
    44 # include <linux/fs.h>
    45 # include <sys/syscall.h>
    46 #endif
    47 
    48 #ifdef CYGWIN
    49 # include <cygwin/fs.h>
    50 #endif
    51 
    52 #if defined DARWIN_OS || defined __FreeBSD__ || defined __OpenBSD__
    53 # include <sys/sysctl.h>
    54 #endif
    55 
    56 #if defined __OpenBSD__
    57 # include <sys/proc.h>
    58 #endif
    59 
    60 #ifdef DARWIN_OS
    61 # include <libproc.h>
    62 #endif
    63 
    64 #ifdef __FreeBSD__
    65 /* Sparc/ARM machine/frame.h has 'struct frame' which conflicts with Emacs's
    66    'struct frame', so rename it.  */
    67 # define frame freebsd_frame
    68 # include <sys/user.h>
    69 # undef frame
    70 
    71 # include <math.h>
    72 #endif
    73 
    74 #ifdef HAVE_SOCKETS
    75 #include <sys/socket.h>
    76 #include <netdb.h>
    77 #endif /* HAVE_SOCKETS */
    78 
    79 #ifdef WINDOWSNT
    80 #define read sys_read
    81 #define write sys_write
    82 #ifndef STDERR_FILENO
    83 #define STDERR_FILENO fileno(GetStdHandle(STD_ERROR_HANDLE))
    84 #endif
    85 #include "w32.h"
    86 #endif /* WINDOWSNT */
    87 
    88 #include <sys/types.h>
    89 #include <sys/stat.h>
    90 #include <errno.h>
    91 
    92 /* Get SI_SRPC_DOMAIN, if it is available.  */
    93 #ifdef HAVE_SYS_SYSTEMINFO_H
    94 #include <sys/systeminfo.h>
    95 #endif
    96 
    97 #ifdef MSDOS    /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
    98 #include "msdos.h"
    99 #endif
   100 
   101 #include <sys/param.h>
   102 #include <sys/file.h>
   103 #include <fcntl.h>
   104 
   105 #include "syssignal.h"
   106 #include "systime.h"
   107 #include "systty.h"
   108 #include "syswait.h"
   109 
   110 #ifdef HAVE_SYS_RESOURCE_H
   111 # include <sys/resource.h>
   112 #endif
   113 
   114 #ifdef HAVE_SYS_UTSNAME_H
   115 # include <sys/utsname.h>
   116 # include <memory.h>
   117 #endif
   118 
   119 #include "keyboard.h"
   120 #include "frame.h"
   121 #include "termhooks.h"
   122 #include "termchar.h"
   123 #include "termopts.h"
   124 #include "process.h"
   125 #include "cm.h"
   126 
   127 #ifdef WINDOWSNT
   128 # include <direct.h>
   129 /* In process.h which conflicts with the local copy.  */
   130 # define _P_WAIT 0
   131 int _cdecl _spawnlp (int, const char *, const char *, ...);
   132 /* The following is needed for O_CLOEXEC, F_SETFD, FD_CLOEXEC, and
   133    several prototypes of functions called below.  */
   134 # include <sys/socket.h>
   135 #endif
   136 
   137 /* Declare here, including term.h is problematic on some systems.  */
   138 extern void tputs (const char *, int, int (*)(int));
   139 
   140 static const int baud_convert[] =
   141   {
   142     0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
   143     1800, 2400, 4800, 9600, 19200, 38400
   144   };
   145 
   146 #ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE
   147 # include <sys/personality.h>
   148 
   149 /* If not -1, the personality that should be restored before exec.  */
   150 static int exec_personality;
   151 
   152 /* Try to disable randomization if the current process needs it and
   153    does not appear to have it already.  */
   154 int
   155 maybe_disable_address_randomization (int argc, char **argv)
   156 {
   157   /* Undocumented Emacs option used only by this function.  */
   158   static char const aslr_disabled_option[] = "--__aslr-disabled";
   159 
   160   if (argc < 2 || strcmp (argv[1], aslr_disabled_option) != 0)
   161     {
   162       /* If dumping via unexec, ASLR must be disabled, as otherwise
   163          data may be scattered and undumpable as a simple executable.
   164          If pdumping, disabling ASLR lessens differences in the .pdmp file.  */
   165       bool disable_aslr = will_dump_p ();
   166 # ifdef __PPC64__
   167       disable_aslr = true;
   168 # endif
   169       exec_personality = disable_aslr ? personality (0xffffffff) : -1;
   170       if (exec_personality & ADDR_NO_RANDOMIZE)
   171         exec_personality = -1;
   172       if (exec_personality != -1
   173           && personality (exec_personality | ADDR_NO_RANDOMIZE) != -1)
   174         {
   175           char **newargv = malloc ((argc + 2) * sizeof *newargv);
   176           if (newargv)
   177             {
   178               /* Invoke self with undocumented option.  */
   179               newargv[0] = argv[0];
   180               newargv[1] = (char *) aslr_disabled_option;
   181               memcpy (&newargv[2], &argv[1], argc * sizeof *newargv);
   182               execvp (newargv[0], newargv);
   183             }
   184 
   185           /* If malloc or execvp fails, warn and then try anyway.  */
   186           perror (argv[0]);
   187           free (newargv);
   188         }
   189     }
   190   else
   191     {
   192       /* Our earlier incarnation already disabled ASLR.  */
   193       argc--;
   194       memmove (&argv[1], &argv[2], argc * sizeof *argv);
   195     }
   196 
   197   return argc;
   198 }
   199 #endif
   200 
   201 #ifndef WINDOWSNT
   202 /* Execute the program in FILE, with argument vector ARGV and environ
   203    ENVP.  Return an error number if unsuccessful.  This is like execve
   204    except it reenables ASLR in the executed program if necessary, and
   205    on error it returns an error number rather than -1.  */
   206 int
   207 emacs_exec_file (char const *file, char *const *argv, char *const *envp)
   208 {
   209 #ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE
   210   if (exec_personality != -1)
   211     personality (exec_personality);
   212 #endif
   213 
   214   execve (file, argv, envp);
   215   return errno;
   216 }
   217 
   218 #endif  /* !WINDOWSNT */
   219 
   220 /* If FD is not already open, arrange for it to be open with FLAGS.  */
   221 static void
   222 force_open (int fd, int flags)
   223 {
   224   if (dup2 (fd, fd) < 0 && errno == EBADF)
   225     {
   226       int n = open (NULL_DEVICE, flags);
   227       if (n < 0 || (fd != n && (dup2 (n, fd) < 0 || emacs_close (n) != 0)))
   228         {
   229           emacs_perror (NULL_DEVICE);
   230           exit (EXIT_FAILURE);
   231         }
   232     }
   233 }
   234 
   235 /* A stream that is like stderr, except line buffered.  It is NULL
   236    during startup, or if line buffering is not in use.  */
   237 static FILE *buferr;
   238 
   239 /* Make sure stdin, stdout, and stderr are open to something, so that
   240    their file descriptors are not hijacked by later system calls.  */
   241 void
   242 init_standard_fds (void)
   243 {
   244   /* Open stdin for *writing*, and stdout and stderr for *reading*.
   245      That way, any attempt to do normal I/O will result in an error,
   246      just as if the files were closed, and the file descriptors will
   247      not be reused by later opens.  */
   248   force_open (STDIN_FILENO, O_WRONLY);
   249   force_open (STDOUT_FILENO, O_RDONLY);
   250   force_open (STDERR_FILENO, O_RDONLY);
   251 
   252   /* Set buferr if possible on platforms defining _PC_PIPE_BUF, as
   253      they support the notion of atomic writes to pipes.  */
   254   #ifdef _PC_PIPE_BUF
   255     buferr = fdopen (STDERR_FILENO, "w");
   256     if (buferr)
   257       setvbuf (buferr, NULL, _IOLBF, 0);
   258   #endif
   259 }
   260 
   261 /* Return the current working directory.  The result should be freed
   262    with 'free'.  Return NULL (setting errno) on errors.  If the
   263    current directory is unreachable, return either NULL or a string
   264    beginning with '('.  */
   265 
   266 static char *
   267 get_current_dir_name_or_unreachable (void)
   268 {
   269   /* Use malloc, not xmalloc, since this function can be called before
   270      the xmalloc exception machinery is available.  */
   271 
   272   char *pwd;
   273 
   274   /* The maximum size of a directory name, including the terminating null.
   275      Leave room so that the caller can append a trailing slash.  */
   276   ptrdiff_t dirsize_max = min (PTRDIFF_MAX, SIZE_MAX) - 1;
   277 
   278   /* The maximum size of a buffer for a file name, including the
   279      terminating null.  This is bounded by PATH_MAX, if available.  */
   280   ptrdiff_t bufsize_max = dirsize_max;
   281 #ifdef PATH_MAX
   282   bufsize_max = min (bufsize_max, PATH_MAX);
   283 #endif
   284 
   285 # if HAVE_GET_CURRENT_DIR_NAME && !BROKEN_GET_CURRENT_DIR_NAME
   286 #  ifdef HYBRID_MALLOC
   287   bool use_libc = will_dump_with_unexec_p ();
   288 #  else
   289   bool use_libc = true;
   290 #  endif
   291   if (use_libc)
   292     {
   293       /* For an unreachable directory, this returns a string that starts
   294          with "(unreachable)"; see Bug#27871.  */
   295       pwd = get_current_dir_name ();
   296       if (pwd)
   297         {
   298           if (strnlen (pwd, dirsize_max) < dirsize_max)
   299             return pwd;
   300           free (pwd);
   301           errno = ERANGE;
   302         }
   303       return NULL;
   304     }
   305 # endif
   306 
   307   size_t pwdlen;
   308   struct stat dotstat, pwdstat;
   309   pwd = getenv ("PWD");
   310 
   311   /* If PWD is accurate, use it instead of calling getcwd.  PWD is
   312      sometimes a nicer name, and using it may avoid a fatal error if a
   313      parent directory is searchable but not readable.  */
   314   if (pwd
   315       && (pwdlen = strnlen (pwd, bufsize_max)) < bufsize_max
   316       && IS_DIRECTORY_SEP (pwd[pwdlen && IS_DEVICE_SEP (pwd[1]) ? 2 : 0])
   317       && emacs_fstatat (AT_FDCWD, pwd, &pwdstat, 0) == 0
   318       && emacs_fstatat (AT_FDCWD, ".", &dotstat, 0) == 0
   319       && dotstat.st_ino == pwdstat.st_ino
   320       && dotstat.st_dev == pwdstat.st_dev)
   321     return strdup (pwd);
   322   else
   323     {
   324       ptrdiff_t buf_size = min (bufsize_max, 1024);
   325       for (;;)
   326         {
   327           char *buf = malloc (buf_size);
   328           if (!buf)
   329             return NULL;
   330           if (getcwd (buf, buf_size) == buf)
   331             return buf;
   332           free (buf);
   333           if (errno != ERANGE || buf_size == bufsize_max)
   334             return NULL;
   335           buf_size = buf_size <= bufsize_max / 2 ? 2 * buf_size : bufsize_max;
   336         }
   337     }
   338 }
   339 
   340 /* Return the current working directory.  The result should be freed
   341    with 'free'.  Return NULL (setting errno) on errors; an unreachable
   342    directory (e.g., its name starts with '(') counts as an error.  */
   343 
   344 char *
   345 emacs_get_current_dir_name (void)
   346 {
   347   char *dir = get_current_dir_name_or_unreachable ();
   348   if (dir && *dir == '(')
   349     {
   350       free (dir);
   351       errno = ENOENT;
   352       return NULL;
   353     }
   354   return dir;
   355 }
   356 
   357 
   358 /* Discard pending input on all input descriptors.  */
   359 
   360 void
   361 discard_tty_input (void)
   362 {
   363 #ifndef WINDOWSNT
   364   struct emacs_tty buf;
   365 
   366   if (noninteractive)
   367     return;
   368 
   369 #ifdef MSDOS    /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
   370   while (dos_keyread () != -1)
   371     ;
   372 #else /* not MSDOS */
   373   {
   374     struct tty_display_info *tty;
   375     for (tty = tty_list; tty; tty = tty->next)
   376       {
   377         if (tty->input)         /* Is the device suspended? */
   378           {
   379             emacs_get_tty (fileno (tty->input), &buf);
   380             emacs_set_tty (fileno (tty->input), &buf, 0);
   381           }
   382       }
   383   }
   384 #endif /* not MSDOS */
   385 #endif /* not WINDOWSNT */
   386 }
   387 
   388 
   389 #ifdef SIGTSTP
   390 
   391 /* Arrange for character C to be read as the next input from
   392    the terminal.
   393    XXX What if we have multiple ttys?
   394 */
   395 
   396 void
   397 stuff_char (char c)
   398 {
   399   if (! (FRAMEP (selected_frame)
   400          && FRAME_LIVE_P (XFRAME (selected_frame))
   401          && FRAME_TERMCAP_P (XFRAME (selected_frame))))
   402     return;
   403 
   404 /* Should perhaps error if in batch mode */
   405 #ifdef TIOCSTI
   406   ioctl (fileno (CURTTY()->input), TIOCSTI, &c);
   407 #else /* no TIOCSTI */
   408   error ("Cannot stuff terminal input characters in this version of Unix");
   409 #endif /* no TIOCSTI */
   410 }
   411 
   412 #endif /* SIGTSTP */
   413 
   414 void
   415 init_baud_rate (int fd)
   416 {
   417   int emacs_ospeed;
   418 
   419   if (noninteractive)
   420     emacs_ospeed = 0;
   421   else
   422     {
   423 #ifdef DOS_NT
   424     emacs_ospeed = 15;
   425 #else  /* not DOS_NT */
   426       struct termios sg;
   427 
   428       sg.c_cflag = B9600;
   429       tcgetattr (fd, &sg);
   430       emacs_ospeed = cfgetospeed (&sg);
   431 #endif /* not DOS_NT */
   432     }
   433 
   434   baud_rate = (emacs_ospeed < ARRAYELTS (baud_convert)
   435                ? baud_convert[emacs_ospeed] : 9600);
   436   if (baud_rate == 0)
   437     baud_rate = 1200;
   438 }
   439 
   440 
   441 
   442 #ifndef MSDOS
   443 
   444 /* Wait for the subprocess with process id CHILD to terminate or change status.
   445    CHILD must be a child process that has not been reaped.
   446    If STATUS is non-null, store the waitpid-style exit status into *STATUS
   447    and tell wait_reading_process_output that it needs to look around.
   448    Use waitpid-style OPTIONS when waiting.
   449    If INTERRUPTIBLE, this function is interruptible by a signal.
   450 
   451    Return CHILD if successful, 0 if no status is available, and a
   452    negative value (setting errno) if waitpid is buggy.  */
   453 static pid_t
   454 get_child_status (pid_t child, int *status, int options, bool interruptible)
   455 {
   456   pid_t pid;
   457 
   458   /* Invoke waitpid only with a known process ID; do not invoke
   459      waitpid with a nonpositive argument.  Otherwise, Emacs might
   460      reap an unwanted process by mistake.  For example, invoking
   461      waitpid (-1, ...) can mess up glib by reaping glib's subprocesses,
   462      so that another thread running glib won't find them.  */
   463   eassert (child > 0);
   464 
   465   while (true)
   466     {
   467       /* Note: the MS-Windows emulation of waitpid calls maybe_quit
   468          internally.  */
   469       if (interruptible)
   470         maybe_quit ();
   471 
   472       pid = waitpid (child, status, options);
   473       if (0 <= pid)
   474         break;
   475       if (errno != EINTR)
   476         {
   477           /* Most likely, waitpid is buggy and the operating system
   478              lost track of the child somehow.  Return -1 and let the
   479              caller try to figure things out.  Possibly the bug could
   480              cause Emacs to kill the wrong process.  Oh well.  */
   481           return pid;
   482         }
   483     }
   484 
   485   /* If successful and status is requested, tell wait_reading_process_output
   486      that it needs to wake up and look around.  */
   487   if (pid && status && input_available_clear_time)
   488     *input_available_clear_time = make_timespec (0, 0);
   489 
   490   return pid;
   491 }
   492 
   493 /* Wait for the subprocess with process id CHILD to terminate.
   494    CHILD must be a child process that has not been reaped.
   495    If STATUS is non-null, store the waitpid-style exit status into *STATUS
   496    and tell wait_reading_process_output that it needs to look around.
   497    If INTERRUPTIBLE, this function is interruptible by a signal.
   498    Return true if successful, false (setting errno) if CHILD cannot be
   499    waited for because waitpid is buggy.  */
   500 bool
   501 wait_for_termination (pid_t child, int *status, bool interruptible)
   502 {
   503   return 0 <= get_child_status (child, status, 0, interruptible);
   504 }
   505 
   506 /* Report whether the subprocess with process id CHILD has changed status.
   507    Termination counts as a change of status.
   508    CHILD must be a child process that has not been reaped.
   509    If STATUS is non-null, store the waitpid-style exit status into *STATUS
   510    and tell wait_reading_process_output that it needs to look around.
   511    Use waitpid-style OPTIONS to check status, but do not wait.
   512 
   513    Return CHILD if successful, 0 if no status is available because
   514    the process's state has not changed.  */
   515 pid_t
   516 child_status_changed (pid_t child, int *status, int options)
   517 {
   518   return get_child_status (child, status, WNOHANG | options, 0);
   519 }
   520 
   521 
   522 /*  Set up the terminal at the other end of a pseudo-terminal that
   523     we will be controlling an inferior through.
   524     It should not echo or do line-editing, since that is done
   525     in Emacs.  No padding needed for insertion into an Emacs buffer.  */
   526 
   527 void
   528 child_setup_tty (int out)
   529 {
   530 #ifndef WINDOWSNT
   531   struct emacs_tty s;
   532 
   533   emacs_get_tty (out, &s);
   534   s.main.c_oflag |= OPOST;      /* Enable output postprocessing */
   535   s.main.c_oflag &= ~ONLCR;     /* Disable map of NL to CR-NL on output */
   536 #ifdef NLDLY
   537   /* https://lists.gnu.org/r/emacs-devel/2008-05/msg00406.html
   538      Some versions of GNU Hurd do not have FFDLY?  */
   539 #ifdef FFDLY
   540   s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
   541                                 /* No output delays */
   542 #else
   543   s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY);
   544                                 /* No output delays */
   545 #endif
   546 #endif
   547   s.main.c_lflag &= ~ECHO;      /* Disable echo */
   548   s.main.c_lflag |= ISIG;       /* Enable signals */
   549 #ifdef IUCLC
   550   s.main.c_iflag &= ~IUCLC;     /* Disable downcasing on input.  */
   551 #endif
   552 #ifdef ISTRIP
   553   s.main.c_iflag &= ~ISTRIP;    /* don't strip 8th bit on input */
   554 #endif
   555 #ifdef OLCUC
   556   s.main.c_oflag &= ~OLCUC;     /* Disable upcasing on output.  */
   557 #endif
   558   s.main.c_oflag &= ~TAB3;      /* Disable tab expansion */
   559   s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */
   560   s.main.c_cc[VERASE] = CDISABLE;       /* disable erase processing */
   561   s.main.c_cc[VKILL] = CDISABLE;        /* disable kill processing */
   562 
   563 #ifdef HPUX
   564   s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
   565 #endif /* HPUX */
   566 
   567 #ifdef SIGNALS_VIA_CHARACTERS
   568   /* the QUIT and INTR character are used in process_send_signal
   569      so set them here to something useful.  */
   570   if (s.main.c_cc[VQUIT] == CDISABLE)
   571     s.main.c_cc[VQUIT] = '\\'&037;      /* Control-\ */
   572   if (s.main.c_cc[VINTR] == CDISABLE)
   573     s.main.c_cc[VINTR] = 'C'&037;       /* Control-C */
   574 #endif /* not SIGNALS_VIA_CHARACTERS */
   575 
   576 #ifdef AIX
   577   /* Also, PTY overloads NUL and BREAK.
   578      don't ignore break, but don't signal either, so it looks like NUL.  */
   579   s.main.c_iflag &= ~IGNBRK;
   580   s.main.c_iflag &= ~BRKINT;
   581   /* rms: Formerly it set s.main.c_cc[VINTR] to 0377 here
   582      unconditionally.  Then a SIGNALS_VIA_CHARACTERS conditional
   583      would force it to 0377.  That looks like duplicated code.  */
   584   s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
   585 #endif /* AIX */
   586 
   587   /* We originally enabled ICANON (and set VEOF to 04), and then had
   588      process.c send additional EOF chars to flush the output when faced
   589      with long lines, but this leads to weird effects when the
   590      subprocess has disabled ICANON and ends up seeing those spurious
   591      extra EOFs.  So we don't send EOFs any more in
   592      process.c:send_process.  First we tried to disable ICANON by
   593      default, so if a subsprocess sets up ICANON, it's his problem (or
   594      the Elisp package that talks to it) to deal with lines that are
   595      too long.  But this disables some features, such as the ability
   596      to send EOF signals.  So we re-enabled ICANON but there is no
   597      more "send eof to flush" going on (which is wrong and unportable
   598      in itself).  The correct way to handle too much output is to
   599      buffer what could not be written and then write it again when
   600      select returns ok for writing.  This has it own set of
   601      problems.  Write is now asynchronous, is that a problem?  How much
   602      do we buffer, and what do we do when that limit is reached?  */
   603 
   604   s.main.c_lflag |= ICANON;     /* Enable line editing and eof processing */
   605   s.main.c_cc[VEOF] = 'D'&037;  /* Control-D */
   606 #if 0       /* These settings only apply to non-ICANON mode. */
   607   s.main.c_cc[VMIN] = 1;
   608   s.main.c_cc[VTIME] = 0;
   609 #endif
   610 
   611   emacs_set_tty (out, &s, 0);
   612 #endif /* not WINDOWSNT */
   613 }
   614 #endif  /* not MSDOS */
   615 
   616 
   617 /* Record a signal code and the action for it.  */
   618 struct save_signal
   619 {
   620   int code;
   621   struct sigaction action;
   622 };
   623 
   624 static void save_signal_handlers (struct save_signal *);
   625 static void restore_signal_handlers (struct save_signal *);
   626 
   627 /* Suspend the Emacs process; give terminal to its superior.  */
   628 
   629 void
   630 sys_suspend (void)
   631 {
   632 #ifndef DOS_NT
   633   kill (0, SIGTSTP);
   634 #else
   635 /* On a system where suspending is not implemented,
   636    instead fork a subshell and let it talk directly to the terminal
   637    while we wait.  */
   638   sys_subshell ();
   639 
   640 #endif
   641 }
   642 
   643 /* Fork a subshell.  */
   644 
   645 void
   646 sys_subshell (void)
   647 {
   648 #ifdef DOS_NT   /* Demacs 1.1.2 91/10/20 Manabu Higashida */
   649 #ifdef MSDOS
   650   int st;
   651   char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS.  */
   652 #else
   653   char oldwd[MAX_UTF8_PATH];
   654 #endif  /* MSDOS */
   655 #else   /* !DOS_NT */
   656   int status;
   657 #endif
   658   pid_t pid;
   659   struct save_signal saved_handlers[5];
   660   char *str = SSDATA (get_current_directory (true));
   661 
   662 #ifdef DOS_NT
   663   pid = 0;
   664 #else
   665   {
   666     char *volatile str_volatile = str;
   667     pid = VFORK ();
   668     str = str_volatile;
   669   }
   670 #endif
   671 
   672   if (pid < 0)
   673     error ("Can't spawn subshell");
   674 
   675   saved_handlers[0].code = SIGINT;
   676   saved_handlers[1].code = SIGQUIT;
   677   saved_handlers[2].code = SIGTERM;
   678 #ifdef USABLE_SIGIO
   679   saved_handlers[3].code = SIGIO;
   680   saved_handlers[4].code = 0;
   681 #elif defined (USABLE_SIGPOLL)
   682   saved_handlers[3].code = SIGPOLL;
   683   saved_handlers[4].code = 0;
   684 #else
   685   saved_handlers[3].code = 0;
   686 #endif
   687 
   688 #ifdef DOS_NT
   689   save_signal_handlers (saved_handlers);
   690 #endif
   691 
   692   if (pid == 0)
   693     {
   694       const char *sh = 0;
   695 
   696 #ifdef DOS_NT    /* MW, Aug 1993 */
   697       getcwd (oldwd, sizeof oldwd);
   698       if (sh == 0)
   699         sh = egetenv ("SUSPEND");       /* KFS, 1994-12-14 */
   700 #endif
   701       if (sh == 0)
   702         sh = egetenv ("SHELL");
   703       if (sh == 0)
   704         sh = "sh";
   705 
   706       /* Use our buffer's default directory for the subshell.  */
   707       if (chdir (str) != 0)
   708         {
   709 #ifndef DOS_NT
   710           emacs_perror (str);
   711           _exit (EXIT_CANCELED);
   712 #endif
   713         }
   714 
   715 #ifdef MSDOS    /* Demacs 1.1.2 91/10/20 Manabu Higashida */
   716       {
   717         char *epwd = getenv ("PWD");
   718         char old_pwd[MAXPATHLEN+1+4];
   719 
   720         /* If PWD is set, pass it with corrected value.  */
   721         if (epwd)
   722           {
   723             strcpy (old_pwd, epwd);
   724             setenv ("PWD", str, 1);
   725           }
   726         st = system (sh);
   727         chdir (oldwd);  /* FIXME: Do the right thing on chdir failure.  */
   728         if (epwd)
   729           putenv (old_pwd);     /* restore previous value */
   730       }
   731 #else /* not MSDOS */
   732 #ifdef  WINDOWSNT
   733       /* Waits for process completion */
   734       pid = _spawnlp (_P_WAIT, sh, sh, NULL);
   735       chdir (oldwd);    /* FIXME: Do the right thing on chdir failure.  */
   736       if (pid == -1)
   737         write (1, "Can't execute subshell", 22);
   738 #else   /* not WINDOWSNT */
   739       execlp (sh, sh, (char *) 0);
   740       emacs_perror (sh);
   741       _exit (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
   742 #endif  /* not WINDOWSNT */
   743 #endif /* not MSDOS */
   744     }
   745 
   746   /* Do this now if we did not do it before.  */
   747 #ifndef MSDOS
   748   save_signal_handlers (saved_handlers);
   749 #endif
   750 
   751 #ifndef DOS_NT
   752   wait_for_termination (pid, &status, 0);
   753 #endif
   754   restore_signal_handlers (saved_handlers);
   755 }
   756 
   757 static void
   758 save_signal_handlers (struct save_signal *saved_handlers)
   759 {
   760   while (saved_handlers->code)
   761     {
   762       struct sigaction action;
   763       emacs_sigaction_init (&action, SIG_IGN);
   764       sigaction (saved_handlers->code, &action, &saved_handlers->action);
   765       saved_handlers++;
   766     }
   767 }
   768 
   769 static void
   770 restore_signal_handlers (struct save_signal *saved_handlers)
   771 {
   772   while (saved_handlers->code)
   773     {
   774       sigaction (saved_handlers->code, &saved_handlers->action, 0);
   775       saved_handlers++;
   776     }
   777 }
   778 
   779 #ifdef USABLE_SIGIO
   780 static int old_fcntl_flags[FD_SETSIZE];
   781 #endif
   782 
   783 void
   784 init_sigio (int fd)
   785 {
   786 #ifdef USABLE_SIGIO
   787   old_fcntl_flags[fd] = fcntl (fd, F_GETFL, 0) & ~FASYNC;
   788   fcntl (fd, F_SETFL, old_fcntl_flags[fd] | FASYNC);
   789   interrupts_deferred = 0;
   790 #endif
   791 }
   792 
   793 #ifndef DOS_NT
   794 #ifdef F_SETOWN
   795 static void
   796 reset_sigio (int fd)
   797 {
   798 #ifdef USABLE_SIGIO
   799   fcntl (fd, F_SETFL, old_fcntl_flags[fd]);
   800 #endif
   801 }
   802 #endif /* F_SETOWN */
   803 #endif
   804 
   805 void
   806 request_sigio (void)
   807 {
   808 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
   809   sigset_t unblocked;
   810 
   811   if (noninteractive)
   812     return;
   813 
   814   sigemptyset (&unblocked);
   815 # ifdef SIGWINCH
   816   sigaddset (&unblocked, SIGWINCH);
   817 # endif
   818 # ifdef USABLE_SIGIO
   819   sigaddset (&unblocked, SIGIO);
   820 # else
   821   sigaddset (&unblocked, SIGPOLL);
   822 # endif
   823   pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
   824 
   825   interrupts_deferred = 0;
   826 #endif
   827 }
   828 
   829 void
   830 unrequest_sigio (void)
   831 {
   832 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
   833   sigset_t blocked;
   834 
   835   if (noninteractive)
   836     return;
   837 
   838   sigemptyset (&blocked);
   839 # ifdef SIGWINCH
   840   sigaddset (&blocked, SIGWINCH);
   841 # endif
   842 # ifdef USABLE_SIGIO
   843   sigaddset (&blocked, SIGIO);
   844 # else
   845   sigaddset (&blocked, SIGPOLL);
   846 # endif
   847   pthread_sigmask (SIG_BLOCK, &blocked, 0);
   848   interrupts_deferred = 1;
   849 #endif
   850 }
   851 
   852 #ifndef MSDOS
   853 /* Block SIGCHLD.  */
   854 
   855 void
   856 block_child_signal (sigset_t *oldset)
   857 {
   858   sigset_t blocked;
   859   sigemptyset (&blocked);
   860   sigaddset (&blocked, SIGCHLD);
   861   sigaddset (&blocked, SIGINT);
   862   pthread_sigmask (SIG_BLOCK, &blocked, oldset);
   863 }
   864 
   865 /* Unblock SIGCHLD.  */
   866 
   867 void
   868 unblock_child_signal (sigset_t const *oldset)
   869 {
   870   pthread_sigmask (SIG_SETMASK, oldset, 0);
   871 }
   872 
   873 #endif  /* !MSDOS */
   874 
   875 /* Block SIGINT.  */
   876 void
   877 block_interrupt_signal (sigset_t *oldset)
   878 {
   879   sigset_t blocked;
   880   sigemptyset (&blocked);
   881   sigaddset (&blocked, SIGINT);
   882   pthread_sigmask (SIG_BLOCK, &blocked, oldset);
   883 }
   884 
   885 /* Restore previously saved signal mask.  */
   886 void
   887 restore_signal_mask (sigset_t const *oldset)
   888 {
   889   pthread_sigmask (SIG_SETMASK, oldset, 0);
   890 }
   891 
   892 
   893 /* Saving and restoring the process group of Emacs's terminal.  */
   894 
   895 /* The process group of which Emacs was a member when it initially
   896    started.
   897 
   898    If Emacs was in its own process group (i.e. inherited_pgroup ==
   899    getpid ()), then we know we're running under a shell with job
   900    control (Emacs would never be run as part of a pipeline).
   901    Everything is fine.
   902 
   903    If Emacs was not in its own process group, then we know we're
   904    running under a shell (or a caller) that doesn't know how to
   905    separate itself from Emacs (like sh).  Emacs must be in its own
   906    process group in order to receive SIGIO correctly.  In this
   907    situation, we put ourselves in our own pgroup, forcibly set the
   908    tty's pgroup to our pgroup, and make sure to restore and reinstate
   909    the tty's pgroup just like any other terminal setting.  If
   910    inherited_group was not the tty's pgroup, then we'll get a
   911    SIGTTmumble when we try to change the tty's pgroup, and a CONT if
   912    it goes foreground in the future, which is what should happen.  */
   913 
   914 static pid_t inherited_pgroup;
   915 
   916 void
   917 init_foreground_group (void)
   918 {
   919   pid_t pgrp = getpgrp ();
   920   inherited_pgroup = getpid () == pgrp ? 0 : pgrp;
   921 }
   922 
   923 /* Block and unblock SIGTTOU.  */
   924 
   925 void
   926 block_tty_out_signal (sigset_t *oldset)
   927 {
   928 #ifdef SIGTTOU
   929   sigset_t blocked;
   930   sigemptyset (&blocked);
   931   sigaddset (&blocked, SIGTTOU);
   932   pthread_sigmask (SIG_BLOCK, &blocked, oldset);
   933 #endif
   934 }
   935 
   936 void
   937 unblock_tty_out_signal (sigset_t const *oldset)
   938 {
   939 #ifdef SIGTTOU
   940   pthread_sigmask (SIG_SETMASK, oldset, 0);
   941 #endif
   942 }
   943 
   944 /* Safely set a controlling terminal FD's process group to PGID.
   945    If we are not in the foreground already, POSIX requires tcsetpgrp
   946    to deliver a SIGTTOU signal, which would stop us.  This is an
   947    annoyance, so temporarily ignore the signal.
   948 
   949    In practice, platforms lacking SIGTTOU also lack tcsetpgrp, so
   950    skip all this unless SIGTTOU is defined.  */
   951 static void
   952 tcsetpgrp_without_stopping (int fd, pid_t pgid)
   953 {
   954 #ifdef SIGTTOU
   955   sigset_t oldset;
   956   block_input ();
   957   block_tty_out_signal (&oldset);
   958   tcsetpgrp (fd, pgid);
   959   unblock_tty_out_signal (&oldset);
   960   unblock_input ();
   961 #endif
   962 }
   963 
   964 /* Split off the foreground process group to Emacs alone.  When we are
   965    in the foreground, but not started in our own process group,
   966    redirect the tty device handle FD to point to our own process
   967    group.  FD must be the file descriptor of the controlling tty.  */
   968 static void
   969 narrow_foreground_group (int fd)
   970 {
   971   if (inherited_pgroup && setpgid (0, 0) == 0)
   972     tcsetpgrp_without_stopping (fd, getpid ());
   973 }
   974 
   975 /* Set the tty to our original foreground group.  */
   976 static void
   977 widen_foreground_group (int fd)
   978 {
   979   if (inherited_pgroup && setpgid (0, inherited_pgroup) == 0)
   980     tcsetpgrp_without_stopping (fd, inherited_pgroup);
   981 }
   982 
   983 /* Getting and setting emacs_tty structures.  */
   984 
   985 /* Set *TC to the parameters associated with the terminal FD,
   986    or clear it if the parameters are not available.
   987    Return 0 on success, -1 on failure.  */
   988 int
   989 emacs_get_tty (int fd, struct emacs_tty *settings)
   990 {
   991   /* Retrieve the primary parameters - baud rate, character size, etcetera.  */
   992   memset (&settings->main, 0, sizeof (settings->main));
   993 #ifdef DOS_NT
   994 #ifdef WINDOWSNT
   995   HANDLE h = (HANDLE)_get_osfhandle (fd);
   996   DWORD console_mode;
   997 
   998   if (h && h != INVALID_HANDLE_VALUE && GetConsoleMode (h, &console_mode))
   999     {
  1000       settings->main = console_mode;
  1001       return 0;
  1002     }
  1003 #endif  /* WINDOWSNT */
  1004   return -1;
  1005 #else   /* !DOS_NT */
  1006   /* We have those nifty POSIX tcmumbleattr functions.  */
  1007   return tcgetattr (fd, &settings->main);
  1008 #endif
  1009 }
  1010 
  1011 
  1012 /* Set the parameters of the tty on FD according to the contents of
  1013    *SETTINGS.  If FLUSHP, discard input.
  1014    Return 0 if all went well, and -1 (setting errno) if anything failed.  */
  1015 
  1016 int
  1017 emacs_set_tty (int fd, struct emacs_tty *settings, bool flushp)
  1018 {
  1019   /* Set the primary parameters - baud rate, character size, etcetera.  */
  1020 #ifdef DOS_NT
  1021 #ifdef WINDOWSNT
  1022   HANDLE h = (HANDLE)_get_osfhandle (fd);
  1023 
  1024   if (h && h != INVALID_HANDLE_VALUE)
  1025     {
  1026       DWORD new_mode;
  1027 
  1028       /* Assume the handle is open for input.  */
  1029       if (flushp)
  1030         FlushConsoleInputBuffer (h);
  1031       new_mode = settings->main;
  1032       SetConsoleMode (h, new_mode);
  1033     }
  1034 #endif  /* WINDOWSNT */
  1035 #else  /* !DOS_NT */
  1036   int i;
  1037   /* We have those nifty POSIX tcmumbleattr functions.
  1038      William J. Smith <wjs@wiis.wang.com> writes:
  1039      "POSIX 1003.1 defines tcsetattr to return success if it was
  1040      able to perform any of the requested actions, even if some
  1041      of the requested actions could not be performed.
  1042      We must read settings back to ensure tty setup properly.
  1043      AIX requires this to keep tty from hanging occasionally."  */
  1044   /* This make sure that we don't loop indefinitely in here.  */
  1045   for (i = 0 ; i < 10 ; i++)
  1046     if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0)
  1047       {
  1048         if (errno == EINTR)
  1049           continue;
  1050         else
  1051           return -1;
  1052       }
  1053     else
  1054       {
  1055         struct termios new;
  1056 
  1057         memset (&new, 0, sizeof (new));
  1058         /* Get the current settings, and see if they're what we asked for.  */
  1059         tcgetattr (fd, &new);
  1060         /* We cannot use memcmp on the whole structure here because under
  1061          * aix386 the termios structure has some reserved field that may
  1062          * not be filled in.
  1063          */
  1064         if (   new.c_iflag == settings->main.c_iflag
  1065             && new.c_oflag == settings->main.c_oflag
  1066             && new.c_cflag == settings->main.c_cflag
  1067             && new.c_lflag == settings->main.c_lflag
  1068             && memcmp (new.c_cc, settings->main.c_cc, NCCS) == 0)
  1069           break;
  1070         else
  1071           continue;
  1072       }
  1073 #endif
  1074 
  1075   /* We have survived the tempest.  */
  1076   return 0;
  1077 }
  1078 
  1079 
  1080 
  1081 #ifdef F_SETOWN
  1082 static int old_fcntl_owner[FD_SETSIZE];
  1083 #endif /* F_SETOWN */
  1084 
  1085 /* Initialize the terminal mode on all tty devices that are currently
  1086    open. */
  1087 
  1088 void
  1089 init_all_sys_modes (void)
  1090 {
  1091   struct tty_display_info *tty;
  1092   for (tty = tty_list; tty; tty = tty->next)
  1093     init_sys_modes (tty);
  1094 }
  1095 
  1096 /* Initialize the terminal mode on the given tty device. */
  1097 
  1098 void
  1099 init_sys_modes (struct tty_display_info *tty_out)
  1100 {
  1101   struct emacs_tty tty;
  1102 #ifndef DOS_NT
  1103   Lisp_Object terminal;
  1104 #endif
  1105 
  1106   Vtty_erase_char = Qnil;
  1107 
  1108   if (noninteractive)
  1109     return;
  1110 
  1111   if (!tty_out->output)
  1112     return;                     /* The tty is suspended. */
  1113 
  1114   narrow_foreground_group (fileno (tty_out->input));
  1115 
  1116   if (! tty_out->old_tty)
  1117     tty_out->old_tty = xmalloc (sizeof *tty_out->old_tty);
  1118 
  1119   emacs_get_tty (fileno (tty_out->input), tty_out->old_tty);
  1120 
  1121   tty = *tty_out->old_tty;
  1122 
  1123 #if !defined (DOS_NT)
  1124   XSETINT (Vtty_erase_char, tty.main.c_cc[VERASE]);
  1125 
  1126   tty.main.c_iflag |= (IGNBRK); /* Ignore break condition */
  1127   tty.main.c_iflag &= ~ICRNL;   /* Disable map of CR to NL on input */
  1128 #ifdef INLCR  /* I'm just being cautious,
  1129                  since I can't check how widespread INLCR is--rms.  */
  1130   tty.main.c_iflag &= ~INLCR;   /* Disable map of NL to CR on input */
  1131 #endif
  1132 #ifdef ISTRIP
  1133   tty.main.c_iflag &= ~ISTRIP;  /* don't strip 8th bit on input */
  1134 #endif
  1135   tty.main.c_lflag &= ~ECHO;    /* Disable echo */
  1136   tty.main.c_lflag &= ~ICANON;  /* Disable erase/kill processing */
  1137 #ifdef IEXTEN
  1138   tty.main.c_lflag &= ~IEXTEN;  /* Disable other editing characters.  */
  1139 #endif
  1140   tty.main.c_lflag |= ISIG;     /* Enable signals */
  1141   if (tty_out->flow_control)
  1142     {
  1143       tty.main.c_iflag |= IXON; /* Enable start/stop output control */
  1144 #ifdef IXANY
  1145       tty.main.c_iflag &= ~IXANY;
  1146 #endif /* IXANY */
  1147     }
  1148   else
  1149     tty.main.c_iflag &= ~IXON;  /* Disable start/stop output control */
  1150   tty.main.c_oflag &= ~ONLCR;   /* Disable map of NL to CR-NL
  1151                                    on output */
  1152   tty.main.c_oflag &= ~TAB3;    /* Disable tab expansion */
  1153 #ifdef CS8
  1154   if (tty_out->meta_key)
  1155     {
  1156       tty.main.c_cflag |= CS8;  /* allow 8th bit on input */
  1157       tty.main.c_cflag &= ~PARENB;/* Don't check parity */
  1158     }
  1159 #endif
  1160 
  1161   XSETTERMINAL(terminal, tty_out->terminal);
  1162   if (!NILP (Fcontrolling_tty_p (terminal)))
  1163     {
  1164       tty.main.c_cc[VINTR] = quit_char; /* C-g (usually) gives SIGINT */
  1165       /* Set up C-g for both SIGQUIT and SIGINT.
  1166          We don't know which we will get, but we handle both alike
  1167          so which one it really gives us does not matter.  */
  1168       tty.main.c_cc[VQUIT] = quit_char;
  1169     }
  1170   else
  1171     {
  1172       /* We normally don't get interrupt or quit signals from tty
  1173          devices other than our controlling terminal; therefore,
  1174          we must handle C-g as normal input.  Unfortunately, this
  1175          means that the interrupt and quit feature must be
  1176          disabled on secondary ttys, or we would not even see the
  1177          keypress.
  1178 
  1179          Note that even though emacsclient could have special code
  1180          to pass SIGINT to Emacs, we should _not_ enable
  1181          interrupt/quit keys for emacsclient frames.  This means
  1182          that we can't break out of loops in C code from a
  1183          secondary tty frame, but we can always decide what
  1184          display the C-g came from, which is more important from a
  1185          usability point of view.  (Consider the case when two
  1186          people work together using the same Emacs instance.)  */
  1187       tty.main.c_cc[VINTR] = CDISABLE;
  1188       tty.main.c_cc[VQUIT] = CDISABLE;
  1189     }
  1190   tty.main.c_cc[VMIN] = 1;      /* Input should wait for at least 1 char */
  1191   tty.main.c_cc[VTIME] = 0;     /* no matter how long that takes.  */
  1192 #ifdef VSWTCH
  1193   tty.main.c_cc[VSWTCH] = CDISABLE;     /* Turn off shell layering use
  1194                                            of C-z */
  1195 #endif /* VSWTCH */
  1196 
  1197 #ifdef VSUSP
  1198   tty.main.c_cc[VSUSP] = CDISABLE;      /* Turn off handling of C-z.  */
  1199 #endif /* VSUSP */
  1200 #ifdef V_DSUSP
  1201   tty.main.c_cc[V_DSUSP] = CDISABLE; /* Turn off handling of C-y.  */
  1202 #endif /* V_DSUSP */
  1203 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP.  */
  1204   tty.main.c_cc[VDSUSP] = CDISABLE;
  1205 #endif /* VDSUSP */
  1206 #ifdef VLNEXT
  1207   tty.main.c_cc[VLNEXT] = CDISABLE;
  1208 #endif /* VLNEXT */
  1209 #ifdef VREPRINT
  1210   tty.main.c_cc[VREPRINT] = CDISABLE;
  1211 #endif /* VREPRINT */
  1212 #ifdef VWERASE
  1213   tty.main.c_cc[VWERASE] = CDISABLE;
  1214 #endif /* VWERASE */
  1215 #ifdef VDISCARD
  1216   tty.main.c_cc[VDISCARD] = CDISABLE;
  1217 #endif /* VDISCARD */
  1218 
  1219   if (tty_out->flow_control)
  1220     {
  1221 #ifdef VSTART
  1222       tty.main.c_cc[VSTART] = '\021';
  1223 #endif /* VSTART */
  1224 #ifdef VSTOP
  1225       tty.main.c_cc[VSTOP] = '\023';
  1226 #endif /* VSTOP */
  1227     }
  1228   else
  1229     {
  1230 #ifdef VSTART
  1231       tty.main.c_cc[VSTART] = CDISABLE;
  1232 #endif /* VSTART */
  1233 #ifdef VSTOP
  1234       tty.main.c_cc[VSTOP] = CDISABLE;
  1235 #endif /* VSTOP */
  1236     }
  1237 
  1238 #ifdef AIX
  1239   tty.main.c_cc[VSTRT] = CDISABLE;
  1240   tty.main.c_cc[VSTOP] = CDISABLE;
  1241   tty.main.c_cc[VSUSP] = CDISABLE;
  1242   tty.main.c_cc[VDSUSP] = CDISABLE;
  1243   if (tty_out->flow_control)
  1244     {
  1245 #ifdef VSTART
  1246       tty.main.c_cc[VSTART] = '\021';
  1247 #endif /* VSTART */
  1248 #ifdef VSTOP
  1249       tty.main.c_cc[VSTOP] = '\023';
  1250 #endif /* VSTOP */
  1251     }
  1252   /* Also, PTY overloads NUL and BREAK.
  1253      don't ignore break, but don't signal either, so it looks like NUL.
  1254      This really serves a purpose only if running in an XTERM window
  1255      or via TELNET or the like, but does no harm elsewhere.  */
  1256   tty.main.c_iflag &= ~IGNBRK;
  1257   tty.main.c_iflag &= ~BRKINT;
  1258 #endif
  1259 #endif /* not DOS_NT */
  1260 
  1261 #ifdef MSDOS    /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
  1262   if (!tty_out->term_initted)
  1263     internal_terminal_init ();
  1264   dos_ttraw (tty_out);
  1265 #endif
  1266 
  1267   emacs_set_tty (fileno (tty_out->input), &tty, 0);
  1268 
  1269   /* This code added to insure that, if flow-control is not to be used,
  1270      we have an unlocked terminal at the start. */
  1271 
  1272 #ifndef HAIKU /* On Haiku, TCXONC is a no-op and causes spurious
  1273                  compiler warnings. */
  1274 #ifdef TCXONC
  1275   if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TCXONC, 1);
  1276 #endif
  1277 #endif /* HAIKU */
  1278 #ifdef TIOCSTART
  1279   if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TIOCSTART, 0);
  1280 #endif
  1281 
  1282 #if !defined (DOS_NT)
  1283 #ifdef TCOON
  1284   if (!tty_out->flow_control) tcflow (fileno (tty_out->input), TCOON);
  1285 #endif
  1286 #endif
  1287 
  1288 #ifdef F_GETOWN
  1289   if (interrupt_input)
  1290     {
  1291       old_fcntl_owner[fileno (tty_out->input)] =
  1292         fcntl (fileno (tty_out->input), F_GETOWN, 0);
  1293       fcntl (fileno (tty_out->input), F_SETOWN, getpid ());
  1294       init_sigio (fileno (tty_out->input));
  1295 #ifdef HAVE_GPM
  1296       if (gpm_tty == tty_out)
  1297         {
  1298           /* Arrange for mouse events to give us SIGIO signals.  */
  1299           fcntl (gpm_fd, F_SETOWN, getpid ());
  1300           fcntl (gpm_fd, F_SETFL, fcntl (gpm_fd, F_GETFL, 0) | O_NONBLOCK);
  1301           init_sigio (gpm_fd);
  1302         }
  1303 #endif /* HAVE_GPM */
  1304     }
  1305 #endif /* F_GETOWN */
  1306 
  1307   const size_t buffer_size = (tty_out->output_buffer_size
  1308                               ? tty_out->output_buffer_size
  1309                               : BUFSIZ);
  1310   setvbuf (tty_out->output, NULL, _IOFBF, buffer_size);
  1311 
  1312   if (tty_out->terminal->set_terminal_modes_hook)
  1313     tty_out->terminal->set_terminal_modes_hook (tty_out->terminal);
  1314 
  1315   if (!tty_out->term_initted)
  1316     {
  1317       Lisp_Object tail, frame;
  1318       FOR_EACH_FRAME (tail, frame)
  1319         {
  1320           /* XXX This needs to be revised. */
  1321           if (FRAME_TERMCAP_P (XFRAME (frame))
  1322               && FRAME_TTY (XFRAME (frame)) == tty_out)
  1323             init_frame_faces (XFRAME (frame));
  1324         }
  1325     }
  1326 
  1327   if (tty_out->term_initted && no_redraw_on_reenter)
  1328     {
  1329       /* We used to call "direct_output_forward_char(0)" here,
  1330          but it's not clear why, since it may not do anything anyway.  */
  1331     }
  1332   else
  1333     {
  1334       Lisp_Object tail, frame;
  1335       frame_garbaged = 1;
  1336       FOR_EACH_FRAME (tail, frame)
  1337         {
  1338           if ((FRAME_TERMCAP_P (XFRAME (frame))
  1339                || FRAME_MSDOS_P (XFRAME (frame)))
  1340               && FRAME_TTY (XFRAME (frame)) == tty_out)
  1341             FRAME_GARBAGED_P (XFRAME (frame)) = 1;
  1342         }
  1343     }
  1344 
  1345   tty_out->term_initted = 1;
  1346 }
  1347 
  1348 /* Return true if safe to use tabs in output.
  1349    At the time this is called, init_sys_modes has not been done yet.  */
  1350 
  1351 bool
  1352 tabs_safe_p (int fd)
  1353 {
  1354   struct emacs_tty etty;
  1355 
  1356   emacs_get_tty (fd, &etty);
  1357 #ifndef DOS_NT
  1358 #ifdef TABDLY
  1359   return ((etty.main.c_oflag & TABDLY) != TAB3);
  1360 #else /* not TABDLY */
  1361   return 1;
  1362 #endif /* not TABDLY */
  1363 #else /* DOS_NT */
  1364   return 0;
  1365 #endif /* DOS_NT */
  1366 }
  1367 
  1368 /* Discard echoing.  */
  1369 
  1370 void
  1371 suppress_echo_on_tty (int fd)
  1372 {
  1373   struct emacs_tty etty;
  1374 
  1375   emacs_get_tty (fd, &etty);
  1376 #ifdef DOS_NT
  1377   /* Set raw input mode.  */
  1378   etty.main = 0;
  1379 #else
  1380   etty.main.c_lflag &= ~ICANON; /* Disable buffering */
  1381   etty.main.c_lflag &= ~ECHO;   /* Disable echoing */
  1382 #endif /* ! WINDOWSNT */
  1383   emacs_set_tty (fd, &etty, 0);
  1384 }
  1385 
  1386 /* Get terminal size from system.
  1387    Store number of lines into *HEIGHTP and width into *WIDTHP.
  1388    We store 0 if there's no valid information.  */
  1389 
  1390 void
  1391 get_tty_size (int fd, int *widthp, int *heightp)
  1392 {
  1393 #if defined TIOCGWINSZ
  1394 
  1395   /* BSD-style.  */
  1396   struct winsize size;
  1397 
  1398   if (ioctl (fd, TIOCGWINSZ, &size) == -1)
  1399     *widthp = *heightp = 0;
  1400   else
  1401     {
  1402       *widthp = size.ws_col;
  1403       *heightp = size.ws_row;
  1404     }
  1405 
  1406 #elif defined TIOCGSIZE
  1407 
  1408   /* SunOS - style.  */
  1409   struct ttysize size;
  1410 
  1411   if (ioctl (fd, TIOCGSIZE, &size) == -1)
  1412     *widthp = *heightp = 0;
  1413   else
  1414     {
  1415       *widthp = size.ts_cols;
  1416       *heightp = size.ts_lines;
  1417     }
  1418 
  1419 #elif defined WINDOWSNT
  1420 
  1421   CONSOLE_SCREEN_BUFFER_INFO info;
  1422   if (GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &info))
  1423     {
  1424       *widthp = info.srWindow.Right - info.srWindow.Left + 1;
  1425       *heightp = info.srWindow.Bottom - info.srWindow.Top + 1;
  1426     }
  1427   else
  1428     *widthp = *heightp = 0;
  1429 
  1430 #elif defined MSDOS
  1431 
  1432   *widthp = ScreenCols ();
  1433   *heightp = ScreenRows ();
  1434 
  1435 #else /* system doesn't know size */
  1436 
  1437   *widthp = 0;
  1438   *heightp = 0;
  1439 
  1440 #endif
  1441 }
  1442 
  1443 /* Set the logical window size associated with descriptor FD
  1444    to HEIGHT and WIDTH.  This is used mainly with ptys.
  1445    Return a negative value on failure.  */
  1446 
  1447 int
  1448 set_window_size (int fd, int height, int width)
  1449 {
  1450 #ifdef TIOCSWINSZ
  1451 
  1452   /* BSD-style.  */
  1453   struct winsize size;
  1454   memset (&size, 0, sizeof (size));
  1455   size.ws_row = height;
  1456   size.ws_col = width;
  1457 
  1458   return ioctl (fd, TIOCSWINSZ, &size);
  1459 
  1460 #else
  1461 #ifdef TIOCSSIZE
  1462 
  1463   /* SunOS - style.  */
  1464   struct ttysize size;
  1465   memset (&size, 0, sizeof (size));
  1466   size.ts_lines = height;
  1467   size.ts_cols = width;
  1468 
  1469   return ioctl (fd, TIOCGSIZE, &size);
  1470 #else
  1471   return -1;
  1472 #endif /* not SunOS-style */
  1473 #endif /* not BSD-style */
  1474 }
  1475 
  1476 
  1477 
  1478 /* Prepare all terminal devices for exiting Emacs. */
  1479 
  1480 void
  1481 reset_all_sys_modes (void)
  1482 {
  1483   struct tty_display_info *tty;
  1484   for (tty = tty_list; tty; tty = tty->next)
  1485     reset_sys_modes (tty);
  1486 }
  1487 
  1488 /* Prepare the terminal for closing it; move the cursor to the
  1489    bottom of the frame, turn off interrupt-driven I/O, etc.  */
  1490 
  1491 void
  1492 reset_sys_modes (struct tty_display_info *tty_out)
  1493 {
  1494   if (noninteractive)
  1495     {
  1496       fflush (stdout);
  1497       return;
  1498     }
  1499   if (!tty_out->term_initted)
  1500     return;
  1501 
  1502   if (!tty_out->output)
  1503     return;                     /* The tty is suspended. */
  1504 
  1505   /* Go to and clear the last line of the terminal. */
  1506 
  1507   cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
  1508 
  1509   /* Code adapted from tty_clear_end_of_line. */
  1510   if (tty_out->TS_clr_line)
  1511     {
  1512       emacs_tputs (tty_out, tty_out->TS_clr_line, 1, cmputc);
  1513     }
  1514   else
  1515     {                   /* have to do it the hard way */
  1516       tty_turn_off_insert (tty_out);
  1517 
  1518       for (int i = cursorX (tty_out); i < FrameCols (tty_out) - 1; i++)
  1519         putc (' ', tty_out->output);
  1520     }
  1521 
  1522   cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
  1523   fflush (tty_out->output);
  1524 
  1525   if (tty_out->terminal->reset_terminal_modes_hook)
  1526     tty_out->terminal->reset_terminal_modes_hook (tty_out->terminal);
  1527 
  1528   /* Avoid possible loss of output when changing terminal modes.  */
  1529   while (tcdrain (fileno (tty_out->output)) != 0 && errno == EINTR)
  1530     continue;
  1531 
  1532 #ifndef DOS_NT
  1533 # ifdef F_SETOWN
  1534   if (interrupt_input)
  1535     {
  1536       reset_sigio (fileno (tty_out->input));
  1537       fcntl (fileno (tty_out->input), F_SETOWN,
  1538              old_fcntl_owner[fileno (tty_out->input)]);
  1539     }
  1540 # endif /* F_SETOWN */
  1541   fcntl (fileno (tty_out->input), F_SETFL,
  1542          fcntl (fileno (tty_out->input), F_GETFL, 0) & ~O_NONBLOCK);
  1543 #endif
  1544 
  1545   if (tty_out->old_tty)
  1546     while (emacs_set_tty (fileno (tty_out->input),
  1547                           tty_out->old_tty, 0) < 0 && errno == EINTR)
  1548       ;
  1549 
  1550 #ifdef MSDOS    /* Demacs 1.1.2 91/10/20 Manabu Higashida */
  1551   dos_ttcooked ();
  1552 #endif
  1553 
  1554   widen_foreground_group (fileno (tty_out->input));
  1555 }
  1556 
  1557 #ifdef HAVE_PTYS
  1558 
  1559 /* Set up the proper status flags for use of a pty.  */
  1560 
  1561 void
  1562 setup_pty (int fd)
  1563 {
  1564   /* I'm told that TOICREMOTE does not mean control chars
  1565      "can't be sent" but rather that they don't have
  1566      input-editing or signaling effects.
  1567      That should be good, because we have other ways
  1568      to do those things in Emacs.
  1569      However, telnet mode seems not to work on 4.2.
  1570      So TIOCREMOTE is turned off now. */
  1571 
  1572   /* Under hp-ux, if TIOCREMOTE is turned on, some calls
  1573      will hang.  In particular, the "timeout" feature (which
  1574      causes a read to return if there is no data available)
  1575      does this.  Also it is known that telnet mode will hang
  1576      in such a way that Emacs must be stopped (perhaps this
  1577      is the same problem).
  1578 
  1579      If TIOCREMOTE is turned off, then there is a bug in
  1580      hp-ux which sometimes loses data.  Apparently the
  1581      code which blocks the master process when the internal
  1582      buffer fills up does not work.  Other than this,
  1583      though, everything else seems to work fine.
  1584 
  1585      Since the latter lossage is more benign, we may as well
  1586      lose that way.  -- cph */
  1587 #ifdef FIONBIO
  1588 #if defined (UNIX98_PTYS)
  1589   {
  1590     int on = 1;
  1591     ioctl (fd, FIONBIO, &on);
  1592   }
  1593 #endif
  1594 #endif
  1595 }
  1596 #endif /* HAVE_PTYS */
  1597 
  1598 void
  1599 init_system_name (void)
  1600 {
  1601   if (!build_details)
  1602     {
  1603       /* Set system-name to nil so that the build is deterministic.  */
  1604       Vsystem_name = Qnil;
  1605       return;
  1606     }
  1607   char *hostname_alloc = NULL;
  1608   char *hostname;
  1609 #ifndef HAVE_GETHOSTNAME
  1610   struct utsname uts;
  1611   uname (&uts);
  1612   hostname = uts.nodename;
  1613 #else /* HAVE_GETHOSTNAME */
  1614   char hostname_buf[256];
  1615   ptrdiff_t hostname_size = sizeof hostname_buf;
  1616   hostname = hostname_buf;
  1617 
  1618   /* Try to get the host name; if the buffer is too short, try
  1619      again.  Apparently, the only indication gethostname gives of
  1620      whether the buffer was large enough is the presence or absence
  1621      of a '\0' in the string.  Eech.  */
  1622   for (;;)
  1623     {
  1624       gethostname (hostname, hostname_size - 1);
  1625       hostname[hostname_size - 1] = '\0';
  1626 
  1627       /* Was the buffer large enough for the '\0'?  */
  1628       if (strlen (hostname) < hostname_size - 1)
  1629         break;
  1630 
  1631       hostname = hostname_alloc = xpalloc (hostname_alloc, &hostname_size, 1,
  1632                                            min (PTRDIFF_MAX, SIZE_MAX), 1);
  1633     }
  1634 #endif /* HAVE_GETHOSTNAME */
  1635   char *p;
  1636   for (p = hostname; *p; p++)
  1637     if (*p == ' ' || *p == '\t')
  1638       *p = '-';
  1639   if (! (STRINGP (Vsystem_name) && SBYTES (Vsystem_name) == p - hostname
  1640          && strcmp (SSDATA (Vsystem_name), hostname) == 0))
  1641     Vsystem_name = build_string (hostname);
  1642   xfree (hostname_alloc);
  1643 }
  1644 
  1645 sigset_t empty_mask;
  1646 
  1647 static struct sigaction process_fatal_action;
  1648 
  1649 static int
  1650 emacs_sigaction_flags (void)
  1651 {
  1652 #ifdef SA_RESTART
  1653   /* SA_RESTART causes interruptible functions with timeouts (e.g.,
  1654      'select') to reset their timeout on some platforms (e.g.,
  1655      HP-UX 11), which is not what we want.  Also, when Emacs is
  1656      interactive, we don't want SA_RESTART because we need to poll
  1657      for pending input so we need long-running syscalls to be interrupted
  1658      after a signal that sets pending_signals.
  1659 
  1660      Non-interactive keyboard input goes through stdio, where we
  1661      always want restartable system calls.  */
  1662   if (noninteractive)
  1663     return SA_RESTART;
  1664 #endif
  1665   return 0;
  1666 }
  1667 
  1668 /* Store into *ACTION a signal action suitable for Emacs, with handler
  1669    HANDLER.  */
  1670 void
  1671 emacs_sigaction_init (struct sigaction *action, signal_handler_t handler)
  1672 {
  1673   sigemptyset (&action->sa_mask);
  1674 
  1675   /* When handling a signal, block nonfatal system signals that are caught
  1676      by Emacs.  This makes race conditions less likely.  */
  1677   sigaddset (&action->sa_mask, SIGALRM);
  1678 #ifdef SIGCHLD
  1679   sigaddset (&action->sa_mask, SIGCHLD);
  1680 #endif
  1681 #ifdef SIGDANGER
  1682   sigaddset (&action->sa_mask, SIGDANGER);
  1683 #endif
  1684 #ifdef PROFILER_CPU_SUPPORT
  1685   sigaddset (&action->sa_mask, SIGPROF);
  1686 #endif
  1687 #ifdef SIGWINCH
  1688   sigaddset (&action->sa_mask, SIGWINCH);
  1689 #endif
  1690   if (! noninteractive)
  1691     {
  1692       sigaddset (&action->sa_mask, SIGINT);
  1693       sigaddset (&action->sa_mask, SIGQUIT);
  1694 #ifdef USABLE_SIGIO
  1695       sigaddset (&action->sa_mask, SIGIO);
  1696 #elif defined (USABLE_SIGPOLL)
  1697       sigaddset (&action->sa_mask, SIGPOLL);
  1698 #endif
  1699     }
  1700 
  1701   action->sa_handler = handler;
  1702   action->sa_flags = emacs_sigaction_flags ();
  1703 }
  1704 
  1705 #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
  1706 static pthread_t main_thread_id;
  1707 #endif
  1708 
  1709 /* SIG has arrived at the current process.  Deliver it to the main
  1710    thread, which should handle it with HANDLER.  (Delivering the
  1711    signal to some other thread might not work if the other thread is
  1712    about to exit.)
  1713 
  1714    If we are on the main thread, handle the signal SIG with HANDLER.
  1715    Otherwise, redirect the signal to the main thread, blocking it from
  1716    this thread.  POSIX says any thread can receive a signal that is
  1717    associated with a process, process group, or asynchronous event.
  1718    On GNU/Linux the main thread typically gets a process signal unless
  1719    it's blocked, but other systems (FreeBSD at least) can deliver the
  1720    signal to other threads.  */
  1721 void
  1722 deliver_process_signal (int sig, signal_handler_t handler)
  1723 {
  1724   /* Preserve errno, to avoid race conditions with signal handlers that
  1725      might change errno.  Races can occur even in single-threaded hosts.  */
  1726   int old_errno = errno;
  1727 
  1728   bool on_main_thread = true;
  1729 #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
  1730   if (! pthread_equal (pthread_self (), main_thread_id))
  1731     {
  1732       sigset_t blocked;
  1733       sigemptyset (&blocked);
  1734       sigaddset (&blocked, sig);
  1735       pthread_sigmask (SIG_BLOCK, &blocked, 0);
  1736       pthread_kill (main_thread_id, sig);
  1737       on_main_thread = false;
  1738     }
  1739 #endif
  1740   if (on_main_thread)
  1741     handler (sig);
  1742 
  1743   errno = old_errno;
  1744 }
  1745 
  1746 /* Static location to save a fatal backtrace in a thread.
  1747    FIXME: If two subsidiary threads fail simultaneously, the resulting
  1748    backtrace may be garbage.  */
  1749 enum { BACKTRACE_LIMIT_MAX = 500 };
  1750 static void *thread_backtrace_buffer[BACKTRACE_LIMIT_MAX + 1];
  1751 static int thread_backtrace_npointers;
  1752 
  1753 /* SIG has arrived at the current thread.
  1754    If we are on the main thread, handle the signal SIG with HANDLER.
  1755    Otherwise, this is a fatal error in the handling thread.  */
  1756 static void
  1757 deliver_thread_signal (int sig, signal_handler_t handler)
  1758 {
  1759   int old_errno = errno;
  1760 
  1761 #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
  1762   if (! pthread_equal (pthread_self (), main_thread_id))
  1763     {
  1764       thread_backtrace_npointers
  1765         = backtrace (thread_backtrace_buffer, BACKTRACE_LIMIT_MAX);
  1766       sigaction (sig, &process_fatal_action, 0);
  1767       pthread_kill (main_thread_id, sig);
  1768 
  1769       /* Avoid further damage while the main thread is exiting.  */
  1770       while (1)
  1771         sigsuspend (&empty_mask);
  1772     }
  1773 #endif
  1774 
  1775   handler (sig);
  1776   errno = old_errno;
  1777 }
  1778 
  1779 /* Handle bus errors, invalid instruction, etc.  */
  1780 static void
  1781 handle_fatal_signal (int sig)
  1782 {
  1783   terminate_due_to_signal (sig, 40);
  1784 }
  1785 
  1786 static void
  1787 deliver_fatal_signal (int sig)
  1788 {
  1789   deliver_process_signal (sig, handle_fatal_signal);
  1790 }
  1791 
  1792 static void
  1793 deliver_fatal_thread_signal (int sig)
  1794 {
  1795   deliver_thread_signal (sig, handle_fatal_signal);
  1796 }
  1797 
  1798 static AVOID
  1799 handle_arith_signal (int sig)
  1800 {
  1801   pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
  1802   xsignal0 (Qarith_error);
  1803 }
  1804 
  1805 #if defined HAVE_STACK_OVERFLOW_HANDLING && !defined WINDOWSNT
  1806 
  1807 /* Alternate stack used by SIGSEGV handler below.  */
  1808 
  1809 /* Storage for the alternate signal stack.
  1810    64 KiB is not too large for Emacs, and is large enough
  1811    for all known platforms.  Smaller sizes may run into trouble.
  1812    For example, libsigsegv 2.6 through 2.8 have a bug where some
  1813    architectures use more than the Linux default of an 8 KiB alternate
  1814    stack when deciding if a fault was caused by stack overflow.  */
  1815 static max_align_t sigsegv_stack[(64 * 1024
  1816                                   + sizeof (max_align_t) - 1)
  1817                                  / sizeof (max_align_t)];
  1818 
  1819 
  1820 /* Return true if SIGINFO indicates a stack overflow.  */
  1821 
  1822 static bool
  1823 stack_overflow (siginfo_t *siginfo)
  1824 {
  1825   if (!attempt_stack_overflow_recovery)
  1826     return false;
  1827 
  1828   /* In theory, a more-accurate heuristic can be obtained by using
  1829      GNU/Linux pthread_getattr_np along with POSIX pthread_attr_getstack
  1830      and pthread_attr_getguardsize to find the location and size of the
  1831      guard area.  In practice, though, these functions are so hard to
  1832      use reliably that they're not worth bothering with.  E.g., see:
  1833      https://sourceware.org/bugzilla/show_bug.cgi?id=16291
  1834      Other operating systems also have problems, e.g., Solaris's
  1835      stack_violation function is tailor-made for this problem, but it
  1836      doesn't work on Solaris 11.2 x86-64 with a 32-bit executable.
  1837 
  1838      GNU libsigsegv is overkill for Emacs; otherwise it might be a
  1839      candidate here.  */
  1840 
  1841   if (!siginfo)
  1842     return false;
  1843 
  1844   /* The faulting address.  */
  1845   char *addr = siginfo->si_addr;
  1846   if (!addr)
  1847     return false;
  1848 
  1849   /* The known top and bottom of the stack.  The actual stack may
  1850      extend a bit beyond these boundaries.  */
  1851   char const *bot = stack_bottom;
  1852   char const *top = current_thread->stack_top;
  1853 
  1854   /* Log base 2 of the stack heuristic ratio.  This ratio is the size
  1855      of the known stack divided by the size of the guard area past the
  1856      end of the stack top.  The heuristic is that a bad address is
  1857      considered to be a stack overflow if it occurs within
  1858      stacksize>>LG_STACK_HEURISTIC bytes above the top of the known
  1859      stack.  This heuristic is not exactly correct but it's good
  1860      enough in practice.  */
  1861   enum { LG_STACK_HEURISTIC = 8 };
  1862 
  1863   if (bot < top)
  1864     return 0 <= addr - top && addr - top < (top - bot) >> LG_STACK_HEURISTIC;
  1865   else
  1866     return 0 <= top - addr && top - addr < (bot - top) >> LG_STACK_HEURISTIC;
  1867 }
  1868 
  1869 
  1870 /* Attempt to recover from SIGSEGV caused by C stack overflow.  */
  1871 
  1872 static void
  1873 handle_sigsegv (int sig, siginfo_t *siginfo, void *arg)
  1874 {
  1875   /* Hard GC error may lead to stack overflow caused by
  1876      too nested calls to mark_object.  No way to survive.  */
  1877   bool fatal = gc_in_progress;
  1878 
  1879 #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
  1880   if (!fatal && !pthread_equal (pthread_self (), main_thread_id))
  1881     fatal = true;
  1882 #endif
  1883 
  1884   if (!fatal && stack_overflow (siginfo))
  1885     siglongjmp (return_to_command_loop, 1);
  1886 
  1887   /* Otherwise we can't do anything with this.  */
  1888   deliver_fatal_thread_signal (sig);
  1889 }
  1890 
  1891 /* Return true if we have successfully set up SIGSEGV handler on alternate
  1892    stack.  Otherwise we just treat SIGSEGV among the rest of fatal signals.  */
  1893 
  1894 static bool
  1895 init_sigsegv (void)
  1896 {
  1897   struct sigaction sa;
  1898   stack_t ss;
  1899 
  1900   ss.ss_sp = sigsegv_stack;
  1901   ss.ss_size = sizeof (sigsegv_stack);
  1902   ss.ss_flags = 0;
  1903   if (sigaltstack (&ss, NULL) < 0)
  1904     return 0;
  1905 
  1906   sigfillset (&sa.sa_mask);
  1907   sa.sa_sigaction = handle_sigsegv;
  1908   sa.sa_flags = SA_SIGINFO | SA_ONSTACK | emacs_sigaction_flags ();
  1909   if (sigaction (SIGSEGV, &sa, NULL) < 0)
  1910     return 0;
  1911 
  1912   return 1;
  1913 }
  1914 
  1915 #else /* not HAVE_STACK_OVERFLOW_HANDLING or WINDOWSNT */
  1916 
  1917 static bool
  1918 init_sigsegv (void)
  1919 {
  1920   return 0;
  1921 }
  1922 
  1923 #endif /* HAVE_STACK_OVERFLOW_HANDLING && !WINDOWSNT */
  1924 
  1925 static void
  1926 deliver_arith_signal (int sig)
  1927 {
  1928   deliver_thread_signal (sig, handle_arith_signal);
  1929 }
  1930 
  1931 #ifdef SIGDANGER
  1932 
  1933 /* Handler for SIGDANGER.  */
  1934 static void
  1935 handle_danger_signal (int sig)
  1936 {
  1937   malloc_warning ("Operating system warns that virtual memory is running low.\n");
  1938 
  1939   /* It might be unsafe to call do_auto_save now.  */
  1940   force_auto_save_soon ();
  1941 }
  1942 
  1943 static void
  1944 deliver_danger_signal (int sig)
  1945 {
  1946   deliver_process_signal (sig, handle_danger_signal);
  1947 }
  1948 #endif
  1949 
  1950 /* Treat SIG as a terminating signal, unless it is already ignored and
  1951    we are in --batch mode.  Among other things, this makes nohup work.  */
  1952 static void
  1953 maybe_fatal_sig (int sig)
  1954 {
  1955   bool catch_sig = !noninteractive;
  1956   if (!catch_sig)
  1957     {
  1958       struct sigaction old_action;
  1959       sigaction (sig, 0, &old_action);
  1960       catch_sig = old_action.sa_handler != SIG_IGN;
  1961     }
  1962   if (catch_sig)
  1963     sigaction (sig, &process_fatal_action, 0);
  1964 }
  1965 
  1966 void
  1967 init_signals (void)
  1968 {
  1969   struct sigaction thread_fatal_action;
  1970   struct sigaction action;
  1971 
  1972   sigemptyset (&empty_mask);
  1973 
  1974 #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
  1975   main_thread_id = pthread_self ();
  1976 #endif
  1977 
  1978   /* Don't alter signal handlers if dumping.  On some machines,
  1979      changing signal handlers sets static data that would make signals
  1980      fail to work right when the dumped Emacs is run.  */
  1981   if (will_dump_p ())
  1982     return;
  1983 
  1984   sigfillset (&process_fatal_action.sa_mask);
  1985   process_fatal_action.sa_handler = deliver_fatal_signal;
  1986   process_fatal_action.sa_flags = emacs_sigaction_flags ();
  1987 
  1988   sigfillset (&thread_fatal_action.sa_mask);
  1989   thread_fatal_action.sa_handler = deliver_fatal_thread_signal;
  1990   thread_fatal_action.sa_flags = process_fatal_action.sa_flags;
  1991 
  1992   /* SIGINT may need special treatment on MS-Windows.  See
  1993      https://lists.gnu.org/r/emacs-devel/2010-09/msg01062.html
  1994      Please update the doc of kill-emacs, kill-emacs-hook, and
  1995      NEWS if you change this.  */
  1996 
  1997   maybe_fatal_sig (SIGHUP);
  1998   maybe_fatal_sig (SIGINT);
  1999   maybe_fatal_sig (SIGTERM);
  2000 
  2001   /* Emacs checks for write errors, so it can safely ignore SIGPIPE.
  2002      However, in batch mode leave SIGPIPE alone, as that causes Emacs
  2003      to behave more like typical batch applications do.  */
  2004   if (! noninteractive)
  2005     signal (SIGPIPE, SIG_IGN);
  2006 
  2007   sigaction (SIGQUIT, &process_fatal_action, 0);
  2008 #ifndef __vax__
  2009   sigaction (SIGILL, &thread_fatal_action, 0);
  2010 #endif /* __vax__ */
  2011   sigaction (SIGTRAP, &thread_fatal_action, 0);
  2012 
  2013   /* Typically SIGFPE is thread-specific and is fatal, like SIGILL.
  2014      But on a non-IEEE host SIGFPE can come from a trap in the Lisp
  2015      interpreter's floating point operations, so treat SIGFPE as an
  2016      arith-error if it arises in the main thread.  */
  2017   if (IEEE_FLOATING_POINT)
  2018     sigaction (SIGFPE, &thread_fatal_action, 0);
  2019   else
  2020     {
  2021       emacs_sigaction_init (&action, deliver_arith_signal);
  2022       sigaction (SIGFPE, &action, 0);
  2023 #ifdef __vax__
  2024       /* NetBSD/vax generates SIGILL upon some floating point errors,
  2025          such as taking the log of 0.0.  */
  2026       sigaction (SIGILL, &action, 0);
  2027 #endif /* __vax__ */
  2028     }
  2029 
  2030 #ifdef SIGUSR1
  2031   add_user_signal (SIGUSR1, "sigusr1");
  2032 #endif
  2033 #ifdef SIGUSR2
  2034   add_user_signal (SIGUSR2, "sigusr2");
  2035 #endif
  2036   sigaction (SIGABRT, &thread_fatal_action, 0);
  2037 #ifdef SIGPRE
  2038   sigaction (SIGPRE, &thread_fatal_action, 0);
  2039 #endif
  2040 #ifdef SIGORE
  2041   sigaction (SIGORE, &thread_fatal_action, 0);
  2042 #endif
  2043 #ifdef SIGUME
  2044   sigaction (SIGUME, &thread_fatal_action, 0);
  2045 #endif
  2046 #ifdef SIGDLK
  2047   sigaction (SIGDLK, &process_fatal_action, 0);
  2048 #endif
  2049 #ifdef SIGCPULIM
  2050   sigaction (SIGCPULIM, &process_fatal_action, 0);
  2051 #endif
  2052 #ifdef SIGIOT
  2053   sigaction (SIGIOT, &thread_fatal_action, 0);
  2054 #endif
  2055 #ifdef SIGEMT
  2056   sigaction (SIGEMT, &thread_fatal_action, 0);
  2057 #endif
  2058 #ifdef SIGBUS
  2059   sigaction (SIGBUS, &thread_fatal_action, 0);
  2060 #endif
  2061   if (!init_sigsegv ())
  2062     sigaction (SIGSEGV, &thread_fatal_action, 0);
  2063 #ifdef SIGSYS
  2064   sigaction (SIGSYS, &thread_fatal_action, 0);
  2065 #endif
  2066   sigaction (SIGTERM, &process_fatal_action, 0);
  2067 #ifdef SIGPROF
  2068   signal (SIGPROF, SIG_IGN);
  2069 #endif
  2070 #ifdef SIGVTALRM
  2071   sigaction (SIGVTALRM, &process_fatal_action, 0);
  2072 #endif
  2073 #ifdef SIGXCPU
  2074   sigaction (SIGXCPU, &process_fatal_action, 0);
  2075 #endif
  2076 #ifdef SIGXFSZ
  2077   sigaction (SIGXFSZ, &process_fatal_action, 0);
  2078 #endif
  2079 
  2080 #ifdef SIGDANGER
  2081   /* This just means available memory is getting low.  */
  2082   emacs_sigaction_init (&action, deliver_danger_signal);
  2083   sigaction (SIGDANGER, &action, 0);
  2084 #endif
  2085 
  2086   /* AIX-specific signals.  */
  2087 #ifdef SIGGRANT
  2088   sigaction (SIGGRANT, &process_fatal_action, 0);
  2089 #endif
  2090 #ifdef SIGMIGRATE
  2091   sigaction (SIGMIGRATE, &process_fatal_action, 0);
  2092 #endif
  2093 #ifdef SIGMSG
  2094   sigaction (SIGMSG, &process_fatal_action, 0);
  2095 #endif
  2096 #ifdef SIGRETRACT
  2097   sigaction (SIGRETRACT, &process_fatal_action, 0);
  2098 #endif
  2099 #ifdef SIGSAK
  2100   sigaction (SIGSAK, &process_fatal_action, 0);
  2101 #endif
  2102 #ifdef SIGSOUND
  2103   sigaction (SIGSOUND, &process_fatal_action, 0);
  2104 #endif
  2105 #ifdef SIGTALRM
  2106   sigaction (SIGTALRM, &thread_fatal_action, 0);
  2107 #endif
  2108 }
  2109 
  2110 #ifndef HAVE_RANDOM
  2111 #ifdef random
  2112 #define HAVE_RANDOM
  2113 #endif
  2114 #endif
  2115 
  2116 /* Figure out how many bits the system's random number generator uses.
  2117    `random' and `lrand48' are assumed to return 31 usable bits.
  2118    BSD `rand' returns a 31 bit value but the low order bits are unusable;
  2119    so we'll shift it and treat it like the 15-bit USG `rand'.  */
  2120 
  2121 #ifndef RAND_BITS
  2122 # ifdef HAVE_RANDOM
  2123 #  define RAND_BITS 31
  2124 # else /* !HAVE_RANDOM */
  2125 #  ifdef HAVE_LRAND48
  2126 #   define RAND_BITS 31
  2127 #   define random lrand48
  2128 #  else /* !HAVE_LRAND48 */
  2129 #   define RAND_BITS 15
  2130 #   if RAND_MAX == 32767
  2131 #    define random rand
  2132 #   else /* RAND_MAX != 32767 */
  2133 #    if RAND_MAX == 2147483647
  2134 #     define random() (rand () >> 16)
  2135 #    else /* RAND_MAX != 2147483647 */
  2136 #     ifdef USG
  2137 #      define random rand
  2138 #     else
  2139 #      define random() (rand () >> 16)
  2140 #     endif /* !USG */
  2141 #    endif /* RAND_MAX != 2147483647 */
  2142 #   endif /* RAND_MAX != 32767 */
  2143 #  endif /* !HAVE_LRAND48 */
  2144 # endif /* !HAVE_RANDOM */
  2145 #endif /* !RAND_BITS */
  2146 
  2147 #ifdef HAVE_RANDOM
  2148 typedef unsigned int random_seed;
  2149 static void set_random_seed (random_seed arg) { srandom (arg); }
  2150 #elif defined HAVE_LRAND48
  2151 typedef long int random_seed;
  2152 static void set_random_seed (random_seed arg) { srand48 (arg); }
  2153 #else
  2154 typedef unsigned int random_seed;
  2155 static void set_random_seed (random_seed arg) { srand (arg); }
  2156 #endif
  2157 
  2158 void
  2159 seed_random (void *seed, ptrdiff_t seed_size)
  2160 {
  2161   random_seed arg = 0;
  2162   unsigned char *argp = (unsigned char *) &arg;
  2163   unsigned char *seedp = seed;
  2164   for (ptrdiff_t i = 0; i < seed_size; i++)
  2165     argp[i % sizeof arg] ^= seedp[i];
  2166   set_random_seed (arg);
  2167 }
  2168 
  2169 void
  2170 init_random (void)
  2171 {
  2172   random_seed v;
  2173   bool success = false;
  2174 
  2175   /* First, try seeding the PRNG from the operating system's entropy
  2176      source.  This approach is both fast and secure.  */
  2177 #ifdef WINDOWSNT
  2178   /* FIXME: Perhaps getrandom can be used here too?  */
  2179   success = w32_init_random (&v, sizeof v) == 0;
  2180 #else
  2181   verify (sizeof v <= 256);
  2182   success = getrandom (&v, sizeof v, 0) == sizeof v;
  2183 #endif
  2184 
  2185   /* If that didn't work, just use the current time value and PID.
  2186      It's at least better than XKCD 221.  */
  2187   if (!success)
  2188     {
  2189       struct timespec t = current_timespec ();
  2190       v = getpid () ^ t.tv_sec ^ t.tv_nsec;
  2191     }
  2192 
  2193   set_random_seed (v);
  2194 }
  2195 
  2196 /*
  2197  * Return a nonnegative random integer out of whatever we've got.
  2198  * It contains enough bits to make a random (signed) Emacs fixnum.
  2199  * This suffices even for a 64-bit architecture with a 15-bit rand.
  2200  */
  2201 EMACS_INT
  2202 get_random (void)
  2203 {
  2204   EMACS_UINT val = 0;
  2205   int i;
  2206   for (i = 0; i < (FIXNUM_BITS + RAND_BITS - 1) / RAND_BITS; i++)
  2207     val = (random () ^ (val << RAND_BITS)
  2208            ^ (val >> (EMACS_INT_WIDTH - RAND_BITS)));
  2209   val ^= val >> (EMACS_INT_WIDTH - FIXNUM_BITS);
  2210   return val & INTMASK;
  2211 }
  2212 
  2213 /* Return a random unsigned long.  */
  2214 unsigned long int
  2215 get_random_ulong (void)
  2216 {
  2217   unsigned long int r = 0;
  2218   for (int i = 0; i < (ULONG_WIDTH + RAND_BITS - 1) / RAND_BITS; i++)
  2219     r = random () ^ (r << RAND_BITS) ^ (r >> (ULONG_WIDTH - RAND_BITS));
  2220   return r;
  2221 }
  2222 
  2223 #ifndef HAVE_SNPRINTF
  2224 /* Approximate snprintf as best we can on ancient hosts that lack it.  */
  2225 int
  2226 snprintf (char *buf, size_t bufsize, char const *format, ...)
  2227 {
  2228   ptrdiff_t size = min (bufsize, PTRDIFF_MAX);
  2229   ptrdiff_t nbytes = size - 1;
  2230   va_list ap;
  2231 
  2232   if (size)
  2233     {
  2234       va_start (ap, format);
  2235       nbytes = doprnt (buf, size, format, 0, ap);
  2236       va_end (ap);
  2237     }
  2238 
  2239   if (nbytes == size - 1)
  2240     {
  2241       /* Calculate the length of the string that would have been created
  2242          had the buffer been large enough.  */
  2243       char stackbuf[4000];
  2244       char *b = stackbuf;
  2245       ptrdiff_t bsize = sizeof stackbuf;
  2246       va_start (ap, format);
  2247       nbytes = evxprintf (&b, &bsize, stackbuf, -1, format, ap);
  2248       va_end (ap);
  2249       if (b != stackbuf)
  2250         xfree (b);
  2251     }
  2252 
  2253   if (INT_MAX < nbytes)
  2254     {
  2255 #ifdef EOVERFLOW
  2256       errno = EOVERFLOW;
  2257 #else
  2258       errno = EDOM;
  2259 #endif
  2260       return -1;
  2261     }
  2262   return nbytes;
  2263 }
  2264 #endif
  2265 
  2266 /* If a backtrace is available, output the top lines of it to stderr.
  2267    Do not output more than BACKTRACE_LIMIT or BACKTRACE_LIMIT_MAX lines.
  2268    This function may be called from a signal handler, so it should
  2269    not invoke async-unsafe functions like malloc.
  2270 
  2271    If BACKTRACE_LIMIT is -1, initialize tables that 'backtrace' uses
  2272    but do not output anything.  This avoids some problems that can
  2273    otherwise occur if the malloc arena is corrupted before 'backtrace'
  2274    is called, since 'backtrace' may call malloc if the tables are not
  2275    initialized.
  2276 
  2277    If the static variable THREAD_BACKTRACE_NPOINTERS is nonzero, a
  2278    fatal error has occurred in some other thread; generate a thread
  2279    backtrace instead, ignoring BACKTRACE_LIMIT.  */
  2280 void
  2281 emacs_backtrace (int backtrace_limit)
  2282 {
  2283   void *main_backtrace_buffer[BACKTRACE_LIMIT_MAX + 1];
  2284   int bounded_limit = min (backtrace_limit, BACKTRACE_LIMIT_MAX);
  2285   void *buffer;
  2286   int npointers;
  2287 
  2288   if (thread_backtrace_npointers)
  2289     {
  2290       buffer = thread_backtrace_buffer;
  2291       npointers = thread_backtrace_npointers;
  2292     }
  2293   else
  2294     {
  2295       buffer = main_backtrace_buffer;
  2296 
  2297       /* Work around 'backtrace' bug; see Bug#19959 and glibc bug#18084.  */
  2298       if (bounded_limit < 0)
  2299         {
  2300           backtrace (buffer, 1);
  2301           return;
  2302         }
  2303 
  2304       npointers = backtrace (buffer, bounded_limit + 1);
  2305     }
  2306 
  2307   if (npointers)
  2308     {
  2309       emacs_write (STDERR_FILENO, "Backtrace:\n", 11);
  2310       backtrace_symbols_fd (buffer, npointers, STDERR_FILENO);
  2311       if (bounded_limit < npointers)
  2312         emacs_write (STDERR_FILENO, "...\n", 4);
  2313     }
  2314 }
  2315 
  2316 #ifndef HAVE_NTGUI
  2317 void
  2318 emacs_abort (void)
  2319 {
  2320   terminate_due_to_signal (SIGABRT, 40);
  2321 }
  2322 #endif
  2323 
  2324 /* Assuming the directory DIRFD, store information about FILENAME into *ST,
  2325    using FLAGS to control how the status is obtained.
  2326    Do not fail merely because fetching info was interrupted by a signal.
  2327    Allow the user to quit.
  2328 
  2329    The type of ST is void * instead of struct stat * because the
  2330    latter type would be problematic in lisp.h.  Some platforms may
  2331    play tricks like "#define stat stat64" in <sys/stat.h>, and lisp.h
  2332    does not include <sys/stat.h>.  */
  2333 
  2334 int
  2335 emacs_fstatat (int dirfd, char const *filename, void *st, int flags)
  2336 {
  2337   int r;
  2338   while ((r = fstatat (dirfd, filename, st, flags)) != 0 && errno == EINTR)
  2339     maybe_quit ();
  2340   return r;
  2341 }
  2342 
  2343 static int
  2344 sys_openat (int dirfd, char const *file, int oflags, int mode)
  2345 {
  2346 #ifdef O_PATH
  2347   return openat (dirfd, file, oflags, mode);
  2348 #else
  2349   /* On platforms without O_PATH, emacs_openat's callers arrange for
  2350      DIRFD to be AT_FDCWD, so it should be safe to just call 'open'.
  2351      This ports to old platforms like OS X 10.9 that lack openat.  */
  2352   eassert (dirfd == AT_FDCWD);
  2353   return open (file, oflags, mode);
  2354 #endif
  2355 }
  2356 
  2357 /* Assuming the directory DIRFD, open FILE for Emacs use,
  2358    using open flags OFLAGS and mode MODE.
  2359    Use binary I/O on systems that care about text vs binary I/O.
  2360    Arrange for subprograms to not inherit the file descriptor.
  2361    Prefer a method that is multithread-safe, if available.
  2362    Do not fail merely because the open was interrupted by a signal.
  2363    Allow the user to quit.  */
  2364 
  2365 int
  2366 emacs_openat (int dirfd, char const *file, int oflags, int mode)
  2367 {
  2368   int fd;
  2369   if (! (oflags & O_TEXT))
  2370     oflags |= O_BINARY;
  2371   oflags |= O_CLOEXEC;
  2372   while ((fd = sys_openat (dirfd, file, oflags, mode)) < 0 && errno == EINTR)
  2373     maybe_quit ();
  2374   return fd;
  2375 }
  2376 
  2377 int
  2378 emacs_open (char const *file, int oflags, int mode)
  2379 {
  2380   return emacs_openat (AT_FDCWD, file, oflags, mode);
  2381 }
  2382 
  2383 /* Same as above, but doesn't allow the user to quit.  */
  2384 
  2385 int
  2386 emacs_open_noquit (char const *file, int oflags, int mode)
  2387 {
  2388   int fd;
  2389   if (! (oflags & O_TEXT))
  2390     oflags |= O_BINARY;
  2391   oflags |= O_CLOEXEC;
  2392   do
  2393     fd = open (file, oflags, mode);
  2394   while (fd < 0 && errno == EINTR);
  2395   return fd;
  2396 }
  2397 
  2398 /* Open FILE as a stream for Emacs use, with mode MODE.
  2399    Act like emacs_open with respect to threads, signals, and quits.  */
  2400 
  2401 FILE *
  2402 emacs_fopen (char const *file, char const *mode)
  2403 {
  2404   int fd, omode, oflags;
  2405   int bflag = 0;
  2406   char const *m = mode;
  2407 
  2408   switch (*m++)
  2409     {
  2410     case 'r': omode = O_RDONLY; oflags = 0; break;
  2411     case 'w': omode = O_WRONLY; oflags = O_CREAT | O_TRUNC; break;
  2412     case 'a': omode = O_WRONLY; oflags = O_CREAT | O_APPEND; break;
  2413     default: emacs_abort ();
  2414     }
  2415 
  2416   while (*m)
  2417     switch (*m++)
  2418       {
  2419       case '+': omode = O_RDWR; break;
  2420       case 't': bflag = O_TEXT; break;
  2421       default: /* Ignore.  */ break;
  2422       }
  2423 
  2424   fd = emacs_open (file, omode | oflags | bflag, 0666);
  2425   return fd < 0 ? 0 : fdopen (fd, mode);
  2426 }
  2427 
  2428 /* Create a pipe for Emacs use.  */
  2429 
  2430 int
  2431 emacs_pipe (int fd[2])
  2432 {
  2433 #ifdef MSDOS
  2434   return pipe (fd);
  2435 #else  /* !MSDOS */
  2436   return pipe2 (fd, O_BINARY | O_CLOEXEC);
  2437 #endif  /* !MSDOS */
  2438 }
  2439 
  2440 /* Approximate posix_close and POSIX_CLOSE_RESTART well enough for Emacs.
  2441    For the background behind this mess, please see Austin Group defect 529
  2442    <https://austingroupbugs.net/view.php?id=529>.  */
  2443 
  2444 #ifndef POSIX_CLOSE_RESTART
  2445 # define POSIX_CLOSE_RESTART 1
  2446 static int
  2447 posix_close (int fd, int flag)
  2448 {
  2449   /* Only the POSIX_CLOSE_RESTART case is emulated.  */
  2450   eassert (flag == POSIX_CLOSE_RESTART);
  2451 
  2452   /* Things are tricky if close (fd) returns -1 with errno == EINTR
  2453      on a system that does not define POSIX_CLOSE_RESTART.
  2454 
  2455      In this case, in some systems (e.g., GNU/Linux, AIX) FD is
  2456      closed, and retrying the close could inadvertently close a file
  2457      descriptor allocated by some other thread.  In other systems
  2458      (e.g., HP/UX) FD is not closed.  And in still other systems
  2459      (e.g., macOS, Solaris), maybe FD is closed, maybe not, and in a
  2460      multithreaded program there can be no way to tell.
  2461 
  2462      So, in this case, pretend that the close succeeded.  This works
  2463      well on systems like GNU/Linux that close FD.  Although it may
  2464      leak a file descriptor on other systems, the leak is unlikely and
  2465      it's better to leak than to close a random victim.  */
  2466   return close (fd) == 0 || errno == EINTR ? 0 : -1;
  2467 }
  2468 #endif
  2469 
  2470 /* Close FD, retrying if interrupted.  If successful, return 0;
  2471    otherwise, return -1 and set errno to a non-EINTR value.  Consider
  2472    an EINPROGRESS error to be successful, as that's merely a signal
  2473    arriving.  FD is always closed when this function returns, even
  2474    when it returns -1.
  2475 
  2476    Do not call this function if FD is nonnegative and might already be closed,
  2477    as that might close an innocent victim opened by some other thread.  */
  2478 
  2479 int
  2480 emacs_close (int fd)
  2481 {
  2482   while (1)
  2483     {
  2484       int r = posix_close (fd, POSIX_CLOSE_RESTART);
  2485       if (r == 0)
  2486         return r;
  2487       if (!POSIX_CLOSE_RESTART || errno != EINTR)
  2488         {
  2489           eassert (errno != EBADF || fd < 0);
  2490           return errno == EINPROGRESS ? 0 : r;
  2491         }
  2492     }
  2493 }
  2494 
  2495 /* Maximum number of bytes to read or write in a single system call.
  2496    This works around a serious bug in Linux kernels before 2.6.16; see
  2497    <https://bugzilla.redhat.com/show_bug.cgi?format=multiple&id=612839>.
  2498    It's likely to work around similar bugs in other operating systems, so do it
  2499    on all platforms.  Round INT_MAX down to a page size, with the conservative
  2500    assumption that page sizes are at most 2**18 bytes (any kernel with a
  2501    page size larger than that shouldn't have the bug).  */
  2502 #ifndef MAX_RW_COUNT
  2503 #define MAX_RW_COUNT (INT_MAX >> 18 << 18)
  2504 #endif
  2505 
  2506 /* Verify that MAX_RW_COUNT fits in the relevant standard types.  */
  2507 #ifndef SSIZE_MAX
  2508 # define SSIZE_MAX TYPE_MAXIMUM (ssize_t)
  2509 #endif
  2510 verify (MAX_RW_COUNT <= PTRDIFF_MAX);
  2511 verify (MAX_RW_COUNT <= SIZE_MAX);
  2512 verify (MAX_RW_COUNT <= SSIZE_MAX);
  2513 
  2514 #ifdef WINDOWSNT
  2515 /* Verify that Emacs read requests cannot cause trouble, even in
  2516    64-bit builds.  The last argument of 'read' is 'unsigned int', and
  2517    the return value's type (see 'sys_read') is 'int'.  */
  2518 verify (MAX_RW_COUNT <= INT_MAX);
  2519 verify (MAX_RW_COUNT <= UINT_MAX);
  2520 #endif
  2521 
  2522 /* Read from FD to a buffer BUF with size NBYTE.
  2523    If interrupted, process any quits and pending signals immediately
  2524    if INTERRUPTIBLE, and then retry the read unless quitting.
  2525    Return the number of bytes read, which might be less than NBYTE.
  2526    On error, set errno to a value other than EINTR, and return -1.  */
  2527 static ptrdiff_t
  2528 emacs_intr_read (int fd, void *buf, ptrdiff_t nbyte, bool interruptible)
  2529 {
  2530   /* No caller should ever pass a too-large size to emacs_read.  */
  2531   eassert (nbyte <= MAX_RW_COUNT);
  2532 
  2533   ssize_t result;
  2534 
  2535   do
  2536     {
  2537       if (interruptible)
  2538         maybe_quit ();
  2539       result = read (fd, buf, nbyte);
  2540     }
  2541   while (result < 0 && errno == EINTR);
  2542 
  2543   return result;
  2544 }
  2545 
  2546 /* Read from FD to a buffer BUF with size NBYTE.
  2547    If interrupted, retry the read.  Return the number of bytes read,
  2548    which might be less than NBYTE.  On error, set errno to a value
  2549    other than EINTR, and return -1.  */
  2550 ptrdiff_t
  2551 emacs_read (int fd, void *buf, ptrdiff_t nbyte)
  2552 {
  2553   return emacs_intr_read (fd, buf, nbyte, false);
  2554 }
  2555 
  2556 /* Like emacs_read, but also process quits and pending signals.  */
  2557 ptrdiff_t
  2558 emacs_read_quit (int fd, void *buf, ptrdiff_t nbyte)
  2559 {
  2560   return emacs_intr_read (fd, buf, nbyte, true);
  2561 }
  2562 
  2563 /* Write to FILEDES from a buffer BUF with size NBYTE, retrying if
  2564    interrupted or if a partial write occurs.  Process any quits
  2565    immediately if INTERRUPTIBLE is positive, and process any pending
  2566    signals immediately if INTERRUPTIBLE is nonzero.  Return the number
  2567    of bytes written; if this is less than NBYTE, set errno to a value
  2568    other than EINTR.  */
  2569 static ptrdiff_t
  2570 emacs_full_write (int fd, char const *buf, ptrdiff_t nbyte,
  2571                   int interruptible)
  2572 {
  2573   ptrdiff_t bytes_written = 0;
  2574 
  2575   while (nbyte > 0)
  2576     {
  2577       ssize_t n = write (fd, buf, min (nbyte, MAX_RW_COUNT));
  2578 
  2579       if (n < 0)
  2580         {
  2581           if (errno != EINTR)
  2582             break;
  2583 
  2584           if (interruptible)
  2585             {
  2586               if (0 < interruptible)
  2587                 maybe_quit ();
  2588               if (pending_signals)
  2589                 process_pending_signals ();
  2590             }
  2591         }
  2592       else
  2593         {
  2594           buf += n;
  2595           nbyte -= n;
  2596           bytes_written += n;
  2597         }
  2598     }
  2599 
  2600   return bytes_written;
  2601 }
  2602 
  2603 /* Write to FD from a buffer BUF with size NBYTE, retrying if
  2604    interrupted or if a partial write occurs.  Do not process quits or
  2605    pending signals.  Return the number of bytes written, setting errno
  2606    if this is less than NBYTE.  */
  2607 ptrdiff_t
  2608 emacs_write (int fd, void const *buf, ptrdiff_t nbyte)
  2609 {
  2610   return emacs_full_write (fd, buf, nbyte, 0);
  2611 }
  2612 
  2613 /* Like emacs_write, but also process pending signals.  */
  2614 ptrdiff_t
  2615 emacs_write_sig (int fd, void const *buf, ptrdiff_t nbyte)
  2616 {
  2617   return emacs_full_write (fd, buf, nbyte, -1);
  2618 }
  2619 
  2620 /* Like emacs_write, but also process quits and pending signals.  */
  2621 ptrdiff_t
  2622 emacs_write_quit (int fd, void const *buf, ptrdiff_t nbyte)
  2623 {
  2624   return emacs_full_write (fd, buf, nbyte, 1);
  2625 }
  2626 
  2627 /* Write a diagnostic to standard error that contains MESSAGE and a
  2628    string derived from errno.  Preserve errno.  Do not buffer stderr.
  2629    Do not process quits or pending signals if interrupted.  */
  2630 void
  2631 emacs_perror (char const *message)
  2632 {
  2633   int err = errno;
  2634   char const *error_string = emacs_strerror (err);
  2635   char const *command = (initial_argv && initial_argv[0]
  2636                          ? initial_argv[0] : "emacs");
  2637   /* Write it out all at once, if it's short; this is less likely to
  2638      be interleaved with other output.  */
  2639   char buf[min (PIPE_BUF, MAX_ALLOCA)];
  2640   int nbytes = snprintf (buf, sizeof buf, "%s: %s: %s\n",
  2641                          command, message, error_string);
  2642   if (0 <= nbytes && nbytes < sizeof buf)
  2643     emacs_write (STDERR_FILENO, buf, nbytes);
  2644   else
  2645     {
  2646       emacs_write (STDERR_FILENO, command, strlen (command));
  2647       emacs_write (STDERR_FILENO, ": ", 2);
  2648       emacs_write (STDERR_FILENO, message, strlen (message));
  2649       emacs_write (STDERR_FILENO, ": ", 2);
  2650       emacs_write (STDERR_FILENO, error_string, strlen (error_string));
  2651       emacs_write (STDERR_FILENO, "\n", 1);
  2652     }
  2653   errno = err;
  2654 }
  2655 
  2656 /* Rename directory SRCFD's entry SRC to directory DSTFD's entry DST.
  2657    This is like renameat except that it fails if DST already exists,
  2658    or if this operation is not supported atomically.  Return 0 if
  2659    successful, -1 (setting errno) otherwise.  */
  2660 int
  2661 renameat_noreplace (int srcfd, char const *src, int dstfd, char const *dst)
  2662 {
  2663 #if defined SYS_renameat2 && defined RENAME_NOREPLACE
  2664   return syscall (SYS_renameat2, srcfd, src, dstfd, dst, RENAME_NOREPLACE);
  2665 #elif defined CYGWIN && defined RENAME_NOREPLACE
  2666   return renameat2 (srcfd, src, dstfd, dst, RENAME_NOREPLACE);
  2667 #elif defined RENAME_EXCL
  2668   return renameatx_np (srcfd, src, dstfd, dst, RENAME_EXCL);
  2669 #else
  2670 # ifdef WINDOWSNT
  2671   if (srcfd == AT_FDCWD && dstfd == AT_FDCWD)
  2672     return sys_rename_replace (src, dst, 0);
  2673 # endif
  2674   errno = ENOSYS;
  2675   return -1;
  2676 #endif
  2677 }
  2678 
  2679 /* Like strsignal, except async-signal-safe, and this function
  2680    returns a string in the C locale rather than the current locale.  */
  2681 char const *
  2682 safe_strsignal (int code)
  2683 {
  2684   char const *signame = sigdescr_np (code);
  2685 
  2686   if (! signame)
  2687     signame = "Unknown signal";
  2688 
  2689   return signame;
  2690 }
  2691 
  2692 /* Output to stderr.  */
  2693 
  2694 /* Return the error output stream.  */
  2695 static FILE *
  2696 errstream (void)
  2697 {
  2698   FILE *err = buferr;
  2699   if (!err)
  2700     return stderr;
  2701   fflush_unlocked (stderr);
  2702   return err;
  2703 }
  2704 
  2705 /* These functions are like fputc, vfprintf, and fwrite,
  2706    except that they output to stderr and buffer better on
  2707    platforms that support line buffering.  This avoids interleaving
  2708    output when Emacs and other processes write to stderr
  2709    simultaneously, so long as the lines are short enough.  When a
  2710    single diagnostic is emitted via a sequence of calls of one or more
  2711    of these functions, the caller should arrange for the last called
  2712    function to output a newline at the end.  */
  2713 
  2714 void
  2715 errputc (int c)
  2716 {
  2717   fputc_unlocked (c, errstream ());
  2718 
  2719 #ifdef WINDOWSNT
  2720   /* Flush stderr after outputting a newline since stderr is fully
  2721      buffered when redirected to a pipe, contrary to POSIX.  */
  2722   if (c == '\n')
  2723     fflush_unlocked (stderr);
  2724 #endif
  2725 }
  2726 
  2727 void
  2728 errwrite (void const *buf, ptrdiff_t nbuf)
  2729 {
  2730   fwrite_unlocked (buf, 1, nbuf, errstream ());
  2731 }
  2732 
  2733 /* Close standard output and standard error, reporting any write
  2734    errors as best we can.  This is intended for use with atexit.  */
  2735 void
  2736 close_output_streams (void)
  2737 {
  2738   if (close_stream (stdout) != 0)
  2739     {
  2740       emacs_perror ("Write error to standard output");
  2741       _exit (EXIT_FAILURE);
  2742     }
  2743 
  2744   /* Do not close stderr if addresses are being sanitized, as the
  2745      sanitizer might report to stderr after this function is invoked.  */
  2746   bool err = buferr && (fflush (buferr) != 0 || ferror (buferr));
  2747   if (err | (ADDRESS_SANITIZER
  2748              ? fflush (stderr) != 0 || ferror (stderr)
  2749              : close_stream (stderr) != 0))
  2750     _exit (EXIT_FAILURE);
  2751 }
  2752 
  2753 #ifndef DOS_NT
  2754 /* For make-serial-process  */
  2755 int
  2756 serial_open (Lisp_Object port)
  2757 {
  2758   int fd = emacs_open (SSDATA (port), O_RDWR | O_NOCTTY | O_NONBLOCK, 0);
  2759   if (fd < 0)
  2760     report_file_error ("Opening serial port", port);
  2761 #ifdef TIOCEXCL
  2762   ioctl (fd, TIOCEXCL, (char *) 0);
  2763 #endif
  2764 
  2765   return fd;
  2766 }
  2767 
  2768 #if !defined (HAVE_CFMAKERAW)
  2769 /* Workaround for targets which are missing cfmakeraw.  */
  2770 /* Pasted from man page.  */
  2771 static void
  2772 cfmakeraw (struct termios *termios_p)
  2773 {
  2774     termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
  2775     termios_p->c_oflag &= ~OPOST;
  2776     termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
  2777     termios_p->c_cflag &= ~(CSIZE|PARENB);
  2778     termios_p->c_cflag |= CS8;
  2779 }
  2780 #endif /* !defined (HAVE_CFMAKERAW */
  2781 
  2782 #if !defined (HAVE_CFSETSPEED)
  2783 /* Workaround for targets which are missing cfsetspeed.  */
  2784 static int
  2785 cfsetspeed (struct termios *termios_p, speed_t vitesse)
  2786 {
  2787   return (cfsetispeed (termios_p, vitesse)
  2788           + cfsetospeed (termios_p, vitesse));
  2789 }
  2790 #endif
  2791 
  2792 /* The following is based on the glibc implementation of cfsetspeed.  */
  2793 
  2794 struct speed_struct
  2795 {
  2796   speed_t value;
  2797   speed_t internal;
  2798 };
  2799 
  2800 static const struct speed_struct speeds[] =
  2801   {
  2802 #ifdef B0
  2803     { 0, B0 },
  2804 #endif
  2805 #ifdef B50
  2806     { 50, B50 },
  2807 #endif
  2808 #ifdef B75
  2809     { 75, B75 },
  2810 #endif
  2811 #ifdef B110
  2812     { 110, B110 },
  2813 #endif
  2814 #ifdef B134
  2815     { 134, B134 },
  2816 #endif
  2817 #ifdef B150
  2818     { 150, B150 },
  2819 #endif
  2820 #ifndef HAVE_TINY_SPEED_T
  2821 #ifdef B200
  2822     { 200, B200 },
  2823 #endif
  2824 #ifdef B300
  2825     { 300, B300 },
  2826 #endif
  2827 #ifdef B600
  2828     { 600, B600 },
  2829 #endif
  2830 #ifdef B1200
  2831     { 1200, B1200 },
  2832 #endif
  2833 #ifdef B1200
  2834     { 1200, B1200 },
  2835 #endif
  2836 #ifdef B1800
  2837     { 1800, B1800 },
  2838 #endif
  2839 #ifdef B2400
  2840     { 2400, B2400 },
  2841 #endif
  2842 #ifdef B4800
  2843     { 4800, B4800 },
  2844 #endif
  2845 #ifdef B9600
  2846     { 9600, B9600 },
  2847 #endif
  2848 #ifdef B19200
  2849     { 19200, B19200 },
  2850 #endif
  2851 #ifdef B38400
  2852     { 38400, B38400 },
  2853 #endif
  2854 #ifdef B57600
  2855     { 57600, B57600 },
  2856 #endif
  2857 #ifdef B76800
  2858     { 76800, B76800 },
  2859 #endif
  2860 #ifdef B115200
  2861     { 115200, B115200 },
  2862 #endif
  2863 #ifdef B153600
  2864     { 153600, B153600 },
  2865 #endif
  2866 #ifdef B230400
  2867     { 230400, B230400 },
  2868 #endif
  2869 #ifdef B307200
  2870     { 307200, B307200 },
  2871 #endif
  2872 #ifdef B460800
  2873     { 460800, B460800 },
  2874 #endif
  2875 #ifdef B500000
  2876     { 500000, B500000 },
  2877 #endif
  2878 #ifdef B576000
  2879     { 576000, B576000 },
  2880 #endif
  2881 #ifdef B921600
  2882     { 921600, B921600 },
  2883 #endif
  2884 #ifdef B1000000
  2885     { 1000000, B1000000 },
  2886 #endif
  2887 #ifdef B1152000
  2888     { 1152000, B1152000 },
  2889 #endif
  2890 #ifdef B1500000
  2891     { 1500000, B1500000 },
  2892 #endif
  2893 #ifdef B2000000
  2894     { 2000000, B2000000 },
  2895 #endif
  2896 #ifdef B2500000
  2897     { 2500000, B2500000 },
  2898 #endif
  2899 #ifdef B3000000
  2900     { 3000000, B3000000 },
  2901 #endif
  2902 #ifdef B3500000
  2903     { 3500000, B3500000 },
  2904 #endif
  2905 #ifdef B4000000
  2906     { 4000000, B4000000 },
  2907 #endif
  2908 #endif /* HAVE_TINY_SPEED_T */
  2909   };
  2910 
  2911 /* Convert a numerical speed (e.g., 9600) to a Bnnn constant (e.g.,
  2912    B9600); see bug#49524.  */
  2913 static speed_t
  2914 convert_speed (speed_t speed)
  2915 {
  2916   for (size_t i = 0; i < sizeof speeds / sizeof speeds[0]; i++)
  2917     {
  2918       if (speed == speeds[i].internal)
  2919         return speed;
  2920       else if (speed == speeds[i].value)
  2921         return speeds[i].internal;
  2922     }
  2923   return speed;
  2924 }
  2925 
  2926 /* For serial-process-configure  */
  2927 void
  2928 serial_configure (struct Lisp_Process *p,
  2929                   Lisp_Object contact)
  2930 {
  2931   Lisp_Object childp2 = Qnil;
  2932   Lisp_Object tem = Qnil;
  2933   struct termios attr;
  2934   int err;
  2935   char summary[4] = "???"; /* This usually becomes "8N1".  */
  2936 
  2937   childp2 = Fcopy_sequence (p->childp);
  2938 
  2939   /* Read port attributes and prepare default configuration.  */
  2940   err = tcgetattr (p->outfd, &attr);
  2941   if (err != 0)
  2942     report_file_error ("Failed tcgetattr", Qnil);
  2943   cfmakeraw (&attr);
  2944 #if defined (CLOCAL)
  2945   attr.c_cflag |= CLOCAL;
  2946 #endif
  2947 #if defined (CREAD)
  2948   attr.c_cflag |= CREAD;
  2949 #endif
  2950 
  2951   /* Configure speed.  */
  2952   if (!NILP (plist_member (contact, QCspeed)))
  2953     tem = plist_get (contact, QCspeed);
  2954   else
  2955     tem = plist_get (p->childp, QCspeed);
  2956   CHECK_FIXNUM (tem);
  2957   err = cfsetspeed (&attr, convert_speed (XFIXNUM (tem)));
  2958   if (err != 0)
  2959     report_file_error ("Failed cfsetspeed", tem);
  2960   childp2 = plist_put (childp2, QCspeed, tem);
  2961 
  2962   /* Configure bytesize.  */
  2963   if (!NILP (plist_member (contact, QCbytesize)))
  2964     tem = plist_get (contact, QCbytesize);
  2965   else
  2966     tem = plist_get (p->childp, QCbytesize);
  2967   if (NILP (tem))
  2968     tem = make_fixnum (8);
  2969   CHECK_FIXNUM (tem);
  2970   if (XFIXNUM (tem) != 7 && XFIXNUM (tem) != 8)
  2971     error (":bytesize must be nil (8), 7, or 8");
  2972   summary[0] = XFIXNUM (tem) + '0';
  2973 #if defined (CSIZE) && defined (CS7) && defined (CS8)
  2974   attr.c_cflag &= ~CSIZE;
  2975   attr.c_cflag |= ((XFIXNUM (tem) == 7) ? CS7 : CS8);
  2976 #else
  2977   /* Don't error on bytesize 8, which should be set by cfmakeraw.  */
  2978   if (XFIXNUM (tem) != 8)
  2979     error ("Bytesize cannot be changed");
  2980 #endif
  2981   childp2 = plist_put (childp2, QCbytesize, tem);
  2982 
  2983   /* Configure parity.  */
  2984   if (!NILP (plist_member (contact, QCparity)))
  2985     tem = plist_get (contact, QCparity);
  2986   else
  2987     tem = plist_get (p->childp, QCparity);
  2988   if (!NILP (tem) && !EQ (tem, Qeven) && !EQ (tem, Qodd))
  2989     error (":parity must be nil (no parity), `even', or `odd'");
  2990 #if defined (PARENB) && defined (PARODD) && defined (IGNPAR) && defined (INPCK)
  2991   attr.c_cflag &= ~(PARENB | PARODD);
  2992   attr.c_iflag &= ~(IGNPAR | INPCK);
  2993   if (NILP (tem))
  2994     {
  2995       summary[1] = 'N';
  2996     }
  2997   else if (EQ (tem, Qeven))
  2998     {
  2999       summary[1] = 'E';
  3000       attr.c_cflag |= PARENB;
  3001       attr.c_iflag |= (IGNPAR | INPCK);
  3002     }
  3003   else if (EQ (tem, Qodd))
  3004     {
  3005       summary[1] = 'O';
  3006       attr.c_cflag |= (PARENB | PARODD);
  3007       attr.c_iflag |= (IGNPAR | INPCK);
  3008     }
  3009 #else
  3010   /* Don't error on no parity, which should be set by cfmakeraw.  */
  3011   if (!NILP (tem))
  3012     error ("Parity cannot be configured");
  3013 #endif
  3014   childp2 = plist_put (childp2, QCparity, tem);
  3015 
  3016   /* Configure stopbits.  */
  3017   if (!NILP (plist_member (contact, QCstopbits)))
  3018     tem = plist_get (contact, QCstopbits);
  3019   else
  3020     tem = plist_get (p->childp, QCstopbits);
  3021   if (NILP (tem))
  3022     tem = make_fixnum (1);
  3023   CHECK_FIXNUM (tem);
  3024   if (XFIXNUM (tem) != 1 && XFIXNUM (tem) != 2)
  3025     error (":stopbits must be nil (1 stopbit), 1, or 2");
  3026   summary[2] = XFIXNUM (tem) + '0';
  3027 #if defined (CSTOPB)
  3028   attr.c_cflag &= ~CSTOPB;
  3029   if (XFIXNUM (tem) == 2)
  3030     attr.c_cflag |= CSTOPB;
  3031 #else
  3032   /* Don't error on 1 stopbit, which should be set by cfmakeraw.  */
  3033   if (XFIXNUM (tem) != 1)
  3034     error ("Stopbits cannot be configured");
  3035 #endif
  3036   childp2 = plist_put (childp2, QCstopbits, tem);
  3037 
  3038   /* Configure flowcontrol.  */
  3039   if (!NILP (plist_member (contact, QCflowcontrol)))
  3040     tem = plist_get (contact, QCflowcontrol);
  3041   else
  3042     tem = plist_get (p->childp, QCflowcontrol);
  3043   if (!NILP (tem) && !EQ (tem, Qhw) && !EQ (tem, Qsw))
  3044     error (":flowcontrol must be nil (no flowcontrol), `hw', or `sw'");
  3045 #if defined (CRTSCTS)
  3046   attr.c_cflag &= ~CRTSCTS;
  3047 #endif
  3048 #if defined (CNEW_RTSCTS)
  3049   attr.c_cflag &= ~CNEW_RTSCTS;
  3050 #endif
  3051 #if defined (IXON) && defined (IXOFF)
  3052   attr.c_iflag &= ~(IXON | IXOFF);
  3053 #endif
  3054   if (NILP (tem))
  3055     {
  3056       /* Already configured.  */
  3057     }
  3058   else if (EQ (tem, Qhw))
  3059     {
  3060 #if defined (CRTSCTS)
  3061       attr.c_cflag |= CRTSCTS;
  3062 #elif defined (CNEW_RTSCTS)
  3063       attr.c_cflag |= CNEW_RTSCTS;
  3064 #else
  3065       error ("Hardware flowcontrol (RTS/CTS) not supported");
  3066 #endif
  3067     }
  3068   else if (EQ (tem, Qsw))
  3069     {
  3070 #if defined (IXON) && defined (IXOFF)
  3071       attr.c_iflag |= (IXON | IXOFF);
  3072 #else
  3073       error ("Software flowcontrol (XON/XOFF) not supported");
  3074 #endif
  3075     }
  3076   childp2 = plist_put (childp2, QCflowcontrol, tem);
  3077 
  3078   /* Activate configuration.  */
  3079   err = tcsetattr (p->outfd, TCSANOW, &attr);
  3080   if (err != 0)
  3081     report_file_error ("Failed tcsetattr", Qnil);
  3082 
  3083   childp2 = plist_put (childp2, QCsummary, build_string (summary));
  3084   pset_childp (p, childp2);
  3085 }
  3086 #endif /* not DOS_NT  */
  3087 
  3088 /* System depended enumeration of and access to system processes a-la ps(1).  */
  3089 
  3090 #ifdef HAVE_PROCFS
  3091 
  3092 /* Process enumeration and access via /proc.  */
  3093 
  3094 Lisp_Object
  3095 list_system_processes (void)
  3096 {
  3097   Lisp_Object procdir, match, proclist, next;
  3098   Lisp_Object tail;
  3099 
  3100   /* For every process on the system, there's a directory in the
  3101      "/proc" pseudo-directory whose name is the numeric ID of that
  3102      process.  */
  3103   procdir = build_string ("/proc");
  3104   match = build_string ("[0-9]+");
  3105   proclist = directory_files_internal (procdir, Qnil, match, Qt,
  3106                                        false, Qnil, Qnil);
  3107 
  3108   /* `proclist' gives process IDs as strings.  Destructively convert
  3109      each string into a number.  */
  3110   for (tail = proclist; CONSP (tail); tail = next)
  3111     {
  3112       next = XCDR (tail);
  3113       XSETCAR (tail, Fstring_to_number (XCAR (tail), Qnil));
  3114     }
  3115 
  3116   /* directory_files_internal returns the files in reverse order; undo
  3117      that.  */
  3118   proclist = Fnreverse (proclist);
  3119   return proclist;
  3120 }
  3121 
  3122 #elif defined DARWIN_OS || defined __FreeBSD__ || defined __OpenBSD__
  3123 
  3124 Lisp_Object
  3125 list_system_processes (void)
  3126 {
  3127 #ifdef DARWIN_OS
  3128   int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
  3129 #elif defined __OpenBSD__
  3130   int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0,
  3131     sizeof (struct kinfo_proc), 4096};
  3132 #else
  3133   int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PROC};
  3134 #endif
  3135   size_t len;
  3136   size_t mibsize = sizeof mib / sizeof mib[0];
  3137   struct kinfo_proc *procs;
  3138   size_t i;
  3139 
  3140   Lisp_Object proclist = Qnil;
  3141 
  3142   if (sysctl (mib, mibsize, NULL, &len, NULL, 0) != 0 || len == 0)
  3143     return proclist;
  3144 
  3145   procs = xmalloc (len);
  3146   if (sysctl (mib, mibsize, procs, &len, NULL, 0) != 0 || len == 0)
  3147     {
  3148       xfree (procs);
  3149       return proclist;
  3150     }
  3151 
  3152   len /= sizeof procs[0];
  3153   for (i = 0; i < len; i++)
  3154     {
  3155 #ifdef DARWIN_OS
  3156       proclist = Fcons (INT_TO_INTEGER (procs[i].kp_proc.p_pid), proclist);
  3157 #elif defined __OpenBSD__
  3158       proclist = Fcons (INT_TO_INTEGER (procs[i].p_pid), proclist);
  3159 #else
  3160       proclist = Fcons (INT_TO_INTEGER (procs[i].ki_pid), proclist);
  3161 #endif
  3162     }
  3163 
  3164   xfree (procs);
  3165 
  3166   return  proclist;
  3167 }
  3168 
  3169 /* The WINDOWSNT implementation is in w32.c.
  3170    The MSDOS implementation is in dosfns.c.
  3171    The Haiku implementation is in haiku.c.  */
  3172 #elif !defined (WINDOWSNT) && !defined (MSDOS) && !defined (HAIKU)
  3173 
  3174 Lisp_Object
  3175 list_system_processes (void)
  3176 {
  3177   return Qnil;
  3178 }
  3179 
  3180 #endif /* !defined (WINDOWSNT) */
  3181 
  3182 #if (HAVE_GETRUSAGE \
  3183      || defined __FreeBSD__ || defined DARWIN_OS || defined __OpenBSD__)
  3184 
  3185 static Lisp_Object
  3186 make_lisp_s_us (time_t s, long us)
  3187 {
  3188   Lisp_Object sec = make_int (s);
  3189   Lisp_Object usec = make_fixnum (us);
  3190   Lisp_Object hz = make_fixnum (1000000);
  3191   Lisp_Object ticks = CALLN (Fplus, CALLN (Ftimes, sec, hz), usec);
  3192   return Ftime_convert (Fcons (ticks, hz), Qnil);
  3193 }
  3194 
  3195 #endif
  3196 
  3197 #if defined __FreeBSD__ || defined DARWIN_OS
  3198 
  3199 static Lisp_Object
  3200 make_lisp_timeval (struct timeval t)
  3201 {
  3202   return make_lisp_s_us (t.tv_sec, t.tv_usec);
  3203 }
  3204 
  3205 #endif
  3206 
  3207 #if defined (GNU_LINUX) || defined (CYGWIN)
  3208 
  3209 static Lisp_Object
  3210 time_from_jiffies (unsigned long long ticks, Lisp_Object hz, Lisp_Object form)
  3211 {
  3212   return Ftime_convert (Fcons (make_uint (ticks), hz), form);
  3213 }
  3214 
  3215 static Lisp_Object
  3216 put_jiffies (Lisp_Object attrs, Lisp_Object propname,
  3217              unsigned long long ticks, Lisp_Object hz)
  3218 {
  3219   return Fcons (Fcons (propname, time_from_jiffies (ticks, hz, Qnil)), attrs);
  3220 }
  3221 
  3222 static Lisp_Object
  3223 get_up_time (void)
  3224 {
  3225   FILE *fup;
  3226   Lisp_Object up = Qnil;
  3227 
  3228   block_input ();
  3229   fup = emacs_fopen ("/proc/uptime", "r");
  3230 
  3231   if (fup)
  3232     {
  3233       unsigned long long upsec;
  3234       EMACS_UINT upfrac;
  3235       int upfrac_start, upfrac_end;
  3236 
  3237       if (fscanf (fup, "%llu.%n%"pI"u%n",
  3238                   &upsec, &upfrac_start, &upfrac, &upfrac_end)
  3239           == 2)
  3240         {
  3241           EMACS_INT hz = 1;
  3242           for (int i = upfrac_start; i < upfrac_end; i++)
  3243             hz *= 10;
  3244           Lisp_Object sec = make_uint (upsec);
  3245           Lisp_Object subsec = Fcons (make_fixnum (upfrac), make_fixnum (hz));
  3246           up = Ftime_add (sec, subsec);
  3247         }
  3248       fclose (fup);
  3249     }
  3250   unblock_input ();
  3251 
  3252   return up;
  3253 }
  3254 
  3255 # ifdef GNU_LINUX
  3256 #define MAJOR(d) (((unsigned)(d) >> 8) & 0xfff)
  3257 #define MINOR(d) (((unsigned)(d) & 0xff) | (((unsigned)(d) & 0xfff00000) >> 12))
  3258 
  3259 static Lisp_Object
  3260 procfs_ttyname (int rdev)
  3261 {
  3262   FILE *fdev;
  3263   char name[PATH_MAX];
  3264 
  3265   block_input ();
  3266   fdev = emacs_fopen ("/proc/tty/drivers", "r");
  3267   name[0] = 0;
  3268 
  3269   if (fdev)
  3270     {
  3271       unsigned major;
  3272       unsigned long minor_beg, minor_end;
  3273       char minor[25];   /* 2 32-bit numbers + dash */
  3274       char *endp;
  3275 
  3276       for (; !feof (fdev) && !ferror (fdev); name[0] = 0)
  3277         {
  3278           if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3
  3279               && major == MAJOR (rdev))
  3280             {
  3281               minor_beg = strtoul (minor, &endp, 0);
  3282               if (*endp == '\0')
  3283                 minor_end = minor_beg;
  3284               else if (*endp == '-')
  3285                 minor_end = strtoul (endp + 1, &endp, 0);
  3286               else
  3287                 continue;
  3288 
  3289               if (MINOR (rdev) >= minor_beg && MINOR (rdev) <= minor_end)
  3290                 {
  3291                   sprintf (name + strlen (name), "%u", MINOR (rdev));
  3292                   break;
  3293                 }
  3294             }
  3295         }
  3296       fclose (fdev);
  3297     }
  3298   unblock_input ();
  3299   return build_string (name);
  3300 }
  3301 # endif /* GNU_LINUX */
  3302 
  3303 static uintmax_t
  3304 procfs_get_total_memory (void)
  3305 {
  3306   FILE *fmem;
  3307   uintmax_t retval = 2 * 1024 * 1024; /* default: 2 GiB */
  3308   int c;
  3309 
  3310   block_input ();
  3311   fmem = emacs_fopen ("/proc/meminfo", "r");
  3312 
  3313   if (fmem)
  3314     {
  3315       uintmax_t entry_value;
  3316       bool done;
  3317 
  3318       do
  3319         switch (fscanf (fmem, "MemTotal: %"SCNuMAX, &entry_value))
  3320           {
  3321           case 1:
  3322             retval = entry_value;
  3323             done = 1;
  3324             break;
  3325 
  3326           case 0:
  3327             while ((c = getc (fmem)) != EOF && c != '\n')
  3328               continue;
  3329             done = c == EOF;
  3330             break;
  3331 
  3332           default:
  3333             done = 1;
  3334             break;
  3335           }
  3336       while (!done);
  3337 
  3338       fclose (fmem);
  3339     }
  3340   unblock_input ();
  3341   return retval;
  3342 }
  3343 
  3344 Lisp_Object
  3345 system_process_attributes (Lisp_Object pid)
  3346 {
  3347   char procfn[PATH_MAX], fn[PATH_MAX];
  3348   struct stat st;
  3349   struct passwd *pw;
  3350   struct group *gr;
  3351   long clocks_per_sec;
  3352   char *procfn_end;
  3353   char procbuf[1025], *p, *q UNINIT;
  3354   int fd;
  3355   ssize_t nread;
  3356   static char const default_cmd[] = "???";
  3357   const char *cmd = default_cmd;
  3358   int cmdsize = sizeof default_cmd - 1;
  3359   char *cmdline = NULL;
  3360   ptrdiff_t cmdline_size;
  3361   char c;
  3362   intmax_t proc_id;
  3363   int ppid, pgrp, sess, tty, tpgid, thcount;
  3364   uid_t uid;
  3365   gid_t gid;
  3366   unsigned long long u_time, s_time, cutime, cstime, start;
  3367   long priority, niceness, rss;
  3368   unsigned long minflt, majflt, cminflt, cmajflt, vsize;
  3369   double pcpu, pmem;
  3370   Lisp_Object attrs = Qnil;
  3371   Lisp_Object decoded_cmd;
  3372 
  3373   CHECK_NUMBER (pid);
  3374   CONS_TO_INTEGER (pid, pid_t, proc_id);
  3375   sprintf (procfn, "/proc/%"PRIdMAX, proc_id);
  3376   if (stat (procfn, &st) < 0)
  3377     return attrs;
  3378 
  3379   /* euid egid */
  3380   uid = st.st_uid;
  3381   attrs = Fcons (Fcons (Qeuid, INT_TO_INTEGER (uid)), attrs);
  3382   block_input ();
  3383   pw = getpwuid (uid);
  3384   unblock_input ();
  3385   if (pw)
  3386     attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
  3387 
  3388   gid = st.st_gid;
  3389   attrs = Fcons (Fcons (Qegid, INT_TO_INTEGER (gid)), attrs);
  3390   block_input ();
  3391   gr = getgrgid (gid);
  3392   unblock_input ();
  3393   if (gr)
  3394     attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
  3395 
  3396   specpdl_ref count = SPECPDL_INDEX ();
  3397   strcpy (fn, procfn);
  3398   procfn_end = fn + strlen (fn);
  3399   strcpy (procfn_end, "/stat");
  3400   fd = emacs_open (fn, O_RDONLY, 0);
  3401   if (fd < 0)
  3402     nread = 0;
  3403   else
  3404     {
  3405       record_unwind_protect_int (close_file_unwind, fd);
  3406       nread = emacs_read_quit (fd, procbuf, sizeof procbuf - 1);
  3407     }
  3408   if (0 < nread)
  3409     {
  3410       procbuf[nread] = '\0';
  3411       p = procbuf;
  3412 
  3413       p = strchr (p, '(');
  3414       if (p != NULL)
  3415         {
  3416           q = strrchr (p + 1, ')');
  3417           /* comm */
  3418           if (q != NULL)
  3419             {
  3420               cmd = p + 1;
  3421               cmdsize = q - cmd;
  3422             }
  3423         }
  3424       else
  3425         q = NULL;
  3426       /* Command name is encoded in locale-coding-system; decode it.  */
  3427       AUTO_STRING_WITH_LEN (cmd_str, cmd, cmdsize);
  3428       decoded_cmd = code_convert_string_norecord (cmd_str,
  3429                                                   Vlocale_coding_system, 0);
  3430       attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
  3431 
  3432       /* state ppid pgrp sess tty tpgid . minflt cminflt majflt cmajflt
  3433          utime stime cutime cstime priority nice thcount . start vsize rss */
  3434       if (q
  3435           && (sscanf (q + 2, ("%c %d %d %d %d %d %*u %lu %lu %lu %lu "
  3436                               "%llu %llu %llu %llu %ld %ld %d %*d %llu %lu %ld"),
  3437                       &c, &ppid, &pgrp, &sess, &tty, &tpgid,
  3438                       &minflt, &cminflt, &majflt, &cmajflt,
  3439                       &u_time, &s_time, &cutime, &cstime,
  3440                       &priority, &niceness, &thcount, &start, &vsize, &rss)
  3441               == 20))
  3442         {
  3443           char state_str[2];
  3444           state_str[0] = c;
  3445           state_str[1] = '\0';
  3446           attrs = Fcons (Fcons (Qstate, build_string (state_str)), attrs);
  3447           attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (ppid)), attrs);
  3448           attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (pgrp)), attrs);
  3449           attrs = Fcons (Fcons (Qsess, INT_TO_INTEGER (sess)), attrs);
  3450 # ifdef GNU_LINUX
  3451           attrs = Fcons (Fcons (Qttname, procfs_ttyname (tty)), attrs);
  3452 # endif
  3453           attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (tpgid)), attrs);
  3454           attrs = Fcons (Fcons (Qminflt, INT_TO_INTEGER (minflt)), attrs);
  3455           attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (majflt)), attrs);
  3456           attrs = Fcons (Fcons (Qcminflt, INT_TO_INTEGER (cminflt)), attrs);
  3457           attrs = Fcons (Fcons (Qcmajflt, INT_TO_INTEGER (cmajflt)), attrs);
  3458 
  3459           clocks_per_sec = sysconf (_SC_CLK_TCK);
  3460           if (0 < clocks_per_sec)
  3461             {
  3462               Lisp_Object hz = make_int (clocks_per_sec);
  3463               attrs = put_jiffies (attrs, Qutime, u_time, hz);
  3464               attrs = put_jiffies (attrs, Qstime, s_time, hz);
  3465               attrs = put_jiffies (attrs, Qtime, s_time + u_time, hz);
  3466               attrs = put_jiffies (attrs, Qcutime, cutime, hz);
  3467               attrs = put_jiffies (attrs, Qcstime, cstime, hz);
  3468               attrs = put_jiffies (attrs, Qctime, cstime + cutime, hz);
  3469 
  3470               Lisp_Object uptime = get_up_time ();
  3471               if (!NILP (uptime))
  3472                 {
  3473                   Lisp_Object now = Ftime_convert (Qnil, hz);
  3474                   Lisp_Object boot = Ftime_subtract (now, uptime);
  3475                   Lisp_Object tstart = time_from_jiffies (start, hz, hz);
  3476                   Lisp_Object lstart =
  3477                     Ftime_convert (Ftime_add (boot, tstart), Qnil);
  3478                   attrs = Fcons (Fcons (Qstart, lstart), attrs);
  3479                   Lisp_Object etime =
  3480                     Ftime_convert (Ftime_subtract (uptime, tstart), Qnil);
  3481                   attrs = Fcons (Fcons (Qetime, etime), attrs);
  3482                   pcpu = (100.0 * (s_time + u_time)
  3483                           / (clocks_per_sec * float_time (etime)));
  3484                   attrs = Fcons (Fcons (Qpcpu, make_float (pcpu)), attrs);
  3485                 }
  3486             }
  3487 
  3488           attrs = Fcons (Fcons (Qpri, make_fixnum (priority)), attrs);
  3489           attrs = Fcons (Fcons (Qnice, make_fixnum (niceness)), attrs);
  3490           attrs = Fcons (Fcons (Qthcount, INT_TO_INTEGER (thcount)), attrs);
  3491           attrs = Fcons (Fcons (Qvsize, INT_TO_INTEGER (vsize / 1024)), attrs);
  3492           attrs = Fcons (Fcons (Qrss, INT_TO_INTEGER (4 * rss)), attrs);
  3493           pmem = 4.0 * 100 * rss / procfs_get_total_memory ();
  3494           if (pmem > 100)
  3495             pmem = 100;
  3496           attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs);
  3497         }
  3498     }
  3499   unbind_to (count, Qnil);
  3500 
  3501 # ifdef CYGWIN
  3502   /* ttname */
  3503   strcpy (procfn_end, "/ctty");
  3504   fd = emacs_open (fn, O_RDONLY, 0);
  3505   if (fd < 0)
  3506     nread = 0;
  3507   else
  3508     {
  3509       record_unwind_protect_int (close_file_unwind, fd);
  3510       nread = emacs_read_quit (fd, procbuf, sizeof procbuf);
  3511     }
  3512   /* /proc/<pid>/ctty should always end in newline. */
  3513   if (0 < nread && procbuf[nread - 1] == '\n')
  3514     procbuf[nread - 1] = '\0';
  3515   else
  3516     procbuf[0] = '\0';
  3517   attrs = Fcons (Fcons (Qttname, build_string (procbuf)), attrs);
  3518   unbind_to (count, Qnil);
  3519 # endif /* CYGWIN */
  3520 
  3521   /* args */
  3522   strcpy (procfn_end, "/cmdline");
  3523   fd = emacs_open (fn, O_RDONLY, 0);
  3524   if (fd >= 0)
  3525     {
  3526       ptrdiff_t readsize, nread_incr;
  3527       record_unwind_protect_int (close_file_unwind, fd);
  3528       record_unwind_protect_nothing ();
  3529       nread = cmdline_size = 0;
  3530 
  3531       do
  3532         {
  3533           cmdline = xpalloc (cmdline, &cmdline_size, 2, STRING_BYTES_BOUND, 1);
  3534           set_unwind_protect_ptr (specpdl_ref_add (count, 1), xfree, cmdline);
  3535 
  3536           /* Leave room even if every byte needs escaping below.  */
  3537           readsize = (cmdline_size >> 1) - nread;
  3538 
  3539           nread_incr = emacs_read_quit (fd, cmdline + nread, readsize);
  3540           nread += max (0, nread_incr);
  3541         }
  3542       while (nread_incr == readsize);
  3543 
  3544       if (nread)
  3545         {
  3546           /* We don't want trailing null characters.  */
  3547           for (p = cmdline + nread; cmdline < p && !p[-1]; p--)
  3548             continue;
  3549 
  3550           /* Escape-quote whitespace and backslashes.  */
  3551           q = cmdline + cmdline_size;
  3552           while (cmdline < p)
  3553             {
  3554               char c = *--p;
  3555               *--q = c ? c : ' ';
  3556               if (c_isspace (c) || c == '\\')
  3557                 *--q = '\\';
  3558             }
  3559 
  3560           nread = cmdline + cmdline_size - q;
  3561         }
  3562 
  3563       if (!nread)
  3564         {
  3565           nread = cmdsize + 2;
  3566           cmdline_size = nread + 1;
  3567           q = cmdline = xrealloc (cmdline, cmdline_size);
  3568           set_unwind_protect_ptr (specpdl_ref_add (count, 1), xfree, cmdline);
  3569           sprintf (cmdline, "[%.*s]", cmdsize, cmd);
  3570         }
  3571       /* Command line is encoded in locale-coding-system; decode it.  */
  3572       AUTO_STRING_WITH_LEN (cmd_str, q, nread);
  3573       decoded_cmd = code_convert_string_norecord (cmd_str,
  3574                                                   Vlocale_coding_system, 0);
  3575       unbind_to (count, Qnil);
  3576       attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
  3577     }
  3578 
  3579   return attrs;
  3580 }
  3581 
  3582 #elif defined (SOLARIS2) && defined (HAVE_PROCFS)
  3583 
  3584 /* The <procfs.h> header does not like to be included if _LP64 is defined and
  3585    __FILE_OFFSET_BITS == 64.  This is an ugly workaround that.  */
  3586 #if !defined (_LP64) && defined (_FILE_OFFSET_BITS) &&  (_FILE_OFFSET_BITS  ==  64)
  3587 #define PROCFS_FILE_OFFSET_BITS_HACK 1
  3588 #undef _FILE_OFFSET_BITS
  3589 #else
  3590 #define PROCFS_FILE_OFFSET_BITS_HACK 0
  3591 #endif
  3592 
  3593 #include <procfs.h>
  3594 
  3595 #if PROCFS_FILE_OFFSET_BITS_HACK ==  1
  3596 #define _FILE_OFFSET_BITS 64
  3597 #ifdef _FILE_OFFSET_BITS /* Avoid unused-macro warnings.  */
  3598 #endif
  3599 #endif /* PROCFS_FILE_OFFSET_BITS_HACK ==  1 */
  3600 
  3601 Lisp_Object
  3602 system_process_attributes (Lisp_Object pid)
  3603 {
  3604   char procfn[PATH_MAX], fn[PATH_MAX];
  3605   struct stat st;
  3606   struct passwd *pw;
  3607   struct group *gr;
  3608   char *procfn_end;
  3609   struct psinfo pinfo;
  3610   int fd;
  3611   ssize_t nread;
  3612   intmax_t proc_id;
  3613   uid_t uid;
  3614   gid_t gid;
  3615   Lisp_Object attrs = Qnil;
  3616   Lisp_Object decoded_cmd;
  3617 
  3618   CHECK_NUMBER (pid);
  3619   CONS_TO_INTEGER (pid, pid_t, proc_id);
  3620   sprintf (procfn, "/proc/%"PRIdMAX, proc_id);
  3621   if (stat (procfn, &st) < 0)
  3622     return attrs;
  3623 
  3624   /* euid egid */
  3625   uid = st.st_uid;
  3626   attrs = Fcons (Fcons (Qeuid, INT_TO_INTEGER (uid)), attrs);
  3627   block_input ();
  3628   pw = getpwuid (uid);
  3629   unblock_input ();
  3630   if (pw)
  3631     attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
  3632 
  3633   gid = st.st_gid;
  3634   attrs = Fcons (Fcons (Qegid, INT_TO_INTEGER (gid)), attrs);
  3635   block_input ();
  3636   gr = getgrgid (gid);
  3637   unblock_input ();
  3638   if (gr)
  3639     attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
  3640 
  3641   specpdl_ref count = SPECPDL_INDEX ();
  3642   strcpy (fn, procfn);
  3643   procfn_end = fn + strlen (fn);
  3644   strcpy (procfn_end, "/psinfo");
  3645   fd = emacs_open (fn, O_RDONLY, 0);
  3646   if (fd < 0)
  3647     nread = 0;
  3648   else
  3649     {
  3650       record_unwind_protect_int (close_file_unwind, fd);
  3651       nread = emacs_read_quit (fd, &pinfo, sizeof pinfo);
  3652     }
  3653 
  3654   if (nread == sizeof pinfo)
  3655     {
  3656       attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (pinfo.pr_ppid)), attrs);
  3657       attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (pinfo.pr_pgid)), attrs);
  3658       attrs = Fcons (Fcons (Qsess, INT_TO_INTEGER (pinfo.pr_sid)), attrs);
  3659 
  3660       {
  3661         char state_str[2];
  3662         state_str[0] = pinfo.pr_lwp.pr_sname;
  3663         state_str[1] = '\0';
  3664         attrs = Fcons (Fcons (Qstate, build_string (state_str)), attrs);
  3665       }
  3666 
  3667       /* FIXME: missing Qttyname. psinfo.pr_ttydev is a dev_t,
  3668          need to get a string from it. */
  3669 
  3670       /* FIXME: missing: Qtpgid */
  3671 
  3672       /* FIXME: missing:
  3673             Qminflt
  3674             Qmajflt
  3675             Qcminflt
  3676             Qcmajflt
  3677 
  3678             Qutime
  3679             Qcutime
  3680             Qstime
  3681             Qcstime
  3682             Are they available? */
  3683 
  3684       attrs = Fcons (Fcons (Qtime, make_lisp_time (pinfo.pr_time)), attrs);
  3685       attrs = Fcons (Fcons (Qctime, make_lisp_time (pinfo.pr_ctime)), attrs);
  3686       attrs = Fcons (Fcons (Qpri, make_fixnum (pinfo.pr_lwp.pr_pri)), attrs);
  3687       attrs = Fcons (Fcons (Qnice, make_fixnum (pinfo.pr_lwp.pr_nice)), attrs);
  3688       attrs = Fcons (Fcons (Qthcount, INT_TO_INTEGER (pinfo.pr_nlwp)), attrs);
  3689 
  3690       attrs = Fcons (Fcons (Qstart, make_lisp_time (pinfo.pr_start)), attrs);
  3691       attrs = Fcons (Fcons (Qvsize, INT_TO_INTEGER (pinfo.pr_size)), attrs);
  3692       attrs = Fcons (Fcons (Qrss, INT_TO_INTEGER (pinfo.pr_rssize)), attrs);
  3693 
  3694       /* pr_pctcpu and pr_pctmem are unsigned integers in the
  3695          range 0 .. 2**15, representing 0.0 .. 1.0.  */
  3696       attrs = Fcons (Fcons (Qpcpu,
  3697                             make_float (100.0 / 0x8000 * pinfo.pr_pctcpu)),
  3698                      attrs);
  3699       attrs = Fcons (Fcons (Qpmem,
  3700                             make_float (100.0 / 0x8000 * pinfo.pr_pctmem)),
  3701                      attrs);
  3702 
  3703       AUTO_STRING (fname, pinfo.pr_fname);
  3704       decoded_cmd = code_convert_string_norecord (fname,
  3705                                                   Vlocale_coding_system, 0);
  3706       attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
  3707       AUTO_STRING (psargs, pinfo.pr_psargs);
  3708       decoded_cmd = code_convert_string_norecord (psargs,
  3709                                                   Vlocale_coding_system, 0);
  3710       attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
  3711     }
  3712   return unbind_to (count, attrs);
  3713 }
  3714 
  3715 #elif defined __FreeBSD__
  3716 
  3717 Lisp_Object
  3718 system_process_attributes (Lisp_Object pid)
  3719 {
  3720   int proc_id;
  3721   int pagesize = getpagesize ();
  3722   unsigned long npages;
  3723   int fscale;
  3724   struct passwd *pw;
  3725   struct group  *gr;
  3726   char *ttyname;
  3727   size_t len;
  3728   char args[MAXPATHLEN];
  3729 
  3730   int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID};
  3731   struct kinfo_proc proc;
  3732   size_t proclen = sizeof proc;
  3733 
  3734   Lisp_Object attrs = Qnil;
  3735   Lisp_Object decoded_comm;
  3736 
  3737   CHECK_NUMBER (pid);
  3738   CONS_TO_INTEGER (pid, int, proc_id);
  3739   mib[3] = proc_id;
  3740 
  3741   if (sysctl (mib, 4, &proc, &proclen, NULL, 0) != 0 || proclen == 0)
  3742     return attrs;
  3743 
  3744   attrs = Fcons (Fcons (Qeuid, INT_TO_INTEGER (proc.ki_uid)), attrs);
  3745 
  3746   block_input ();
  3747   pw = getpwuid (proc.ki_uid);
  3748   unblock_input ();
  3749   if (pw)
  3750     attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
  3751 
  3752   attrs = Fcons (Fcons (Qegid, INT_TO_INTEGER (proc.ki_svgid)), attrs);
  3753 
  3754   block_input ();
  3755   gr = getgrgid (proc.ki_svgid);
  3756   unblock_input ();
  3757   if (gr)
  3758     attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
  3759 
  3760   AUTO_STRING (comm, proc.ki_comm);
  3761   decoded_comm = code_convert_string_norecord (comm, Vlocale_coding_system, 0);
  3762 
  3763   attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs);
  3764   {
  3765     char state[2] = {'\0', '\0'};
  3766     switch (proc.ki_stat)
  3767       {
  3768       case SRUN:
  3769         state[0] = 'R';
  3770         break;
  3771 
  3772       case SSLEEP:
  3773         state[0] = 'S';
  3774         break;
  3775 
  3776       case SLOCK:
  3777         state[0] = 'D';
  3778         break;
  3779 
  3780       case SZOMB:
  3781         state[0] = 'Z';
  3782         break;
  3783 
  3784       case SSTOP:
  3785         state[0] = 'T';
  3786         break;
  3787       }
  3788     attrs = Fcons (Fcons (Qstate, build_string (state)), attrs);
  3789   }
  3790 
  3791   attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (proc.ki_ppid)), attrs);
  3792   attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (proc.ki_pgid)), attrs);
  3793   attrs = Fcons (Fcons (Qsess, INT_TO_INTEGER (proc.ki_sid)),  attrs);
  3794 
  3795   block_input ();
  3796   ttyname = proc.ki_tdev == NODEV ? NULL : devname (proc.ki_tdev, S_IFCHR);
  3797   unblock_input ();
  3798   if (ttyname)
  3799     attrs = Fcons (Fcons (Qttname, build_string (ttyname)), attrs);
  3800 
  3801   attrs = Fcons (Fcons (Qtpgid,   INT_TO_INTEGER (proc.ki_tpgid)), attrs);
  3802   attrs = Fcons (Fcons (Qminflt,  INT_TO_INTEGER (proc.ki_rusage.ru_minflt)),
  3803                  attrs);
  3804   attrs = Fcons (Fcons (Qmajflt,  INT_TO_INTEGER (proc.ki_rusage.ru_majflt)),
  3805                  attrs);
  3806   attrs = Fcons (Fcons (Qcminflt, make_fixnum (proc.ki_rusage_ch.ru_minflt)), attrs);
  3807   attrs = Fcons (Fcons (Qcmajflt, make_fixnum (proc.ki_rusage_ch.ru_majflt)), attrs);
  3808 
  3809   Lisp_Object utime = make_lisp_timeval (proc.ki_rusage.ru_utime);
  3810   attrs = Fcons (Fcons (Qutime, utime), attrs);
  3811   Lisp_Object stime = make_lisp_timeval (proc.ki_rusage.ru_stime);
  3812   attrs = Fcons (Fcons (Qstime, stime), attrs);
  3813   attrs = Fcons (Fcons (Qtime, Ftime_add (utime, stime)), attrs);
  3814 
  3815   Lisp_Object cutime = make_lisp_timeval (proc.ki_rusage_ch.ru_utime);
  3816   attrs = Fcons (Fcons (Qcutime, cutime), attrs);
  3817   Lisp_Object cstime = make_lisp_timeval (proc.ki_rusage_ch.ru_stime);
  3818   attrs = Fcons (Fcons (Qcstime, cstime), attrs);
  3819   attrs = Fcons (Fcons (Qctime, Ftime_add (cutime, cstime)), attrs);
  3820 
  3821   attrs = Fcons (Fcons (Qthcount, INT_TO_INTEGER (proc.ki_numthreads)), attrs);
  3822   attrs = Fcons (Fcons (Qpri,   make_fixnum (proc.ki_pri.pri_native)), attrs);
  3823   attrs = Fcons (Fcons (Qnice,  make_fixnum (proc.ki_nice)), attrs);
  3824   Lisp_Object start = make_lisp_timeval (proc.ki_start);
  3825   attrs = Fcons (Fcons (Qstart, start), attrs);
  3826   attrs = Fcons (Fcons (Qvsize, make_fixnum (proc.ki_size >> 10)), attrs);
  3827   attrs = Fcons (Fcons (Qrss,   make_fixnum (proc.ki_rssize * pagesize >> 10)),
  3828                  attrs);
  3829 
  3830   Lisp_Object now = Ftime_convert (Qnil, make_fixnum (1000000));
  3831   Lisp_Object etime = Ftime_convert (Ftime_subtract (now, start), Qnil);
  3832   attrs = Fcons (Fcons (Qetime, etime), attrs);
  3833 
  3834   len = sizeof fscale;
  3835   if (sysctlbyname ("kern.fscale", &fscale, &len, NULL, 0) == 0)
  3836     {
  3837       double pcpu;
  3838       fixpt_t ccpu;
  3839       len = sizeof ccpu;
  3840       if (sysctlbyname ("kern.ccpu", &ccpu, &len, NULL, 0) == 0)
  3841         {
  3842           pcpu = (100.0 * proc.ki_pctcpu / fscale
  3843                   / (1 - exp (proc.ki_swtime * log ((double) ccpu / fscale))));
  3844           attrs = Fcons (Fcons (Qpcpu, INT_TO_INTEGER (pcpu)), attrs);
  3845         }
  3846     }
  3847 
  3848   len = sizeof npages;
  3849   if (sysctlbyname ("hw.availpages", &npages, &len, NULL, 0) == 0)
  3850     {
  3851       double pmem = (proc.ki_flag & P_INMEM
  3852                      ? 100.0 * proc.ki_rssize / npages
  3853                      : 0);
  3854       attrs = Fcons (Fcons (Qpmem, INT_TO_INTEGER (pmem)), attrs);
  3855     }
  3856 
  3857   mib[2] = KERN_PROC_ARGS;
  3858   len = MAXPATHLEN;
  3859   if (sysctl (mib, 4, args, &len, NULL, 0) == 0 && len != 0)
  3860     {
  3861       int i;
  3862       for (i = 0; i < len; i++)
  3863         {
  3864           if (! args[i] && i < len - 1)
  3865             args[i] = ' ';
  3866         }
  3867 
  3868       AUTO_STRING (comm, args);
  3869       decoded_comm = code_convert_string_norecord (comm,
  3870                                                    Vlocale_coding_system, 0);
  3871 
  3872       attrs = Fcons (Fcons (Qargs, decoded_comm), attrs);
  3873     }
  3874 
  3875   return attrs;
  3876 }
  3877 
  3878 #elif defined __OpenBSD__
  3879 
  3880 Lisp_Object
  3881 system_process_attributes (Lisp_Object pid)
  3882 {
  3883   int proc_id, fscale, i;
  3884   int pagesize = getpagesize ();
  3885   int mib[6];
  3886   size_t len;
  3887   double pct;
  3888   char *ttyname, args[ARG_MAX];
  3889   struct kinfo_proc proc;
  3890   struct passwd *pw;
  3891   struct group *gr;
  3892   struct uvmexp uvmexp;
  3893 
  3894   Lisp_Object attrs = Qnil;
  3895   Lisp_Object decoded_comm;
  3896 
  3897   CHECK_NUMBER (pid);
  3898   CONS_TO_INTEGER (pid, int, proc_id);
  3899 
  3900   len = sizeof proc;
  3901   mib[0] = CTL_KERN;
  3902   mib[1] = KERN_PROC;
  3903   mib[2] = KERN_PROC_PID;
  3904   mib[3] = proc_id;
  3905   mib[4] = len;
  3906   mib[5] = 1;
  3907   if (sysctl (mib, 6, &proc, &len, NULL, 0) != 0)
  3908     return attrs;
  3909 
  3910   attrs = Fcons (Fcons (Qeuid, INT_TO_INTEGER (proc.p_uid)), attrs);
  3911 
  3912   block_input ();
  3913   pw = getpwuid (proc.p_uid);
  3914   unblock_input ();
  3915   if (pw)
  3916     attrs = Fcons (Fcons (Quser, build_string(pw->pw_name)), attrs);
  3917 
  3918   attrs = Fcons (Fcons (Qegid, INT_TO_INTEGER(proc.p_svgid)), attrs);
  3919 
  3920   block_input ();
  3921   gr = getgrgid (proc.p_svgid);
  3922   unblock_input ();
  3923   if (gr)
  3924     attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
  3925 
  3926   AUTO_STRING (comm, proc.p_comm);
  3927   decoded_comm = code_convert_string_norecord (comm, Vlocale_coding_system, 0);
  3928   attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs);
  3929 
  3930   {
  3931     char state[2] = {'\0', '\0'};
  3932     switch (proc.p_stat) {
  3933     case SIDL:
  3934       state[0] = 'I';
  3935       break;
  3936     case SRUN:
  3937       state[0] = 'R';
  3938       break;
  3939     case SSLEEP:
  3940       state[0] = 'S';
  3941       break;
  3942     case SSTOP:
  3943       state[0] = 'T';
  3944       break;
  3945     case SZOMB:
  3946       state[0] = 'Z';
  3947       break;
  3948     case SDEAD:
  3949       state[0] = 'D';
  3950       break;
  3951     }
  3952     attrs = Fcons (Fcons (Qstate, build_string (state)), attrs);
  3953   }
  3954 
  3955   attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (proc.p_ppid)), attrs);
  3956   attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (proc.p_gid)), attrs);
  3957   attrs = Fcons (Fcons (Qsess, INT_TO_INTEGER (proc.p_sid)),  attrs);
  3958 
  3959   block_input ();
  3960   ttyname = proc.p_tdev == NODEV ? NULL : devname (proc.p_tdev, S_IFCHR);
  3961   unblock_input ();
  3962   if (ttyname)
  3963     attrs = Fcons (Fcons (Qttname, build_string (ttyname)), attrs);
  3964 
  3965   attrs = Fcons (Fcons (Qtpgid,   INT_TO_INTEGER (proc.p_tpgid)), attrs);
  3966   attrs = Fcons (Fcons (Qminflt,  INT_TO_INTEGER (proc.p_uru_minflt)),
  3967                  attrs);
  3968   attrs = Fcons (Fcons (Qmajflt,  INT_TO_INTEGER (proc.p_uru_majflt)),
  3969                  attrs);
  3970 
  3971   /* FIXME: missing cminflt, cmajflt. */
  3972 
  3973   Lisp_Object utime = make_lisp_s_us (proc.p_uutime_sec, proc.p_uutime_usec);
  3974   attrs = Fcons (Fcons (Qutime, utime), attrs);
  3975   Lisp_Object stime = make_lisp_s_us (proc.p_ustime_sec, proc.p_ustime_usec);
  3976   attrs = Fcons (Fcons (Qstime, stime), attrs);
  3977   attrs = Fcons (Fcons (Qtime, Ftime_add (utime, stime)), attrs);
  3978 
  3979   attrs = Fcons (Fcons (Qcutime, make_lisp_s_us (proc.p_uctime_sec,
  3980                                                  proc.p_uctime_usec)),
  3981                  attrs);
  3982 
  3983   /* FIXME: missing cstime and thus ctime. */
  3984 
  3985   attrs = Fcons (Fcons (Qpri,   make_fixnum (proc.p_priority)), attrs);
  3986   attrs = Fcons (Fcons (Qnice,  make_fixnum (proc.p_nice)), attrs);
  3987 
  3988   /* FIXME: missing thcount (thread count) */
  3989 
  3990   attrs = Fcons (Fcons (Qstart, make_lisp_s_us (proc.p_ustart_sec,
  3991                                                 proc.p_ustart_usec)),
  3992                  attrs);
  3993 
  3994   len = (proc.p_vm_tsize + proc.p_vm_dsize + proc.p_vm_ssize) * pagesize >> 10;
  3995   attrs = Fcons (Fcons (Qvsize, make_fixnum (len)), attrs);
  3996 
  3997   attrs = Fcons (Fcons (Qrss,   make_fixnum (proc.p_vm_rssize * pagesize >> 10)),
  3998                  attrs);
  3999 
  4000   Lisp_Object now = Ftime_convert (Qnil, make_fixnum (1000000));
  4001   Lisp_Object start = make_lisp_s_us (proc.p_ustart_sec,
  4002                                       proc.p_ustart_usec);
  4003   Lisp_Object etime = Ftime_convert (Ftime_subtract (now, start), Qnil);
  4004   attrs = Fcons (Fcons (Qetime, etime), attrs);
  4005 
  4006   len = sizeof (fscale);
  4007   mib[0] = CTL_KERN;
  4008   mib[1] = KERN_FSCALE;
  4009   if (sysctl (mib, 2, &fscale, &len, NULL, 0) != -1)
  4010     {
  4011       pct = (double)proc.p_pctcpu / fscale * 100.0;
  4012       attrs = Fcons (Fcons (Qpcpu, make_float (pct)), attrs);
  4013     }
  4014 
  4015   len = sizeof (uvmexp);
  4016   mib[0] = CTL_VM;
  4017   mib[1] = VM_UVMEXP;
  4018   if (sysctl (mib, 2, &uvmexp, &len, NULL, 0) != -1)
  4019     {
  4020       pct = (100.0 * (double)proc.p_vm_rssize / uvmexp.npages);
  4021       attrs = Fcons (Fcons (Qpmem, make_float (pct)), attrs);
  4022     }
  4023 
  4024   len = sizeof args;
  4025   mib[0] = CTL_KERN;
  4026   mib[1] = KERN_PROC_ARGS;
  4027   mib[2] = proc_id;
  4028   mib[3] = KERN_PROC_ARGV;
  4029   if (sysctl (mib, 4, &args, &len, NULL, 0) == 0 && len != 0)
  4030     {
  4031       char **argv = (char**)args;
  4032 
  4033       /* concatenate argv reusing the existing storage storage.
  4034          sysctl(8) guarantees that "the buffer pointed to by oldp is
  4035          filled with an array of char pointers followed by the strings
  4036          themselves." */
  4037       for (i = 0; argv[i] != NULL; ++i)
  4038         {
  4039           if (argv[i+1] != NULL)
  4040             {
  4041               len = strlen (argv[i]);
  4042               argv[i][len] = ' ';
  4043             }
  4044         }
  4045 
  4046       AUTO_STRING (comm, *argv);
  4047       decoded_comm = code_convert_string_norecord (comm,
  4048                                                    Vlocale_coding_system, 0);
  4049       attrs = Fcons (Fcons (Qargs, decoded_comm), attrs);
  4050     }
  4051 
  4052   return attrs;
  4053 }
  4054 
  4055 #elif defined DARWIN_OS
  4056 
  4057 #define HAVE_RUSAGE_INFO_CURRENT (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101000)
  4058 #define HAVE_PROC_PIDINFO (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)
  4059 
  4060 Lisp_Object
  4061 system_process_attributes (Lisp_Object pid)
  4062 {
  4063   int proc_id, i;
  4064   struct passwd *pw;
  4065   struct group  *gr;
  4066   char *ttyname;
  4067   struct timeval starttime;
  4068   dev_t tdev;
  4069   uid_t uid;
  4070   gid_t gid;
  4071 
  4072   int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID};
  4073   struct kinfo_proc proc;
  4074   size_t len = sizeof proc;
  4075 
  4076   Lisp_Object attrs = Qnil;
  4077   Lisp_Object decoded_comm;
  4078 
  4079   CHECK_NUMBER (pid);
  4080   CONS_TO_INTEGER (pid, int, proc_id);
  4081   mib[3] = proc_id;
  4082 
  4083   if (sysctl (mib, 4, &proc, &len, NULL, 0) != 0 || len == 0)
  4084     return attrs;
  4085 
  4086   uid = proc.kp_eproc.e_ucred.cr_uid;
  4087   attrs = Fcons (Fcons (Qeuid, INT_TO_INTEGER (uid)), attrs);
  4088 
  4089   block_input ();
  4090   pw = getpwuid (uid);
  4091   unblock_input ();
  4092   if (pw)
  4093     attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
  4094 
  4095   gid = proc.kp_eproc.e_pcred.p_svgid;
  4096   attrs = Fcons (Fcons (Qegid, INT_TO_INTEGER (gid)), attrs);
  4097 
  4098   block_input ();
  4099   gr = getgrgid (gid);
  4100   unblock_input ();
  4101   if (gr)
  4102     attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
  4103 
  4104   char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
  4105   char *comm;
  4106 
  4107   if (proc_pidpath (proc_id, pathbuf, sizeof(pathbuf)) > 0)
  4108     {
  4109       if ((comm = strrchr (pathbuf, '/')))
  4110         comm++;
  4111       else
  4112         comm = pathbuf;
  4113     }
  4114   else
  4115     comm = proc.kp_proc.p_comm;
  4116 
  4117   decoded_comm = (code_convert_string_norecord
  4118                   (build_unibyte_string (comm),
  4119                    Vlocale_coding_system, 0));
  4120   attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs);
  4121 
  4122   {
  4123     char state[2] = {'\0', '\0'};
  4124     switch (proc.kp_proc.p_stat)
  4125       {
  4126       case SRUN:
  4127         state[0] = 'R';
  4128         break;
  4129 
  4130       case SSLEEP:
  4131         state[0] = 'S';
  4132         break;
  4133 
  4134       case SZOMB:
  4135         state[0] = 'Z';
  4136         break;
  4137 
  4138       case SSTOP:
  4139         state[0] = 'T';
  4140         break;
  4141 
  4142       case SIDL:
  4143         state[0] = 'I';
  4144         break;
  4145       }
  4146     attrs = Fcons (Fcons (Qstate, build_string (state)), attrs);
  4147   }
  4148 
  4149   attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (proc.kp_eproc.e_ppid)), attrs);
  4150   attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (proc.kp_eproc.e_pgid)), attrs);
  4151 
  4152   tdev = proc.kp_eproc.e_tdev;
  4153   block_input ();
  4154   ttyname = tdev == NODEV ? NULL : devname (tdev, S_IFCHR);
  4155   unblock_input ();
  4156   if (ttyname)
  4157     attrs = Fcons (Fcons (Qttname, build_string (ttyname)), attrs);
  4158 
  4159   attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (proc.kp_eproc.e_tpgid)),
  4160                  attrs);
  4161 
  4162 #if HAVE_RUSAGE_INFO_CURRENT
  4163   rusage_info_current ri;
  4164   if (proc_pid_rusage(proc_id, RUSAGE_INFO_CURRENT, (rusage_info_t *) &ri) == 0)
  4165     {
  4166       struct timespec utime = make_timespec (ri.ri_user_time / TIMESPEC_HZ,
  4167                                              ri.ri_user_time % TIMESPEC_HZ);
  4168       struct timespec stime = make_timespec (ri.ri_system_time / TIMESPEC_HZ,
  4169                                              ri.ri_system_time % TIMESPEC_HZ);
  4170       attrs = Fcons (Fcons (Qutime, make_lisp_time (utime)), attrs);
  4171       attrs = Fcons (Fcons (Qstime, make_lisp_time (stime)), attrs);
  4172       attrs = Fcons (Fcons (Qtime, make_lisp_time (timespec_add (utime, stime))), attrs);
  4173 
  4174       attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (ri.ri_pageins)), attrs);
  4175   }
  4176 #else  /* !HAVE_RUSAGE_INFO_CURRENT */
  4177   struct rusage *rusage = proc.kp_proc.p_ru;
  4178   if (rusage)
  4179     {
  4180       attrs = Fcons (Fcons (Qminflt, INT_TO_INTEGER (rusage->ru_minflt)),
  4181                      attrs);
  4182       attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (rusage->ru_majflt)),
  4183                      attrs);
  4184 
  4185       Lisp_Object utime = make_lisp_timeval (rusage->ru_utime);
  4186       Lisp_Object stime = make_lisp_timeval (rusage->ru_stime);
  4187       attrs = Fcons (Fcons (Qutime, utime), attrs);
  4188       attrs = Fcons (Fcons (Qstime, stime), attrs);
  4189       attrs = Fcons (Fcons (Qtime, Ftime_add (utime, stime)), attrs);
  4190     }
  4191 #endif  /* !HAVE_RUSAGE_INFO_CURRENT */
  4192 
  4193   starttime = proc.kp_proc.p_starttime;
  4194   attrs = Fcons (Fcons (Qnice,  make_fixnum (proc.kp_proc.p_nice)), attrs);
  4195   Lisp_Object start = make_lisp_timeval (starttime);
  4196   attrs = Fcons (Fcons (Qstart, start), attrs);
  4197 
  4198   Lisp_Object now = Ftime_convert (Qnil, make_fixnum (1000000));
  4199   Lisp_Object etime = Ftime_convert (Ftime_subtract (now, start), Qnil);
  4200   attrs = Fcons (Fcons (Qetime, etime), attrs);
  4201 
  4202 #if HAVE_PROC_PIDINFO
  4203   struct proc_taskinfo taskinfo;
  4204   if (proc_pidinfo (proc_id, PROC_PIDTASKINFO, 0, &taskinfo, sizeof (taskinfo)) > 0)
  4205     {
  4206       attrs = Fcons (Fcons (Qvsize, make_fixnum (taskinfo.pti_virtual_size / 1024)), attrs);
  4207       attrs = Fcons (Fcons (Qrss, make_fixnum (taskinfo.pti_resident_size / 1024)), attrs);
  4208       attrs = Fcons (Fcons (Qthcount, make_fixnum (taskinfo.pti_threadnum)), attrs);
  4209     }
  4210 #endif  /* HAVE_PROC_PIDINFO */
  4211 
  4212 #ifdef KERN_PROCARGS2
  4213   char args[ARG_MAX];
  4214   mib[1] = KERN_PROCARGS2;
  4215   mib[2] = proc_id;
  4216   len = sizeof args;
  4217 
  4218   if (sysctl (mib, 3, &args, &len, NULL, 0) == 0 && len != 0)
  4219     {
  4220       char *start, *end;
  4221 
  4222       int argc = *(int*)args; /* argc is the first int */
  4223       start = args + sizeof (int);
  4224 
  4225       start += strlen (start) + 1; /* skip executable name and any '\0's */
  4226       while ((start - args < len) && ! *start) start++;
  4227 
  4228       /* skip argv to find real end */
  4229       for (i = 0, end = start; i < argc && (end - args) < len; i++)
  4230         {
  4231           end += strlen (end) + 1;
  4232         }
  4233 
  4234       len = end - start;
  4235       for (int i = 0; i < len; i++)
  4236         {
  4237           if (! start[i] && i < len - 1)
  4238             start[i] = ' ';
  4239         }
  4240 
  4241       AUTO_STRING (comm, start);
  4242       decoded_comm = code_convert_string_norecord (comm,
  4243                                                    Vlocale_coding_system, 0);
  4244       attrs = Fcons (Fcons (Qargs, decoded_comm), attrs);
  4245     }
  4246 #endif  /* KERN_PROCARGS2 */
  4247 
  4248   return attrs;
  4249 }
  4250 
  4251 /* The WINDOWSNT implementation is in w32.c.
  4252    The MSDOS implementation is in dosfns.c.
  4253    The HAIKU implementation is in haiku.c.  */
  4254 #elif !defined (WINDOWSNT) && !defined (MSDOS) && !defined (HAIKU)
  4255 
  4256 Lisp_Object
  4257 system_process_attributes (Lisp_Object pid)
  4258 {
  4259   return Qnil;
  4260 }
  4261 
  4262 #endif  /* !defined (WINDOWSNT) */
  4263 
  4264 DEFUN ("get-internal-run-time", Fget_internal_run_time, Sget_internal_run_time,
  4265        0, 0, 0,
  4266        doc: /* Return the current run time used by Emacs.
  4267 The time is returned as in the style of `current-time'.
  4268 
  4269 On systems that can't determine the run time, `get-internal-run-time'
  4270 does the same thing as `current-time'.  */)
  4271   (void)
  4272 {
  4273 #ifdef HAVE_GETRUSAGE
  4274   struct rusage usage;
  4275   time_t secs;
  4276   int usecs;
  4277 
  4278   if (getrusage (RUSAGE_SELF, &usage) < 0)
  4279     /* This shouldn't happen.  What action is appropriate?  */
  4280     xsignal0 (Qerror);
  4281 
  4282   /* Sum up user time and system time.  */
  4283   secs = usage.ru_utime.tv_sec + usage.ru_stime.tv_sec;
  4284   usecs = usage.ru_utime.tv_usec + usage.ru_stime.tv_usec;
  4285   if (usecs >= 1000000)
  4286     {
  4287       usecs -= 1000000;
  4288       secs++;
  4289     }
  4290   return make_lisp_s_us (secs, usecs);
  4291 #else /* ! HAVE_GETRUSAGE  */
  4292 #ifdef WINDOWSNT
  4293   return w32_get_internal_run_time ();
  4294 #else /* ! WINDOWSNT  */
  4295   return Fcurrent_time ();
  4296 #endif /* WINDOWSNT  */
  4297 #endif /* HAVE_GETRUSAGE  */
  4298 }
  4299 
  4300 /* Wide character string collation.  */
  4301 
  4302 #ifdef __STDC_ISO_10646__
  4303 # include <wchar.h>
  4304 # include <wctype.h>
  4305 
  4306 # if defined HAVE_NEWLOCALE || defined HAVE_SETLOCALE
  4307 #  include <locale.h>
  4308 # endif
  4309 # ifndef LC_COLLATE
  4310 #  define LC_COLLATE 0
  4311 # endif
  4312 # ifndef LC_COLLATE_MASK
  4313 #  define LC_COLLATE_MASK 0
  4314 # endif
  4315 # ifndef LC_CTYPE
  4316 #  define LC_CTYPE 0
  4317 # endif
  4318 # ifndef LC_CTYPE_MASK
  4319 #  define LC_CTYPE_MASK 0
  4320 # endif
  4321 
  4322 # ifndef HAVE_NEWLOCALE
  4323 #  undef freelocale
  4324 #  undef locale_t
  4325 #  undef newlocale
  4326 #  undef wcscoll_l
  4327 #  undef towlower_l
  4328 #  define freelocale emacs_freelocale
  4329 #  define locale_t emacs_locale_t
  4330 #  define newlocale emacs_newlocale
  4331 #  define wcscoll_l emacs_wcscoll_l
  4332 #  define towlower_l emacs_towlower_l
  4333 
  4334 typedef char const *locale_t;
  4335 
  4336 static locale_t
  4337 newlocale (int category_mask, char const *locale, locale_t loc)
  4338 {
  4339   return locale;
  4340 }
  4341 
  4342 static void
  4343 freelocale (locale_t loc)
  4344 {
  4345 }
  4346 
  4347 static char *
  4348 emacs_setlocale (int category, char const *locale)
  4349 {
  4350 #  ifdef HAVE_SETLOCALE
  4351   errno = 0;
  4352   char *loc = setlocale (category, locale);
  4353   if (loc || errno)
  4354     return loc;
  4355   errno = EINVAL;
  4356 #  else
  4357   errno = ENOTSUP;
  4358 #  endif
  4359   return 0;
  4360 }
  4361 
  4362 static int
  4363 wcscoll_l (wchar_t const *a, wchar_t const *b, locale_t loc)
  4364 {
  4365   int result = 0;
  4366   char *oldloc = emacs_setlocale (LC_COLLATE, NULL);
  4367   int err;
  4368 
  4369   if (! oldloc)
  4370     err = errno;
  4371   else
  4372     {
  4373       USE_SAFE_ALLOCA;
  4374       char *oldcopy = SAFE_ALLOCA (strlen (oldloc) + 1);
  4375       strcpy (oldcopy, oldloc);
  4376       if (! emacs_setlocale (LC_COLLATE, loc))
  4377         err = errno;
  4378       else
  4379         {
  4380           errno = 0;
  4381           result = wcscoll (a, b);
  4382           err = errno;
  4383           if (! emacs_setlocale (LC_COLLATE, oldcopy))
  4384             err = errno;
  4385         }
  4386       SAFE_FREE ();
  4387     }
  4388 
  4389   errno = err;
  4390   return result;
  4391 }
  4392 
  4393 static wint_t
  4394 towlower_l (wint_t wc, locale_t loc)
  4395 {
  4396   wint_t result = wc;
  4397   char *oldloc = emacs_setlocale (LC_CTYPE, NULL);
  4398 
  4399   if (oldloc)
  4400     {
  4401       USE_SAFE_ALLOCA;
  4402       char *oldcopy = SAFE_ALLOCA (strlen (oldloc) + 1);
  4403       strcpy (oldcopy, oldloc);
  4404       if (emacs_setlocale (LC_CTYPE, loc))
  4405         {
  4406           result = towlower (wc);
  4407           emacs_setlocale (LC_COLLATE, oldcopy);
  4408         }
  4409       SAFE_FREE ();
  4410     }
  4411 
  4412   return result;
  4413 }
  4414 # endif
  4415 
  4416 int
  4417 str_collate (Lisp_Object s1, Lisp_Object s2,
  4418              Lisp_Object locale, Lisp_Object ignore_case)
  4419 {
  4420   int res, err;
  4421   ptrdiff_t len, i, i_byte;
  4422   wchar_t *p1, *p2;
  4423 
  4424   USE_SAFE_ALLOCA;
  4425 
  4426   /* Convert byte stream to code points.  */
  4427   len = SCHARS (s1); i = i_byte = 0;
  4428   SAFE_NALLOCA (p1, 1, len + 1);
  4429   while (i < len)
  4430     {
  4431       wchar_t *p = &p1[i];
  4432       *p = fetch_string_char_advance (s1, &i, &i_byte);
  4433     }
  4434   p1[len] = 0;
  4435 
  4436   len = SCHARS (s2); i = i_byte = 0;
  4437   SAFE_NALLOCA (p2, 1, len + 1);
  4438   while (i < len)
  4439     {
  4440       wchar_t *p = &p2[i];
  4441       *p = fetch_string_char_advance (s2, &i, &i_byte);
  4442     }
  4443   p2[len] = 0;
  4444 
  4445   if (STRINGP (locale))
  4446     {
  4447       locale_t loc = newlocale (LC_COLLATE_MASK | LC_CTYPE_MASK,
  4448                                 SSDATA (locale), 0);
  4449       if (!loc)
  4450         error ("Invalid locale %s: %s", SSDATA (locale), emacs_strerror (errno));
  4451 
  4452       if (! NILP (ignore_case))
  4453         for (int i = 1; i < 3; i++)
  4454           {
  4455             wchar_t *p = (i == 1) ? p1 : p2;
  4456             for (; *p; p++)
  4457               *p = towlower_l (*p, loc);
  4458           }
  4459 
  4460       errno = 0;
  4461       res = wcscoll_l (p1, p2, loc);
  4462       err = errno;
  4463       freelocale (loc);
  4464     }
  4465   else
  4466     {
  4467       if (! NILP (ignore_case))
  4468         for (int i = 1; i < 3; i++)
  4469           {
  4470             wchar_t *p = (i == 1) ? p1 : p2;
  4471             for (; *p; p++)
  4472               *p = towlower (*p);
  4473           }
  4474 
  4475       errno = 0;
  4476       res = wcscoll (p1, p2);
  4477       err = errno;
  4478     }
  4479 #  ifndef HAVE_NEWLOCALE
  4480   if (err)
  4481     error ("Invalid locale or string for collation: %s", emacs_strerror (err));
  4482 #  else
  4483   if (err)
  4484     error ("Invalid string for collation: %s", emacs_strerror (err));
  4485 #  endif
  4486 
  4487   SAFE_FREE ();
  4488   return res;
  4489 }
  4490 #endif  /* __STDC_ISO_10646__ */
  4491 
  4492 #ifdef WINDOWSNT
  4493 int
  4494 str_collate (Lisp_Object s1, Lisp_Object s2,
  4495              Lisp_Object locale, Lisp_Object ignore_case)
  4496 {
  4497 
  4498   char *loc = STRINGP (locale) ? SSDATA (locale) : NULL;
  4499   int res, err = errno;
  4500 
  4501   errno = 0;
  4502   res = w32_compare_strings (SSDATA (s1), SSDATA (s2), loc, !NILP (ignore_case));
  4503   if (errno)
  4504     error ("Invalid string for collation: %s", strerror (errno));
  4505 
  4506   errno = err;
  4507   return res;
  4508 }
  4509 #endif  /* WINDOWSNT */
  4510 
  4511 void
  4512 syms_of_sysdep (void)
  4513 {
  4514   defsubr (&Sget_internal_run_time);
  4515 }

/* [<][>][^][v][top][bottom][index][help] */