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

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