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 int
  2648 emacs_fclose (FILE *stream)
  2649 {
  2650 #if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
  2651   return fclose (stream);
  2652 #else
  2653   return android_fclose (stream);
  2654 #endif
  2655 }
  2656 
  2657 /* Wrappers around unlink, symlink, rename, renameat_noreplace, and
  2658    rmdir.  These operations handle asset and content directories on
  2659    Android, and may return EINTR.  */
  2660 
  2661 int
  2662 emacs_unlink (const char *name)
  2663 {
  2664 #if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
  2665   return unlink (name);
  2666 #else /* !defined HAVE_ANDROID || defined ANDROID_STUBIFY */
  2667   return android_unlink (name);
  2668 #endif /* !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY) */
  2669 }
  2670 
  2671 int
  2672 emacs_symlink (const char *target, const char *linkname)
  2673 {
  2674 #if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
  2675   return symlink (target, linkname);
  2676 #else /* !defined HAVE_ANDROID || defined ANDROID_STUBIFY */
  2677   return android_symlink (target, linkname);
  2678 #endif /* !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY) */
  2679 }
  2680 
  2681 int
  2682 emacs_rmdir (const char *dirname)
  2683 {
  2684 #if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
  2685   return rmdir (dirname);
  2686 #else /* !defined HAVE_ANDROID || defined ANDROID_STUBIFY */
  2687   return android_rmdir (dirname);
  2688 #endif /* !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY) */
  2689 }
  2690 
  2691 int
  2692 emacs_mkdir (const char *dirname, mode_t mode)
  2693 {
  2694 #if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
  2695   return mkdir (dirname, mode);
  2696 #else /* !defined HAVE_ANDROID || defined ANDROID_STUBIFY */
  2697   return android_mkdir (dirname, mode);
  2698 #endif /* !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY) */
  2699 }
  2700 
  2701 int
  2702 emacs_renameat_noreplace (int srcfd, const char *src,
  2703                           int dstfd, const char *dst)
  2704 {
  2705 #if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
  2706   return renameat_noreplace (srcfd, src, dstfd, dst);
  2707 #else /* !defined HAVE_ANDROID || defined ANDROID_STUBIFY */
  2708   return android_renameat_noreplace (srcfd, src, dstfd, dst);
  2709 #endif /* !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY) */
  2710 }
  2711 
  2712 int
  2713 emacs_rename (const char *src, const char *dst)
  2714 {
  2715 #if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
  2716   return rename (src, dst);
  2717 #else /* !defined HAVE_ANDROID || defined ANDROID_STUBIFY */
  2718   return android_rename (src, dst);
  2719 #endif /* !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY) */
  2720 }
  2721 
  2722 int
  2723 emacs_fchmodat (int fd, const char *path, mode_t mode, int flags)
  2724 {
  2725 #if !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY)
  2726   return fchmodat (fd, path, mode, flags);
  2727 #else /* !defined HAVE_ANDROID || defined ANDROID_STUBIFY */
  2728   return android_fchmodat (fd, path, mode, flags);
  2729 #endif /* !(defined HAVE_ANDROID && !defined ANDROID_STUBIFY) */
  2730 }
  2731 
  2732 /* Maximum number of bytes to read or write in a single system call.
  2733    This works around a serious bug in Linux kernels before 2.6.16; see
  2734    <https://bugzilla.redhat.com/show_bug.cgi?format=multiple&id=612839>.
  2735    It's likely to work around similar bugs in other operating systems, so do it
  2736    on all platforms.  Round INT_MAX down to a page size, with the conservative
  2737    assumption that page sizes are at most 2**18 bytes (any kernel with a
  2738    page size larger than that shouldn't have the bug).  */
  2739 #ifndef MAX_RW_COUNT
  2740 #define MAX_RW_COUNT (INT_MAX >> 18 << 18)
  2741 #endif
  2742 
  2743 /* Verify that MAX_RW_COUNT fits in the relevant standard types.  */
  2744 #ifndef SSIZE_MAX
  2745 # define SSIZE_MAX TYPE_MAXIMUM (ssize_t)
  2746 #endif
  2747 verify (MAX_RW_COUNT <= PTRDIFF_MAX);
  2748 verify (MAX_RW_COUNT <= SIZE_MAX);
  2749 verify (MAX_RW_COUNT <= SSIZE_MAX);
  2750 
  2751 #ifdef WINDOWSNT
  2752 /* Verify that Emacs read requests cannot cause trouble, even in
  2753    64-bit builds.  The last argument of 'read' is 'unsigned int', and
  2754    the return value's type (see 'sys_read') is 'int'.  */
  2755 verify (MAX_RW_COUNT <= INT_MAX);
  2756 verify (MAX_RW_COUNT <= UINT_MAX);
  2757 #endif
  2758 
  2759 /* Read from FD to a buffer BUF with size NBYTE.
  2760    If interrupted, process any quits and pending signals immediately
  2761    if INTERRUPTIBLE, and then retry the read unless quitting.
  2762    Return the number of bytes read, which might be less than NBYTE.
  2763    On error, set errno to a value other than EINTR, and return -1.  */
  2764 static ptrdiff_t
  2765 emacs_intr_read (int fd, void *buf, ptrdiff_t nbyte, bool interruptible)
  2766 {
  2767   /* No caller should ever pass a too-large size to emacs_read.  */
  2768   eassert (nbyte <= MAX_RW_COUNT);
  2769 
  2770   ssize_t result;
  2771 
  2772   do
  2773     {
  2774       if (interruptible)
  2775         maybe_quit ();
  2776       result = read (fd, buf, nbyte);
  2777     }
  2778   while (result < 0 && errno == EINTR);
  2779 
  2780   return result;
  2781 }
  2782 
  2783 /* Read from FD to a buffer BUF with size NBYTE.
  2784    If interrupted, retry the read.  Return the number of bytes read,
  2785    which might be less than NBYTE.  On error, set errno to a value
  2786    other than EINTR, and return -1.  */
  2787 ptrdiff_t
  2788 emacs_read (int fd, void *buf, ptrdiff_t nbyte)
  2789 {
  2790   return emacs_intr_read (fd, buf, nbyte, false);
  2791 }
  2792 
  2793 /* Like emacs_read, but also process quits and pending signals.  */
  2794 ptrdiff_t
  2795 emacs_read_quit (int fd, void *buf, ptrdiff_t nbyte)
  2796 {
  2797   return emacs_intr_read (fd, buf, nbyte, true);
  2798 }
  2799 
  2800 /* Write to FILEDES from a buffer BUF with size NBYTE, retrying if
  2801    interrupted or if a partial write occurs.  Process any quits
  2802    immediately if INTERRUPTIBLE is positive, and process any pending
  2803    signals immediately if INTERRUPTIBLE is nonzero.  Return the number
  2804    of bytes written; if this is less than NBYTE, set errno to a value
  2805    other than EINTR.  */
  2806 static ptrdiff_t
  2807 emacs_full_write (int fd, char const *buf, ptrdiff_t nbyte,
  2808                   int interruptible)
  2809 {
  2810   ptrdiff_t bytes_written = 0;
  2811 
  2812   while (nbyte > 0)
  2813     {
  2814       ssize_t n = write (fd, buf, min (nbyte, MAX_RW_COUNT));
  2815 
  2816       if (n < 0)
  2817         {
  2818           if (errno != EINTR)
  2819             break;
  2820 
  2821           if (interruptible)
  2822             {
  2823               if (0 < interruptible)
  2824                 maybe_quit ();
  2825               if (pending_signals)
  2826                 process_pending_signals ();
  2827             }
  2828         }
  2829       else
  2830         {
  2831           buf += n;
  2832           nbyte -= n;
  2833           bytes_written += n;
  2834         }
  2835     }
  2836 
  2837   return bytes_written;
  2838 }
  2839 
  2840 /* Write to FD from a buffer BUF with size NBYTE, retrying if
  2841    interrupted or if a partial write occurs.  Do not process quits or
  2842    pending signals.  Return the number of bytes written, setting errno
  2843    if this is less than NBYTE.  */
  2844 ptrdiff_t
  2845 emacs_write (int fd, void const *buf, ptrdiff_t nbyte)
  2846 {
  2847   return emacs_full_write (fd, buf, nbyte, 0);
  2848 }
  2849 
  2850 /* Like emacs_write, but also process pending signals.  */
  2851 ptrdiff_t
  2852 emacs_write_sig (int fd, void const *buf, ptrdiff_t nbyte)
  2853 {
  2854   return emacs_full_write (fd, buf, nbyte, -1);
  2855 }
  2856 
  2857 /* Like emacs_write, but also process quits and pending signals.  */
  2858 ptrdiff_t
  2859 emacs_write_quit (int fd, void const *buf, ptrdiff_t nbyte)
  2860 {
  2861   return emacs_full_write (fd, buf, nbyte, 1);
  2862 }
  2863 
  2864 /* Write a diagnostic to standard error that contains MESSAGE and a
  2865    string derived from errno.  Preserve errno.  Do not buffer stderr.
  2866    Do not process quits or pending signals if interrupted.  */
  2867 void
  2868 emacs_perror (char const *message)
  2869 {
  2870   int err = errno;
  2871   char const *error_string = emacs_strerror (err);
  2872   char const *command = (initial_argv && initial_argv[0]
  2873                          ? initial_argv[0] : "emacs");
  2874   /* Write it out all at once, if it's short; this is less likely to
  2875      be interleaved with other output.  */
  2876   char buf[min (PIPE_BUF, MAX_ALLOCA)];
  2877   int nbytes = snprintf (buf, sizeof buf, "%s: %s: %s\n",
  2878                          command, message, error_string);
  2879   if (0 <= nbytes && nbytes < sizeof buf)
  2880     emacs_write (STDERR_FILENO, buf, nbytes);
  2881   else
  2882     {
  2883       emacs_write (STDERR_FILENO, command, strlen (command));
  2884       emacs_write (STDERR_FILENO, ": ", 2);
  2885       emacs_write (STDERR_FILENO, message, strlen (message));
  2886       emacs_write (STDERR_FILENO, ": ", 2);
  2887       emacs_write (STDERR_FILENO, error_string, strlen (error_string));
  2888       emacs_write (STDERR_FILENO, "\n", 1);
  2889     }
  2890   errno = err;
  2891 }
  2892 
  2893 /* Rename directory SRCFD's entry SRC to directory DSTFD's entry DST.
  2894    This is like renameat except that it fails if DST already exists,
  2895    or if this operation is not supported atomically.  Return 0 if
  2896    successful, -1 (setting errno) otherwise.  */
  2897 int
  2898 renameat_noreplace (int srcfd, char const *src, int dstfd, char const *dst)
  2899 {
  2900 #if HAVE_RENAMEAT2 && defined RENAME_NOREPLACE
  2901   return renameat2 (srcfd, src, dstfd, dst, RENAME_NOREPLACE);
  2902 #elif defined SYS_renameat2 && defined RENAME_NOREPLACE
  2903   /* Linux kernel 3.15 (2014) or later, with glibc 2.27 (2018) or earlier.  */
  2904   return syscall (SYS_renameat2, srcfd, src, dstfd, dst, RENAME_NOREPLACE);
  2905 #elif defined RENAME_EXCL
  2906   return renameatx_np (srcfd, src, dstfd, dst, RENAME_EXCL);
  2907 #else
  2908 # ifdef WINDOWSNT
  2909   if (srcfd == AT_FDCWD && dstfd == AT_FDCWD)
  2910     return sys_rename_replace (src, dst, 0);
  2911 # endif
  2912   errno = ENOSYS;
  2913   return -1;
  2914 #endif
  2915 }
  2916 
  2917 /* Like strsignal, except async-signal-safe, and this function
  2918    returns a string in the C locale rather than the current locale.  */
  2919 char const *
  2920 safe_strsignal (int code)
  2921 {
  2922   char const *signame = sigdescr_np (code);
  2923 
  2924   if (! signame)
  2925     signame = "Unknown signal";
  2926 
  2927   return signame;
  2928 }
  2929 
  2930 /* Output to stderr.  */
  2931 
  2932 /* Return the error output stream.  */
  2933 static FILE *
  2934 errstream (void)
  2935 {
  2936   FILE *err = buferr;
  2937   if (!err)
  2938     return stderr;
  2939   fflush_unlocked (stderr);
  2940   return err;
  2941 }
  2942 
  2943 /* These functions are like fputc, vfprintf, and fwrite,
  2944    except that they output to stderr and buffer better on
  2945    platforms that support line buffering.  This avoids interleaving
  2946    output when Emacs and other processes write to stderr
  2947    simultaneously, so long as the lines are short enough.  When a
  2948    single diagnostic is emitted via a sequence of calls of one or more
  2949    of these functions, the caller should arrange for the last called
  2950    function to output a newline at the end.  */
  2951 
  2952 void
  2953 errputc (int c)
  2954 {
  2955   fputc_unlocked (c, errstream ());
  2956 
  2957 #ifdef WINDOWSNT
  2958   /* Flush stderr after outputting a newline since stderr is fully
  2959      buffered when redirected to a pipe, contrary to POSIX.  */
  2960   if (c == '\n')
  2961     fflush_unlocked (stderr);
  2962 #endif
  2963 }
  2964 
  2965 void
  2966 errwrite (void const *buf, ptrdiff_t nbuf)
  2967 {
  2968   fwrite_unlocked (buf, 1, nbuf, errstream ());
  2969 }
  2970 
  2971 /* Close standard output and standard error, reporting any write
  2972    errors as best we can.  This is intended for use with atexit.  */
  2973 void
  2974 close_output_streams (void)
  2975 {
  2976   /* Android comes with some kind of ``file descriptor sanitizer''
  2977      that aborts when stdout or stderr is closed.  */
  2978 
  2979 #if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
  2980   fflush (stderr);
  2981   fflush (stdout);
  2982   return;
  2983 #endif
  2984 
  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 }
  2999 
  3000 #ifndef DOS_NT
  3001 /* For make-serial-process  */
  3002 int
  3003 serial_open (Lisp_Object port)
  3004 {
  3005   int fd = emacs_open (SSDATA (port), O_RDWR | O_NOCTTY | O_NONBLOCK, 0);
  3006   if (fd < 0)
  3007     report_file_error ("Opening serial port", port);
  3008 #ifdef TIOCEXCL
  3009   ioctl (fd, TIOCEXCL, (char *) 0);
  3010 #endif
  3011 
  3012   return fd;
  3013 }
  3014 
  3015 #if !defined (HAVE_CFMAKERAW)
  3016 /* Workaround for targets which are missing cfmakeraw.  */
  3017 /* Pasted from man page.  */
  3018 static void
  3019 cfmakeraw (struct termios *termios_p)
  3020 {
  3021     termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
  3022     termios_p->c_oflag &= ~OPOST;
  3023     termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
  3024     termios_p->c_cflag &= ~(CSIZE|PARENB);
  3025     termios_p->c_cflag |= CS8;
  3026 }
  3027 #endif /* !defined (HAVE_CFMAKERAW */
  3028 
  3029 #if !defined (HAVE_CFSETSPEED)
  3030 /* Workaround for targets which are missing cfsetspeed.  */
  3031 static int
  3032 cfsetspeed (struct termios *termios_p, speed_t vitesse)
  3033 {
  3034   return (cfsetispeed (termios_p, vitesse)
  3035           + cfsetospeed (termios_p, vitesse));
  3036 }
  3037 #endif
  3038 
  3039 /* The following is based on the glibc implementation of cfsetspeed.  */
  3040 
  3041 struct speed_struct
  3042 {
  3043   speed_t value;
  3044   speed_t internal;
  3045 };
  3046 
  3047 static const struct speed_struct speeds[] =
  3048   {
  3049 #ifdef B0
  3050     { 0, B0 },
  3051 #endif
  3052 #ifdef B50
  3053     { 50, B50 },
  3054 #endif
  3055 #ifdef B75
  3056     { 75, B75 },
  3057 #endif
  3058 #ifdef B110
  3059     { 110, B110 },
  3060 #endif
  3061 #ifdef B134
  3062     { 134, B134 },
  3063 #endif
  3064 #ifdef B150
  3065     { 150, B150 },
  3066 #endif
  3067 #ifndef HAVE_TINY_SPEED_T
  3068 #ifdef B200
  3069     { 200, B200 },
  3070 #endif
  3071 #ifdef B300
  3072     { 300, B300 },
  3073 #endif
  3074 #ifdef B600
  3075     { 600, B600 },
  3076 #endif
  3077 #ifdef B1200
  3078     { 1200, B1200 },
  3079 #endif
  3080 #ifdef B1200
  3081     { 1200, B1200 },
  3082 #endif
  3083 #ifdef B1800
  3084     { 1800, B1800 },
  3085 #endif
  3086 #ifdef B2400
  3087     { 2400, B2400 },
  3088 #endif
  3089 #ifdef B4800
  3090     { 4800, B4800 },
  3091 #endif
  3092 #ifdef B9600
  3093     { 9600, B9600 },
  3094 #endif
  3095 #ifdef B19200
  3096     { 19200, B19200 },
  3097 #endif
  3098 #ifdef B38400
  3099     { 38400, B38400 },
  3100 #endif
  3101 #ifdef B57600
  3102     { 57600, B57600 },
  3103 #endif
  3104 #ifdef B76800
  3105     { 76800, B76800 },
  3106 #endif
  3107 #ifdef B115200
  3108     { 115200, B115200 },
  3109 #endif
  3110 #ifdef B153600
  3111     { 153600, B153600 },
  3112 #endif
  3113 #ifdef B230400
  3114     { 230400, B230400 },
  3115 #endif
  3116 #ifdef B307200
  3117     { 307200, B307200 },
  3118 #endif
  3119 #ifdef B460800
  3120     { 460800, B460800 },
  3121 #endif
  3122 #ifdef B500000
  3123     { 500000, B500000 },
  3124 #endif
  3125 #ifdef B576000
  3126     { 576000, B576000 },
  3127 #endif
  3128 #ifdef B921600
  3129     { 921600, B921600 },
  3130 #endif
  3131 #ifdef B1000000
  3132     { 1000000, B1000000 },
  3133 #endif
  3134 #ifdef B1152000
  3135     { 1152000, B1152000 },
  3136 #endif
  3137 #ifdef B1500000
  3138     { 1500000, B1500000 },
  3139 #endif
  3140 #ifdef B2000000
  3141     { 2000000, B2000000 },
  3142 #endif
  3143 #ifdef B2500000
  3144     { 2500000, B2500000 },
  3145 #endif
  3146 #ifdef B3000000
  3147     { 3000000, B3000000 },
  3148 #endif
  3149 #ifdef B3500000
  3150     { 3500000, B3500000 },
  3151 #endif
  3152 #ifdef B4000000
  3153     { 4000000, B4000000 },
  3154 #endif
  3155 #endif /* HAVE_TINY_SPEED_T */
  3156   };
  3157 
  3158 /* Convert a numerical speed (e.g., 9600) to a Bnnn constant (e.g.,
  3159    B9600); see bug#49524.  */
  3160 static speed_t
  3161 convert_speed (speed_t speed)
  3162 {
  3163   for (size_t i = 0; i < sizeof speeds / sizeof speeds[0]; i++)
  3164     {
  3165       if (speed == speeds[i].internal)
  3166         return speed;
  3167       else if (speed == speeds[i].value)
  3168         return speeds[i].internal;
  3169     }
  3170   return speed;
  3171 }
  3172 
  3173 /* For serial-process-configure  */
  3174 void
  3175 serial_configure (struct Lisp_Process *p,
  3176                   Lisp_Object contact)
  3177 {
  3178   Lisp_Object childp2 = Qnil;
  3179   Lisp_Object tem = Qnil;
  3180   struct termios attr;
  3181   int err;
  3182   char summary[4] = "???"; /* This usually becomes "8N1".  */
  3183 
  3184   childp2 = Fcopy_sequence (p->childp);
  3185 
  3186   /* Read port attributes and prepare default configuration.  */
  3187   err = tcgetattr (p->outfd, &attr);
  3188   if (err != 0)
  3189     report_file_error ("Failed tcgetattr", Qnil);
  3190   cfmakeraw (&attr);
  3191 #if defined (CLOCAL)
  3192   attr.c_cflag |= CLOCAL;
  3193 #endif
  3194 #if defined (CREAD)
  3195   attr.c_cflag |= CREAD;
  3196 #endif
  3197 
  3198   /* Configure speed.  */
  3199   if (!NILP (plist_member (contact, QCspeed)))
  3200     tem = plist_get (contact, QCspeed);
  3201   else
  3202     tem = plist_get (p->childp, QCspeed);
  3203   CHECK_FIXNUM (tem);
  3204   err = cfsetspeed (&attr, convert_speed (XFIXNUM (tem)));
  3205   if (err != 0)
  3206     report_file_error ("Failed cfsetspeed", tem);
  3207   childp2 = plist_put (childp2, QCspeed, tem);
  3208 
  3209   /* Configure bytesize.  */
  3210   if (!NILP (plist_member (contact, QCbytesize)))
  3211     tem = plist_get (contact, QCbytesize);
  3212   else
  3213     tem = plist_get (p->childp, QCbytesize);
  3214   if (NILP (tem))
  3215     tem = make_fixnum (8);
  3216   CHECK_FIXNUM (tem);
  3217   if (XFIXNUM (tem) != 7 && XFIXNUM (tem) != 8)
  3218     error (":bytesize must be nil (8), 7, or 8");
  3219   summary[0] = XFIXNUM (tem) + '0';
  3220 #if defined (CSIZE) && defined (CS7) && defined (CS8)
  3221   attr.c_cflag &= ~CSIZE;
  3222   attr.c_cflag |= ((XFIXNUM (tem) == 7) ? CS7 : CS8);
  3223 #else
  3224   /* Don't error on bytesize 8, which should be set by cfmakeraw.  */
  3225   if (XFIXNUM (tem) != 8)
  3226     error ("Bytesize cannot be changed");
  3227 #endif
  3228   childp2 = plist_put (childp2, QCbytesize, tem);
  3229 
  3230   /* Configure parity.  */
  3231   if (!NILP (plist_member (contact, QCparity)))
  3232     tem = plist_get (contact, QCparity);
  3233   else
  3234     tem = plist_get (p->childp, QCparity);
  3235   if (!NILP (tem) && !EQ (tem, Qeven) && !EQ (tem, Qodd))
  3236     error (":parity must be nil (no parity), `even', or `odd'");
  3237 #if defined (PARENB) && defined (PARODD) && defined (IGNPAR) && defined (INPCK)
  3238   attr.c_cflag &= ~(PARENB | PARODD);
  3239   attr.c_iflag &= ~(IGNPAR | INPCK);
  3240   if (NILP (tem))
  3241     {
  3242       summary[1] = 'N';
  3243     }
  3244   else if (EQ (tem, Qeven))
  3245     {
  3246       summary[1] = 'E';
  3247       attr.c_cflag |= PARENB;
  3248       attr.c_iflag |= (IGNPAR | INPCK);
  3249     }
  3250   else if (EQ (tem, Qodd))
  3251     {
  3252       summary[1] = 'O';
  3253       attr.c_cflag |= (PARENB | PARODD);
  3254       attr.c_iflag |= (IGNPAR | INPCK);
  3255     }
  3256 #else
  3257   /* Don't error on no parity, which should be set by cfmakeraw.  */
  3258   if (!NILP (tem))
  3259     error ("Parity cannot be configured");
  3260 #endif
  3261   childp2 = plist_put (childp2, QCparity, tem);
  3262 
  3263   /* Configure stopbits.  */
  3264   if (!NILP (plist_member (contact, QCstopbits)))
  3265     tem = plist_get (contact, QCstopbits);
  3266   else
  3267     tem = plist_get (p->childp, QCstopbits);
  3268   if (NILP (tem))
  3269     tem = make_fixnum (1);
  3270   CHECK_FIXNUM (tem);
  3271   if (XFIXNUM (tem) != 1 && XFIXNUM (tem) != 2)
  3272     error (":stopbits must be nil (1 stopbit), 1, or 2");
  3273   summary[2] = XFIXNUM (tem) + '0';
  3274 #if defined (CSTOPB)
  3275   attr.c_cflag &= ~CSTOPB;
  3276   if (XFIXNUM (tem) == 2)
  3277     attr.c_cflag |= CSTOPB;
  3278 #else
  3279   /* Don't error on 1 stopbit, which should be set by cfmakeraw.  */
  3280   if (XFIXNUM (tem) != 1)
  3281     error ("Stopbits cannot be configured");
  3282 #endif
  3283   childp2 = plist_put (childp2, QCstopbits, tem);
  3284 
  3285   /* Configure flowcontrol.  */
  3286   if (!NILP (plist_member (contact, QCflowcontrol)))
  3287     tem = plist_get (contact, QCflowcontrol);
  3288   else
  3289     tem = plist_get (p->childp, QCflowcontrol);
  3290   if (!NILP (tem) && !EQ (tem, Qhw) && !EQ (tem, Qsw))
  3291     error (":flowcontrol must be nil (no flowcontrol), `hw', or `sw'");
  3292 #if defined (CRTSCTS)
  3293   attr.c_cflag &= ~CRTSCTS;
  3294 #endif
  3295 #if defined (CNEW_RTSCTS)
  3296   attr.c_cflag &= ~CNEW_RTSCTS;
  3297 #endif
  3298 #if defined (IXON) && defined (IXOFF)
  3299   attr.c_iflag &= ~(IXON | IXOFF);
  3300 #endif
  3301   if (NILP (tem))
  3302     {
  3303       /* Already configured.  */
  3304     }
  3305   else if (EQ (tem, Qhw))
  3306     {
  3307 #if defined (CRTSCTS)
  3308       attr.c_cflag |= CRTSCTS;
  3309 #elif defined (CNEW_RTSCTS)
  3310       attr.c_cflag |= CNEW_RTSCTS;
  3311 #else
  3312       error ("Hardware flowcontrol (RTS/CTS) not supported");
  3313 #endif
  3314     }
  3315   else if (EQ (tem, Qsw))
  3316     {
  3317 #if defined (IXON) && defined (IXOFF)
  3318       attr.c_iflag |= (IXON | IXOFF);
  3319 #else
  3320       error ("Software flowcontrol (XON/XOFF) not supported");
  3321 #endif
  3322     }
  3323   childp2 = plist_put (childp2, QCflowcontrol, tem);
  3324 
  3325   /* Activate configuration.  */
  3326   err = tcsetattr (p->outfd, TCSANOW, &attr);
  3327   if (err != 0)
  3328     report_file_error ("Failed tcsetattr", Qnil);
  3329 
  3330   childp2 = plist_put (childp2, QCsummary, build_string (summary));
  3331   pset_childp (p, childp2);
  3332 }
  3333 #endif /* not DOS_NT  */
  3334 
  3335 /* System depended enumeration of and access to system processes a-la ps(1).  */
  3336 
  3337 #ifdef HAVE_PROCFS
  3338 
  3339 /* Process enumeration and access via /proc.  */
  3340 
  3341 Lisp_Object
  3342 list_system_processes (void)
  3343 {
  3344   Lisp_Object procdir, match, proclist, next;
  3345   Lisp_Object tail;
  3346 
  3347   /* For every process on the system, there's a directory in the
  3348      "/proc" pseudo-directory whose name is the numeric ID of that
  3349      process.  */
  3350   procdir = build_string ("/proc");
  3351   match = build_string ("[0-9]+");
  3352   proclist = directory_files_internal (procdir, Qnil, match, Qt,
  3353                                        false, Qnil, Qnil);
  3354 
  3355   /* `proclist' gives process IDs as strings.  Destructively convert
  3356      each string into a number.  */
  3357   for (tail = proclist; CONSP (tail); tail = next)
  3358     {
  3359       next = XCDR (tail);
  3360       XSETCAR (tail, Fstring_to_number (XCAR (tail), Qnil));
  3361     }
  3362 
  3363   /* directory_files_internal returns the files in reverse order; undo
  3364      that.  */
  3365   proclist = Fnreverse (proclist);
  3366   return proclist;
  3367 }
  3368 
  3369 #elif defined DARWIN_OS || defined __FreeBSD__ || defined __OpenBSD__
  3370 
  3371 Lisp_Object
  3372 list_system_processes (void)
  3373 {
  3374 #ifdef DARWIN_OS
  3375   int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
  3376 #elif defined __OpenBSD__
  3377   int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0,
  3378     sizeof (struct kinfo_proc), 4096};
  3379 #else
  3380   int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PROC};
  3381 #endif
  3382   size_t len;
  3383   size_t mibsize = sizeof mib / sizeof mib[0];
  3384   struct kinfo_proc *procs;
  3385   size_t i;
  3386 
  3387   Lisp_Object proclist = Qnil;
  3388 
  3389   if (sysctl (mib, mibsize, NULL, &len, NULL, 0) != 0 || len == 0)
  3390     return proclist;
  3391 
  3392   procs = xmalloc (len);
  3393   if (sysctl (mib, mibsize, procs, &len, NULL, 0) != 0 || len == 0)
  3394     {
  3395       xfree (procs);
  3396       return proclist;
  3397     }
  3398 
  3399   len /= sizeof procs[0];
  3400   for (i = 0; i < len; i++)
  3401     {
  3402 #ifdef DARWIN_OS
  3403       proclist = Fcons (INT_TO_INTEGER (procs[i].kp_proc.p_pid), proclist);
  3404 #elif defined __OpenBSD__
  3405       proclist = Fcons (INT_TO_INTEGER (procs[i].p_pid), proclist);
  3406 #else
  3407       proclist = Fcons (INT_TO_INTEGER (procs[i].ki_pid), proclist);
  3408 #endif
  3409     }
  3410 
  3411   xfree (procs);
  3412 
  3413   return  proclist;
  3414 }
  3415 
  3416 /* The WINDOWSNT implementation is in w32.c.
  3417    The MSDOS implementation is in dosfns.c.
  3418    The Haiku implementation is in haiku.c.  */
  3419 #elif !defined (WINDOWSNT) && !defined (MSDOS) && !defined (HAIKU)
  3420 
  3421 Lisp_Object
  3422 list_system_processes (void)
  3423 {
  3424   return Qnil;
  3425 }
  3426 
  3427 #endif /* !defined (WINDOWSNT) */
  3428 
  3429 #if (HAVE_GETRUSAGE \
  3430      || defined __FreeBSD__ || defined DARWIN_OS || defined __OpenBSD__)
  3431 
  3432 static Lisp_Object
  3433 make_lisp_s_us (time_t s, long us)
  3434 {
  3435   Lisp_Object sec = make_int (s);
  3436   Lisp_Object usec = make_fixnum (us);
  3437   Lisp_Object hz = make_fixnum (1000000);
  3438   Lisp_Object ticks = CALLN (Fplus, CALLN (Ftimes, sec, hz), usec);
  3439   return Ftime_convert (Fcons (ticks, hz), Qnil);
  3440 }
  3441 
  3442 #endif
  3443 
  3444 #if defined __FreeBSD__ || defined DARWIN_OS
  3445 
  3446 static Lisp_Object
  3447 make_lisp_timeval (struct timeval t)
  3448 {
  3449   return make_lisp_s_us (t.tv_sec, t.tv_usec);
  3450 }
  3451 
  3452 #endif
  3453 
  3454 #if defined (GNU_LINUX) || defined (CYGWIN)
  3455 
  3456 static Lisp_Object
  3457 time_from_jiffies (unsigned long long ticks, Lisp_Object hz, Lisp_Object form)
  3458 {
  3459   return Ftime_convert (Fcons (make_uint (ticks), hz), form);
  3460 }
  3461 
  3462 static Lisp_Object
  3463 put_jiffies (Lisp_Object attrs, Lisp_Object propname,
  3464              unsigned long long ticks, Lisp_Object hz)
  3465 {
  3466   return Fcons (Fcons (propname, time_from_jiffies (ticks, hz, Qnil)), attrs);
  3467 }
  3468 
  3469 static Lisp_Object
  3470 get_up_time (void)
  3471 {
  3472   FILE *fup;
  3473   Lisp_Object up = Qnil;
  3474 
  3475   block_input ();
  3476   fup = emacs_fopen ("/proc/uptime", "r");
  3477 
  3478   if (fup)
  3479     {
  3480       unsigned long long upsec;
  3481       EMACS_UINT upfrac;
  3482       int upfrac_start, upfrac_end;
  3483 
  3484       if (fscanf (fup, "%llu.%n%"pI"u%n",
  3485                   &upsec, &upfrac_start, &upfrac, &upfrac_end)
  3486           == 2)
  3487         {
  3488           EMACS_INT hz = 1;
  3489           for (int i = upfrac_start; i < upfrac_end; i++)
  3490             hz *= 10;
  3491           Lisp_Object sec = make_uint (upsec);
  3492           Lisp_Object subsec = Fcons (make_fixnum (upfrac), make_fixnum (hz));
  3493           up = Ftime_add (sec, subsec);
  3494         }
  3495       fclose (fup);
  3496     }
  3497   unblock_input ();
  3498 
  3499   return up;
  3500 }
  3501 
  3502 # ifdef GNU_LINUX
  3503 #define MAJOR(d) (((unsigned)(d) >> 8) & 0xfff)
  3504 #define MINOR(d) (((unsigned)(d) & 0xff) | (((unsigned)(d) & 0xfff00000) >> 12))
  3505 
  3506 static Lisp_Object
  3507 procfs_ttyname (int rdev)
  3508 {
  3509   FILE *fdev;
  3510   char name[PATH_MAX];
  3511 
  3512   block_input ();
  3513   fdev = emacs_fopen ("/proc/tty/drivers", "r");
  3514   name[0] = 0;
  3515 
  3516   if (fdev)
  3517     {
  3518       unsigned major;
  3519       unsigned long minor_beg, minor_end;
  3520       char minor[25];   /* 2 32-bit numbers + dash */
  3521       char *endp;
  3522 
  3523       for (; !feof (fdev) && !ferror (fdev); name[0] = 0)
  3524         {
  3525           if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3
  3526               && major == MAJOR (rdev))
  3527             {
  3528               minor_beg = strtoul (minor, &endp, 0);
  3529               if (*endp == '\0')
  3530                 minor_end = minor_beg;
  3531               else if (*endp == '-')
  3532                 minor_end = strtoul (endp + 1, &endp, 0);
  3533               else
  3534                 continue;
  3535 
  3536               if (MINOR (rdev) >= minor_beg && MINOR (rdev) <= minor_end)
  3537                 {
  3538                   sprintf (name + strlen (name), "%u", MINOR (rdev));
  3539                   break;
  3540                 }
  3541             }
  3542         }
  3543       fclose (fdev);
  3544     }
  3545   unblock_input ();
  3546   return build_string (name);
  3547 }
  3548 # endif /* GNU_LINUX */
  3549 
  3550 static uintmax_t
  3551 procfs_get_total_memory (void)
  3552 {
  3553   FILE *fmem;
  3554   uintmax_t retval = 2 * 1024 * 1024; /* default: 2 GiB */
  3555   int c;
  3556 
  3557   block_input ();
  3558   fmem = emacs_fopen ("/proc/meminfo", "r");
  3559 
  3560   if (fmem)
  3561     {
  3562       uintmax_t entry_value;
  3563       bool done;
  3564 
  3565       do
  3566         switch (fscanf (fmem, "MemTotal: %"SCNuMAX, &entry_value))
  3567           {
  3568           case 1:
  3569             retval = entry_value;
  3570             done = 1;
  3571             break;
  3572 
  3573           case 0:
  3574             while ((c = getc (fmem)) != EOF && c != '\n')
  3575               continue;
  3576             done = c == EOF;
  3577             break;
  3578 
  3579           default:
  3580             done = 1;
  3581             break;
  3582           }
  3583       while (!done);
  3584 
  3585       fclose (fmem);
  3586     }
  3587   unblock_input ();
  3588   return retval;
  3589 }
  3590 
  3591 Lisp_Object
  3592 system_process_attributes (Lisp_Object pid)
  3593 {
  3594   char procfn[PATH_MAX], fn[PATH_MAX];
  3595   struct stat st;
  3596   struct passwd *pw;
  3597   struct group *gr;
  3598   long clocks_per_sec;
  3599   char *procfn_end;
  3600   char procbuf[1025], *p, *q UNINIT;
  3601   int fd;
  3602   ssize_t nread;
  3603   static char const default_cmd[] = "???";
  3604   const char *cmd = default_cmd;
  3605   int cmdsize = sizeof default_cmd - 1;
  3606   char *cmdline = NULL;
  3607   ptrdiff_t cmdline_size;
  3608   char c;
  3609   intmax_t proc_id;
  3610   int ppid, pgrp, sess, tty, tpgid, thcount;
  3611   uid_t uid;
  3612   gid_t gid;
  3613   unsigned long long u_time, s_time, cutime, cstime, start;
  3614   long priority, niceness, rss;
  3615   unsigned long minflt, majflt, cminflt, cmajflt, vsize;
  3616   double pcpu, pmem;
  3617   Lisp_Object attrs = Qnil;
  3618   Lisp_Object decoded_cmd;
  3619 
  3620   CHECK_NUMBER (pid);
  3621   CONS_TO_INTEGER (pid, pid_t, proc_id);
  3622   sprintf (procfn, "/proc/%"PRIdMAX, proc_id);
  3623   if (stat (procfn, &st) < 0)
  3624     return attrs;
  3625 
  3626   /* euid egid */
  3627   uid = st.st_uid;
  3628   attrs = Fcons (Fcons (Qeuid, INT_TO_INTEGER (uid)), attrs);
  3629   block_input ();
  3630   pw = getpwuid (uid);
  3631   unblock_input ();
  3632   if (pw)
  3633     attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
  3634 
  3635   gid = st.st_gid;
  3636   attrs = Fcons (Fcons (Qegid, INT_TO_INTEGER (gid)), attrs);
  3637   block_input ();
  3638   gr = getgrgid (gid);
  3639   unblock_input ();
  3640   if (gr)
  3641     attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
  3642 
  3643   specpdl_ref count = SPECPDL_INDEX ();
  3644   strcpy (fn, procfn);
  3645   procfn_end = fn + strlen (fn);
  3646   strcpy (procfn_end, "/stat");
  3647   fd = emacs_open (fn, O_RDONLY, 0);
  3648   if (fd < 0)
  3649     nread = 0;
  3650   else
  3651     {
  3652       record_unwind_protect_int (close_file_unwind, fd);
  3653       nread = emacs_read_quit (fd, procbuf, sizeof procbuf - 1);
  3654     }
  3655   if (0 < nread)
  3656     {
  3657       procbuf[nread] = '\0';
  3658       p = procbuf;
  3659 
  3660       p = strchr (p, '(');
  3661       if (p != NULL)
  3662         {
  3663           q = strrchr (p + 1, ')');
  3664           /* comm */
  3665           if (q != NULL)
  3666             {
  3667               cmd = p + 1;
  3668               cmdsize = q - cmd;
  3669             }
  3670         }
  3671       else
  3672         q = NULL;
  3673       /* Command name is encoded in locale-coding-system; decode it.  */
  3674       AUTO_STRING_WITH_LEN (cmd_str, cmd, cmdsize);
  3675       decoded_cmd = code_convert_string_norecord (cmd_str,
  3676                                                   Vlocale_coding_system, 0);
  3677       attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
  3678 
  3679       /* state ppid pgrp sess tty tpgid . minflt cminflt majflt cmajflt
  3680          utime stime cutime cstime priority nice thcount . start vsize rss */
  3681       if (q
  3682           && (sscanf (q + 2, ("%c %d %d %d %d %d %*u %lu %lu %lu %lu "
  3683                               "%llu %llu %llu %llu %ld %ld %d %*d %llu %lu %ld"),
  3684                       &c, &ppid, &pgrp, &sess, &tty, &tpgid,
  3685                       &minflt, &cminflt, &majflt, &cmajflt,
  3686                       &u_time, &s_time, &cutime, &cstime,
  3687                       &priority, &niceness, &thcount, &start, &vsize, &rss)
  3688               == 20))
  3689         {
  3690           char state_str[2];
  3691           state_str[0] = c;
  3692           state_str[1] = '\0';
  3693           attrs = Fcons (Fcons (Qstate, build_string (state_str)), attrs);
  3694           attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (ppid)), attrs);
  3695           attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (pgrp)), attrs);
  3696           attrs = Fcons (Fcons (Qsess, INT_TO_INTEGER (sess)), attrs);
  3697 # ifdef GNU_LINUX
  3698           attrs = Fcons (Fcons (Qttname, procfs_ttyname (tty)), attrs);
  3699 # endif
  3700           attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (tpgid)), attrs);
  3701           attrs = Fcons (Fcons (Qminflt, INT_TO_INTEGER (minflt)), attrs);
  3702           attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (majflt)), attrs);
  3703           attrs = Fcons (Fcons (Qcminflt, INT_TO_INTEGER (cminflt)), attrs);
  3704           attrs = Fcons (Fcons (Qcmajflt, INT_TO_INTEGER (cmajflt)), attrs);
  3705 
  3706           clocks_per_sec = sysconf (_SC_CLK_TCK);
  3707           if (0 < clocks_per_sec)
  3708             {
  3709               Lisp_Object hz = make_int (clocks_per_sec);
  3710               attrs = put_jiffies (attrs, Qutime, u_time, hz);
  3711               attrs = put_jiffies (attrs, Qstime, s_time, hz);
  3712               attrs = put_jiffies (attrs, Qtime, s_time + u_time, hz);
  3713               attrs = put_jiffies (attrs, Qcutime, cutime, hz);
  3714               attrs = put_jiffies (attrs, Qcstime, cstime, hz);
  3715               attrs = put_jiffies (attrs, Qctime, cstime + cutime, hz);
  3716 
  3717               Lisp_Object uptime = get_up_time ();
  3718               if (!NILP (uptime))
  3719                 {
  3720                   Lisp_Object now = Ftime_convert (Qnil, hz);
  3721                   Lisp_Object boot = Ftime_subtract (now, uptime);
  3722                   Lisp_Object tstart = time_from_jiffies (start, hz, hz);
  3723                   Lisp_Object lstart =
  3724                     Ftime_convert (Ftime_add (boot, tstart), Qnil);
  3725                   attrs = Fcons (Fcons (Qstart, lstart), attrs);
  3726                   Lisp_Object etime =
  3727                     Ftime_convert (Ftime_subtract (uptime, tstart), Qnil);
  3728                   attrs = Fcons (Fcons (Qetime, etime), attrs);
  3729                   pcpu = (100.0 * (s_time + u_time)
  3730                           / (clocks_per_sec * float_time (etime)));
  3731                   attrs = Fcons (Fcons (Qpcpu, make_float (pcpu)), attrs);
  3732                 }
  3733             }
  3734 
  3735           attrs = Fcons (Fcons (Qpri, make_fixnum (priority)), attrs);
  3736           attrs = Fcons (Fcons (Qnice, make_fixnum (niceness)), attrs);
  3737           attrs = Fcons (Fcons (Qthcount, INT_TO_INTEGER (thcount)), attrs);
  3738           attrs = Fcons (Fcons (Qvsize, INT_TO_INTEGER (vsize / 1024)), attrs);
  3739           attrs = Fcons (Fcons (Qrss, INT_TO_INTEGER (4 * rss)), attrs);
  3740           pmem = 4.0 * 100 * rss / procfs_get_total_memory ();
  3741           if (pmem > 100)
  3742             pmem = 100;
  3743           attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs);
  3744         }
  3745     }
  3746   unbind_to (count, Qnil);
  3747 
  3748 # ifdef CYGWIN
  3749   /* ttname */
  3750   strcpy (procfn_end, "/ctty");
  3751   fd = emacs_open (fn, O_RDONLY, 0);
  3752   if (fd < 0)
  3753     nread = 0;
  3754   else
  3755     {
  3756       record_unwind_protect_int (close_file_unwind, fd);
  3757       nread = emacs_read_quit (fd, procbuf, sizeof procbuf);
  3758     }
  3759   /* /proc/<pid>/ctty should always end in newline. */
  3760   if (0 < nread && procbuf[nread - 1] == '\n')
  3761     procbuf[nread - 1] = '\0';
  3762   else
  3763     procbuf[0] = '\0';
  3764   attrs = Fcons (Fcons (Qttname, build_string (procbuf)), attrs);
  3765   unbind_to (count, Qnil);
  3766 # endif /* CYGWIN */
  3767 
  3768   /* args */
  3769   strcpy (procfn_end, "/cmdline");
  3770   fd = emacs_open (fn, O_RDONLY, 0);
  3771   if (fd >= 0)
  3772     {
  3773       ptrdiff_t readsize, nread_incr;
  3774       record_unwind_protect_int (close_file_unwind, fd);
  3775       record_unwind_protect_nothing ();
  3776       nread = cmdline_size = 0;
  3777 
  3778       do
  3779         {
  3780           cmdline = xpalloc (cmdline, &cmdline_size, 2, STRING_BYTES_BOUND, 1);
  3781           set_unwind_protect_ptr (specpdl_ref_add (count, 1), xfree, cmdline);
  3782 
  3783           /* Leave room even if every byte needs escaping below.  */
  3784           readsize = (cmdline_size >> 1) - nread;
  3785 
  3786           nread_incr = emacs_read_quit (fd, cmdline + nread, readsize);
  3787           nread += max (0, nread_incr);
  3788         }
  3789       while (nread_incr == readsize);
  3790 
  3791       if (nread)
  3792         {
  3793           /* We don't want trailing null characters.  */
  3794           for (p = cmdline + nread; cmdline < p && !p[-1]; p--)
  3795             continue;
  3796 
  3797           /* Escape-quote whitespace and backslashes.  */
  3798           q = cmdline + cmdline_size;
  3799           while (cmdline < p)
  3800             {
  3801               char c = *--p;
  3802               *--q = c ? c : ' ';
  3803               if (c_isspace (c) || c == '\\')
  3804                 *--q = '\\';
  3805             }
  3806 
  3807           nread = cmdline + cmdline_size - q;
  3808         }
  3809 
  3810       if (!nread)
  3811         {
  3812           nread = cmdsize + 2;
  3813           cmdline_size = nread + 1;
  3814           q = cmdline = xrealloc (cmdline, cmdline_size);
  3815           set_unwind_protect_ptr (specpdl_ref_add (count, 1), xfree, cmdline);
  3816           sprintf (cmdline, "[%.*s]", cmdsize, cmd);
  3817         }
  3818       /* Command line is encoded in locale-coding-system; decode it.  */
  3819       AUTO_STRING_WITH_LEN (cmd_str, q, nread);
  3820       decoded_cmd = code_convert_string_norecord (cmd_str,
  3821                                                   Vlocale_coding_system, 0);
  3822       unbind_to (count, Qnil);
  3823       attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
  3824     }
  3825 
  3826   return attrs;
  3827 }
  3828 
  3829 #elif defined (SOLARIS2) && defined (HAVE_PROCFS)
  3830 
  3831 /* The <procfs.h> header does not like to be included if _LP64 is defined and
  3832    __FILE_OFFSET_BITS == 64.  This is an ugly workaround that.  */
  3833 #if !defined (_LP64) && defined (_FILE_OFFSET_BITS) &&  (_FILE_OFFSET_BITS  ==  64)
  3834 #define PROCFS_FILE_OFFSET_BITS_HACK 1
  3835 #undef _FILE_OFFSET_BITS
  3836 #else
  3837 #define PROCFS_FILE_OFFSET_BITS_HACK 0
  3838 #endif
  3839 
  3840 #include <procfs.h>
  3841 
  3842 #if PROCFS_FILE_OFFSET_BITS_HACK ==  1
  3843 #define _FILE_OFFSET_BITS 64
  3844 #ifdef _FILE_OFFSET_BITS /* Avoid unused-macro warnings.  */
  3845 #endif
  3846 #endif /* PROCFS_FILE_OFFSET_BITS_HACK ==  1 */
  3847 
  3848 Lisp_Object
  3849 system_process_attributes (Lisp_Object pid)
  3850 {
  3851   char procfn[PATH_MAX], fn[PATH_MAX];
  3852   struct stat st;
  3853   struct passwd *pw;
  3854   struct group *gr;
  3855   char *procfn_end;
  3856   struct psinfo pinfo;
  3857   int fd;
  3858   ssize_t nread;
  3859   intmax_t proc_id;
  3860   uid_t uid;
  3861   gid_t gid;
  3862   Lisp_Object attrs = Qnil;
  3863   Lisp_Object decoded_cmd;
  3864 
  3865   CHECK_NUMBER (pid);
  3866   CONS_TO_INTEGER (pid, pid_t, proc_id);
  3867   sprintf (procfn, "/proc/%"PRIdMAX, proc_id);
  3868   if (stat (procfn, &st) < 0)
  3869     return attrs;
  3870 
  3871   /* euid egid */
  3872   uid = st.st_uid;
  3873   attrs = Fcons (Fcons (Qeuid, INT_TO_INTEGER (uid)), attrs);
  3874   block_input ();
  3875   pw = getpwuid (uid);
  3876   unblock_input ();
  3877   if (pw)
  3878     attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
  3879 
  3880   gid = st.st_gid;
  3881   attrs = Fcons (Fcons (Qegid, INT_TO_INTEGER (gid)), attrs);
  3882   block_input ();
  3883   gr = getgrgid (gid);
  3884   unblock_input ();
  3885   if (gr)
  3886     attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
  3887 
  3888   specpdl_ref count = SPECPDL_INDEX ();
  3889   strcpy (fn, procfn);
  3890   procfn_end = fn + strlen (fn);
  3891   strcpy (procfn_end, "/psinfo");
  3892   fd = emacs_open (fn, O_RDONLY, 0);
  3893   if (fd < 0)
  3894     nread = 0;
  3895   else
  3896     {
  3897       record_unwind_protect_int (close_file_unwind, fd);
  3898       nread = emacs_read_quit (fd, &pinfo, sizeof pinfo);
  3899     }
  3900 
  3901   if (nread == sizeof pinfo)
  3902     {
  3903       attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (pinfo.pr_ppid)), attrs);
  3904       attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (pinfo.pr_pgid)), attrs);
  3905       attrs = Fcons (Fcons (Qsess, INT_TO_INTEGER (pinfo.pr_sid)), attrs);
  3906 
  3907       {
  3908         char state_str[2];
  3909         state_str[0] = pinfo.pr_lwp.pr_sname;
  3910         state_str[1] = '\0';
  3911         attrs = Fcons (Fcons (Qstate, build_string (state_str)), attrs);
  3912       }
  3913 
  3914       /* FIXME: missing Qttyname. psinfo.pr_ttydev is a dev_t,
  3915          need to get a string from it. */
  3916 
  3917       /* FIXME: missing: Qtpgid */
  3918 
  3919       /* FIXME: missing:
  3920             Qminflt
  3921             Qmajflt
  3922             Qcminflt
  3923             Qcmajflt
  3924 
  3925             Qutime
  3926             Qcutime
  3927             Qstime
  3928             Qcstime
  3929             Are they available? */
  3930 
  3931       attrs = Fcons (Fcons (Qtime, make_lisp_time (pinfo.pr_time)), attrs);
  3932       attrs = Fcons (Fcons (Qctime, make_lisp_time (pinfo.pr_ctime)), attrs);
  3933       attrs = Fcons (Fcons (Qpri, make_fixnum (pinfo.pr_lwp.pr_pri)), attrs);
  3934       attrs = Fcons (Fcons (Qnice, make_fixnum (pinfo.pr_lwp.pr_nice)), attrs);
  3935       attrs = Fcons (Fcons (Qthcount, INT_TO_INTEGER (pinfo.pr_nlwp)), attrs);
  3936 
  3937       attrs = Fcons (Fcons (Qstart, make_lisp_time (pinfo.pr_start)), attrs);
  3938       attrs = Fcons (Fcons (Qvsize, INT_TO_INTEGER (pinfo.pr_size)), attrs);
  3939       attrs = Fcons (Fcons (Qrss, INT_TO_INTEGER (pinfo.pr_rssize)), attrs);
  3940 
  3941       /* pr_pctcpu and pr_pctmem are unsigned integers in the
  3942          range 0 .. 2**15, representing 0.0 .. 1.0.  */
  3943       attrs = Fcons (Fcons (Qpcpu,
  3944                             make_float (100.0 / 0x8000 * pinfo.pr_pctcpu)),
  3945                      attrs);
  3946       attrs = Fcons (Fcons (Qpmem,
  3947                             make_float (100.0 / 0x8000 * pinfo.pr_pctmem)),
  3948                      attrs);
  3949 
  3950       AUTO_STRING (fname, pinfo.pr_fname);
  3951       decoded_cmd = code_convert_string_norecord (fname,
  3952                                                   Vlocale_coding_system, 0);
  3953       attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
  3954       AUTO_STRING (psargs, pinfo.pr_psargs);
  3955       decoded_cmd = code_convert_string_norecord (psargs,
  3956                                                   Vlocale_coding_system, 0);
  3957       attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
  3958     }
  3959   return unbind_to (count, attrs);
  3960 }
  3961 
  3962 #elif defined __FreeBSD__
  3963 
  3964 Lisp_Object
  3965 system_process_attributes (Lisp_Object pid)
  3966 {
  3967   int proc_id;
  3968   int pagesize = getpagesize ();
  3969   unsigned long npages;
  3970   int fscale;
  3971   struct passwd *pw;
  3972   struct group  *gr;
  3973   char *ttyname;
  3974   size_t len;
  3975   char args[MAXPATHLEN];
  3976 
  3977   int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID};
  3978   struct kinfo_proc proc;
  3979   size_t proclen = sizeof proc;
  3980 
  3981   Lisp_Object attrs = Qnil;
  3982   Lisp_Object decoded_comm;
  3983 
  3984   CHECK_NUMBER (pid);
  3985   CONS_TO_INTEGER (pid, int, proc_id);
  3986   mib[3] = proc_id;
  3987 
  3988   if (sysctl (mib, 4, &proc, &proclen, NULL, 0) != 0 || proclen == 0)
  3989     return attrs;
  3990 
  3991   attrs = Fcons (Fcons (Qeuid, INT_TO_INTEGER (proc.ki_uid)), attrs);
  3992 
  3993   block_input ();
  3994   pw = getpwuid (proc.ki_uid);
  3995   unblock_input ();
  3996   if (pw)
  3997     attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
  3998 
  3999   attrs = Fcons (Fcons (Qegid, INT_TO_INTEGER (proc.ki_svgid)), attrs);
  4000 
  4001   block_input ();
  4002   gr = getgrgid (proc.ki_svgid);
  4003   unblock_input ();
  4004   if (gr)
  4005     attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
  4006 
  4007   AUTO_STRING (comm, proc.ki_comm);
  4008   decoded_comm = code_convert_string_norecord (comm, Vlocale_coding_system, 0);
  4009 
  4010   attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs);
  4011   {
  4012     char state[2] = {'\0', '\0'};
  4013     switch (proc.ki_stat)
  4014       {
  4015       case SRUN:
  4016         state[0] = 'R';
  4017         break;
  4018 
  4019       case SSLEEP:
  4020         state[0] = 'S';
  4021         break;
  4022 
  4023       case SLOCK:
  4024         state[0] = 'D';
  4025         break;
  4026 
  4027       case SZOMB:
  4028         state[0] = 'Z';
  4029         break;
  4030 
  4031       case SSTOP:
  4032         state[0] = 'T';
  4033         break;
  4034       }
  4035     attrs = Fcons (Fcons (Qstate, build_string (state)), attrs);
  4036   }
  4037 
  4038   attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (proc.ki_ppid)), attrs);
  4039   attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (proc.ki_pgid)), attrs);
  4040   attrs = Fcons (Fcons (Qsess, INT_TO_INTEGER (proc.ki_sid)),  attrs);
  4041 
  4042   block_input ();
  4043   ttyname = proc.ki_tdev == NODEV ? NULL : devname (proc.ki_tdev, S_IFCHR);
  4044   unblock_input ();
  4045   if (ttyname)
  4046     attrs = Fcons (Fcons (Qttname, build_string (ttyname)), attrs);
  4047 
  4048   attrs = Fcons (Fcons (Qtpgid,   INT_TO_INTEGER (proc.ki_tpgid)), attrs);
  4049   attrs = Fcons (Fcons (Qminflt,  INT_TO_INTEGER (proc.ki_rusage.ru_minflt)),
  4050                  attrs);
  4051   attrs = Fcons (Fcons (Qmajflt,  INT_TO_INTEGER (proc.ki_rusage.ru_majflt)),
  4052                  attrs);
  4053   attrs = Fcons (Fcons (Qcminflt, make_fixnum (proc.ki_rusage_ch.ru_minflt)), attrs);
  4054   attrs = Fcons (Fcons (Qcmajflt, make_fixnum (proc.ki_rusage_ch.ru_majflt)), attrs);
  4055 
  4056   Lisp_Object utime = make_lisp_timeval (proc.ki_rusage.ru_utime);
  4057   attrs = Fcons (Fcons (Qutime, utime), attrs);
  4058   Lisp_Object stime = make_lisp_timeval (proc.ki_rusage.ru_stime);
  4059   attrs = Fcons (Fcons (Qstime, stime), attrs);
  4060   attrs = Fcons (Fcons (Qtime, Ftime_add (utime, stime)), attrs);
  4061 
  4062   Lisp_Object cutime = make_lisp_timeval (proc.ki_rusage_ch.ru_utime);
  4063   attrs = Fcons (Fcons (Qcutime, cutime), attrs);
  4064   Lisp_Object cstime = make_lisp_timeval (proc.ki_rusage_ch.ru_stime);
  4065   attrs = Fcons (Fcons (Qcstime, cstime), attrs);
  4066   attrs = Fcons (Fcons (Qctime, Ftime_add (cutime, cstime)), attrs);
  4067 
  4068   attrs = Fcons (Fcons (Qthcount, INT_TO_INTEGER (proc.ki_numthreads)), attrs);
  4069   attrs = Fcons (Fcons (Qpri,   make_fixnum (proc.ki_pri.pri_native)), attrs);
  4070   attrs = Fcons (Fcons (Qnice,  make_fixnum (proc.ki_nice)), attrs);
  4071   Lisp_Object start = make_lisp_timeval (proc.ki_start);
  4072   attrs = Fcons (Fcons (Qstart, start), attrs);
  4073   attrs = Fcons (Fcons (Qvsize, make_fixnum (proc.ki_size >> 10)), attrs);
  4074   attrs = Fcons (Fcons (Qrss,   make_fixnum (proc.ki_rssize * pagesize >> 10)),
  4075                  attrs);
  4076 
  4077   Lisp_Object now = Ftime_convert (Qnil, make_fixnum (1000000));
  4078   Lisp_Object etime = Ftime_convert (Ftime_subtract (now, start), Qnil);
  4079   attrs = Fcons (Fcons (Qetime, etime), attrs);
  4080 
  4081   len = sizeof fscale;
  4082   if (sysctlbyname ("kern.fscale", &fscale, &len, NULL, 0) == 0)
  4083     {
  4084       double pcpu;
  4085       fixpt_t ccpu;
  4086       len = sizeof ccpu;
  4087       if (sysctlbyname ("kern.ccpu", &ccpu, &len, NULL, 0) == 0)
  4088         {
  4089           pcpu = (100.0 * proc.ki_pctcpu / fscale
  4090                   / (1 - exp (proc.ki_swtime * log ((double) ccpu / fscale))));
  4091           attrs = Fcons (Fcons (Qpcpu, INT_TO_INTEGER (pcpu)), attrs);
  4092         }
  4093     }
  4094 
  4095   len = sizeof npages;
  4096   if (sysctlbyname ("hw.availpages", &npages, &len, NULL, 0) == 0)
  4097     {
  4098       double pmem = (proc.ki_flag & P_INMEM
  4099                      ? 100.0 * proc.ki_rssize / npages
  4100                      : 0);
  4101       attrs = Fcons (Fcons (Qpmem, INT_TO_INTEGER (pmem)), attrs);
  4102     }
  4103 
  4104   mib[2] = KERN_PROC_ARGS;
  4105   len = MAXPATHLEN;
  4106   if (sysctl (mib, 4, args, &len, NULL, 0) == 0 && len != 0)
  4107     {
  4108       int i;
  4109       for (i = 0; i < len; i++)
  4110         {
  4111           if (! args[i] && i < len - 1)
  4112             args[i] = ' ';
  4113         }
  4114 
  4115       AUTO_STRING (comm, args);
  4116       decoded_comm = code_convert_string_norecord (comm,
  4117                                                    Vlocale_coding_system, 0);
  4118 
  4119       attrs = Fcons (Fcons (Qargs, decoded_comm), attrs);
  4120     }
  4121 
  4122   return attrs;
  4123 }
  4124 
  4125 #elif defined __OpenBSD__
  4126 
  4127 Lisp_Object
  4128 system_process_attributes (Lisp_Object pid)
  4129 {
  4130   int proc_id, fscale, i;
  4131   int pagesize = getpagesize ();
  4132   int mib[6];
  4133   size_t len;
  4134   double pct;
  4135   char *ttyname, args[ARG_MAX];
  4136   struct kinfo_proc proc;
  4137   struct passwd *pw;
  4138   struct group *gr;
  4139   struct uvmexp uvmexp;
  4140 
  4141   Lisp_Object attrs = Qnil;
  4142   Lisp_Object decoded_comm;
  4143 
  4144   CHECK_NUMBER (pid);
  4145   CONS_TO_INTEGER (pid, int, proc_id);
  4146 
  4147   len = sizeof proc;
  4148   mib[0] = CTL_KERN;
  4149   mib[1] = KERN_PROC;
  4150   mib[2] = KERN_PROC_PID;
  4151   mib[3] = proc_id;
  4152   mib[4] = len;
  4153   mib[5] = 1;
  4154   if (sysctl (mib, 6, &proc, &len, NULL, 0) != 0)
  4155     return attrs;
  4156 
  4157   attrs = Fcons (Fcons (Qeuid, INT_TO_INTEGER (proc.p_uid)), attrs);
  4158 
  4159   block_input ();
  4160   pw = getpwuid (proc.p_uid);
  4161   unblock_input ();
  4162   if (pw)
  4163     attrs = Fcons (Fcons (Quser, build_string(pw->pw_name)), attrs);
  4164 
  4165   attrs = Fcons (Fcons (Qegid, INT_TO_INTEGER(proc.p_svgid)), attrs);
  4166 
  4167   block_input ();
  4168   gr = getgrgid (proc.p_svgid);
  4169   unblock_input ();
  4170   if (gr)
  4171     attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
  4172 
  4173   AUTO_STRING (comm, proc.p_comm);
  4174   decoded_comm = code_convert_string_norecord (comm, Vlocale_coding_system, 0);
  4175   attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs);
  4176 
  4177   {
  4178     char state[2] = {'\0', '\0'};
  4179     switch (proc.p_stat) {
  4180     case SIDL:
  4181       state[0] = 'I';
  4182       break;
  4183     case SRUN:
  4184       state[0] = 'R';
  4185       break;
  4186     case SSLEEP:
  4187       state[0] = 'S';
  4188       break;
  4189     case SSTOP:
  4190       state[0] = 'T';
  4191       break;
  4192     case SZOMB:
  4193       state[0] = 'Z';
  4194       break;
  4195     case SDEAD:
  4196       state[0] = 'D';
  4197       break;
  4198     }
  4199     attrs = Fcons (Fcons (Qstate, build_string (state)), attrs);
  4200   }
  4201 
  4202   attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (proc.p_ppid)), attrs);
  4203   attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (proc.p_gid)), attrs);
  4204   attrs = Fcons (Fcons (Qsess, INT_TO_INTEGER (proc.p_sid)),  attrs);
  4205 
  4206   block_input ();
  4207   ttyname = proc.p_tdev == NODEV ? NULL : devname (proc.p_tdev, S_IFCHR);
  4208   unblock_input ();
  4209   if (ttyname)
  4210     attrs = Fcons (Fcons (Qttname, build_string (ttyname)), attrs);
  4211 
  4212   attrs = Fcons (Fcons (Qtpgid,   INT_TO_INTEGER (proc.p_tpgid)), attrs);
  4213   attrs = Fcons (Fcons (Qminflt,  INT_TO_INTEGER (proc.p_uru_minflt)),
  4214                  attrs);
  4215   attrs = Fcons (Fcons (Qmajflt,  INT_TO_INTEGER (proc.p_uru_majflt)),
  4216                  attrs);
  4217 
  4218   /* FIXME: missing cminflt, cmajflt. */
  4219 
  4220   Lisp_Object utime = make_lisp_s_us (proc.p_uutime_sec, proc.p_uutime_usec);
  4221   attrs = Fcons (Fcons (Qutime, utime), attrs);
  4222   Lisp_Object stime = make_lisp_s_us (proc.p_ustime_sec, proc.p_ustime_usec);
  4223   attrs = Fcons (Fcons (Qstime, stime), attrs);
  4224   attrs = Fcons (Fcons (Qtime, Ftime_add (utime, stime)), attrs);
  4225 
  4226   attrs = Fcons (Fcons (Qcutime, make_lisp_s_us (proc.p_uctime_sec,
  4227                                                  proc.p_uctime_usec)),
  4228                  attrs);
  4229 
  4230   /* FIXME: missing cstime and thus ctime. */
  4231 
  4232   attrs = Fcons (Fcons (Qpri,   make_fixnum (proc.p_priority)), attrs);
  4233   attrs = Fcons (Fcons (Qnice,  make_fixnum (proc.p_nice)), attrs);
  4234 
  4235   /* FIXME: missing thcount (thread count) */
  4236 
  4237   attrs = Fcons (Fcons (Qstart, make_lisp_s_us (proc.p_ustart_sec,
  4238                                                 proc.p_ustart_usec)),
  4239                  attrs);
  4240 
  4241   len = (proc.p_vm_tsize + proc.p_vm_dsize + proc.p_vm_ssize) * pagesize >> 10;
  4242   attrs = Fcons (Fcons (Qvsize, make_fixnum (len)), attrs);
  4243 
  4244   attrs = Fcons (Fcons (Qrss,   make_fixnum (proc.p_vm_rssize * pagesize >> 10)),
  4245                  attrs);
  4246 
  4247   Lisp_Object now = Ftime_convert (Qnil, make_fixnum (1000000));
  4248   Lisp_Object start = make_lisp_s_us (proc.p_ustart_sec,
  4249                                       proc.p_ustart_usec);
  4250   Lisp_Object etime = Ftime_convert (Ftime_subtract (now, start), Qnil);
  4251   attrs = Fcons (Fcons (Qetime, etime), attrs);
  4252 
  4253   len = sizeof (fscale);
  4254   mib[0] = CTL_KERN;
  4255   mib[1] = KERN_FSCALE;
  4256   if (sysctl (mib, 2, &fscale, &len, NULL, 0) != -1)
  4257     {
  4258       pct = (double)proc.p_pctcpu / fscale * 100.0;
  4259       attrs = Fcons (Fcons (Qpcpu, make_float (pct)), attrs);
  4260     }
  4261 
  4262   len = sizeof (uvmexp);
  4263   mib[0] = CTL_VM;
  4264   mib[1] = VM_UVMEXP;
  4265   if (sysctl (mib, 2, &uvmexp, &len, NULL, 0) != -1)
  4266     {
  4267       pct = (100.0 * (double)proc.p_vm_rssize / uvmexp.npages);
  4268       attrs = Fcons (Fcons (Qpmem, make_float (pct)), attrs);
  4269     }
  4270 
  4271   len = sizeof args;
  4272   mib[0] = CTL_KERN;
  4273   mib[1] = KERN_PROC_ARGS;
  4274   mib[2] = proc_id;
  4275   mib[3] = KERN_PROC_ARGV;
  4276   if (sysctl (mib, 4, &args, &len, NULL, 0) == 0 && len != 0)
  4277     {
  4278       char **argv = (char**)args;
  4279 
  4280       /* concatenate argv reusing the existing storage storage.
  4281          sysctl(8) guarantees that "the buffer pointed to by oldp is
  4282          filled with an array of char pointers followed by the strings
  4283          themselves." */
  4284       for (i = 0; argv[i] != NULL; ++i)
  4285         {
  4286           if (argv[i+1] != NULL)
  4287             {
  4288               len = strlen (argv[i]);
  4289               argv[i][len] = ' ';
  4290             }
  4291         }
  4292 
  4293       AUTO_STRING (comm, *argv);
  4294       decoded_comm = code_convert_string_norecord (comm,
  4295                                                    Vlocale_coding_system, 0);
  4296       attrs = Fcons (Fcons (Qargs, decoded_comm), attrs);
  4297     }
  4298 
  4299   return attrs;
  4300 }
  4301 
  4302 #elif defined DARWIN_OS
  4303 
  4304 #define HAVE_RUSAGE_INFO_CURRENT (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101000)
  4305 #define HAVE_PROC_PIDINFO (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)
  4306 
  4307 Lisp_Object
  4308 system_process_attributes (Lisp_Object pid)
  4309 {
  4310   int proc_id, i;
  4311   struct passwd *pw;
  4312   struct group  *gr;
  4313   char *ttyname;
  4314   struct timeval starttime;
  4315   dev_t tdev;
  4316   uid_t uid;
  4317   gid_t gid;
  4318 
  4319   int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID};
  4320   struct kinfo_proc proc;
  4321   size_t len = sizeof proc;
  4322 
  4323   Lisp_Object attrs = Qnil;
  4324   Lisp_Object decoded_comm;
  4325 
  4326   CHECK_NUMBER (pid);
  4327   CONS_TO_INTEGER (pid, int, proc_id);
  4328   mib[3] = proc_id;
  4329 
  4330   if (sysctl (mib, 4, &proc, &len, NULL, 0) != 0 || len == 0)
  4331     return attrs;
  4332 
  4333   uid = proc.kp_eproc.e_ucred.cr_uid;
  4334   attrs = Fcons (Fcons (Qeuid, INT_TO_INTEGER (uid)), attrs);
  4335 
  4336   block_input ();
  4337   pw = getpwuid (uid);
  4338   unblock_input ();
  4339   if (pw)
  4340     attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
  4341 
  4342   gid = proc.kp_eproc.e_pcred.p_svgid;
  4343   attrs = Fcons (Fcons (Qegid, INT_TO_INTEGER (gid)), attrs);
  4344 
  4345   block_input ();
  4346   gr = getgrgid (gid);
  4347   unblock_input ();
  4348   if (gr)
  4349     attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
  4350 
  4351   char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
  4352   char *comm;
  4353 
  4354   if (proc_pidpath (proc_id, pathbuf, sizeof(pathbuf)) > 0)
  4355     {
  4356       if ((comm = strrchr (pathbuf, '/')))
  4357         comm++;
  4358       else
  4359         comm = pathbuf;
  4360     }
  4361   else
  4362     comm = proc.kp_proc.p_comm;
  4363 
  4364   decoded_comm = (code_convert_string_norecord
  4365                   (build_unibyte_string (comm),
  4366                    Vlocale_coding_system, 0));
  4367   attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs);
  4368 
  4369   {
  4370     char state[2] = {'\0', '\0'};
  4371     switch (proc.kp_proc.p_stat)
  4372       {
  4373       case SRUN:
  4374         state[0] = 'R';
  4375         break;
  4376 
  4377       case SSLEEP:
  4378         state[0] = 'S';
  4379         break;
  4380 
  4381       case SZOMB:
  4382         state[0] = 'Z';
  4383         break;
  4384 
  4385       case SSTOP:
  4386         state[0] = 'T';
  4387         break;
  4388 
  4389       case SIDL:
  4390         state[0] = 'I';
  4391         break;
  4392       }
  4393     attrs = Fcons (Fcons (Qstate, build_string (state)), attrs);
  4394   }
  4395 
  4396   attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (proc.kp_eproc.e_ppid)), attrs);
  4397   attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (proc.kp_eproc.e_pgid)), attrs);
  4398 
  4399   tdev = proc.kp_eproc.e_tdev;
  4400   block_input ();
  4401   ttyname = tdev == NODEV ? NULL : devname (tdev, S_IFCHR);
  4402   unblock_input ();
  4403   if (ttyname)
  4404     attrs = Fcons (Fcons (Qttname, build_string (ttyname)), attrs);
  4405 
  4406   attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (proc.kp_eproc.e_tpgid)),
  4407                  attrs);
  4408 
  4409 #if HAVE_RUSAGE_INFO_CURRENT
  4410   rusage_info_current ri;
  4411   if (proc_pid_rusage(proc_id, RUSAGE_INFO_CURRENT, (rusage_info_t *) &ri) == 0)
  4412     {
  4413       struct timespec utime = make_timespec (ri.ri_user_time / TIMESPEC_HZ,
  4414                                              ri.ri_user_time % TIMESPEC_HZ);
  4415       struct timespec stime = make_timespec (ri.ri_system_time / TIMESPEC_HZ,
  4416                                              ri.ri_system_time % TIMESPEC_HZ);
  4417       attrs = Fcons (Fcons (Qutime, make_lisp_time (utime)), attrs);
  4418       attrs = Fcons (Fcons (Qstime, make_lisp_time (stime)), attrs);
  4419       attrs = Fcons (Fcons (Qtime, make_lisp_time (timespec_add (utime, stime))), attrs);
  4420 
  4421       attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (ri.ri_pageins)), attrs);
  4422   }
  4423 #else  /* !HAVE_RUSAGE_INFO_CURRENT */
  4424   struct rusage *rusage = proc.kp_proc.p_ru;
  4425   if (rusage)
  4426     {
  4427       attrs = Fcons (Fcons (Qminflt, INT_TO_INTEGER (rusage->ru_minflt)),
  4428                      attrs);
  4429       attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (rusage->ru_majflt)),
  4430                      attrs);
  4431 
  4432       Lisp_Object utime = make_lisp_timeval (rusage->ru_utime);
  4433       Lisp_Object stime = make_lisp_timeval (rusage->ru_stime);
  4434       attrs = Fcons (Fcons (Qutime, utime), attrs);
  4435       attrs = Fcons (Fcons (Qstime, stime), attrs);
  4436       attrs = Fcons (Fcons (Qtime, Ftime_add (utime, stime)), attrs);
  4437     }
  4438 #endif  /* !HAVE_RUSAGE_INFO_CURRENT */
  4439 
  4440   starttime = proc.kp_proc.p_starttime;
  4441   attrs = Fcons (Fcons (Qnice,  make_fixnum (proc.kp_proc.p_nice)), attrs);
  4442   Lisp_Object start = make_lisp_timeval (starttime);
  4443   attrs = Fcons (Fcons (Qstart, start), attrs);
  4444 
  4445   Lisp_Object now = Ftime_convert (Qnil, make_fixnum (1000000));
  4446   Lisp_Object etime = Ftime_convert (Ftime_subtract (now, start), Qnil);
  4447   attrs = Fcons (Fcons (Qetime, etime), attrs);
  4448 
  4449 #if HAVE_PROC_PIDINFO
  4450   struct proc_taskinfo taskinfo;
  4451   if (proc_pidinfo (proc_id, PROC_PIDTASKINFO, 0, &taskinfo, sizeof (taskinfo)) > 0)
  4452     {
  4453       attrs = Fcons (Fcons (Qvsize, make_fixnum (taskinfo.pti_virtual_size / 1024)), attrs);
  4454       attrs = Fcons (Fcons (Qrss, make_fixnum (taskinfo.pti_resident_size / 1024)), attrs);
  4455       attrs = Fcons (Fcons (Qthcount, make_fixnum (taskinfo.pti_threadnum)), attrs);
  4456     }
  4457 #endif  /* HAVE_PROC_PIDINFO */
  4458 
  4459 #ifdef KERN_PROCARGS2
  4460   char args[ARG_MAX];
  4461   mib[1] = KERN_PROCARGS2;
  4462   mib[2] = proc_id;
  4463   len = sizeof args;
  4464 
  4465   if (sysctl (mib, 3, &args, &len, NULL, 0) == 0 && len != 0)
  4466     {
  4467       char *start, *end;
  4468 
  4469       int argc = *(int*)args; /* argc is the first int */
  4470       start = args + sizeof (int);
  4471 
  4472       start += strlen (start) + 1; /* skip executable name and any '\0's */
  4473       while ((start - args < len) && ! *start) start++;
  4474 
  4475       /* skip argv to find real end */
  4476       for (i = 0, end = start; i < argc && (end - args) < len; i++)
  4477         {
  4478           end += strlen (end) + 1;
  4479         }
  4480 
  4481       len = end - start;
  4482       for (int i = 0; i < len; i++)
  4483         {
  4484           if (! start[i] && i < len - 1)
  4485             start[i] = ' ';
  4486         }
  4487 
  4488       AUTO_STRING (comm, start);
  4489       decoded_comm = code_convert_string_norecord (comm,
  4490                                                    Vlocale_coding_system, 0);
  4491       attrs = Fcons (Fcons (Qargs, decoded_comm), attrs);
  4492     }
  4493 #endif  /* KERN_PROCARGS2 */
  4494 
  4495   return attrs;
  4496 }
  4497 
  4498 /* The WINDOWSNT implementation is in w32.c.
  4499    The MSDOS implementation is in dosfns.c.
  4500    The HAIKU implementation is in haiku.c.  */
  4501 #elif !defined (WINDOWSNT) && !defined (MSDOS) && !defined (HAIKU)
  4502 
  4503 Lisp_Object
  4504 system_process_attributes (Lisp_Object pid)
  4505 {
  4506   return Qnil;
  4507 }
  4508 
  4509 #endif  /* !defined (WINDOWSNT) */
  4510 
  4511 DEFUN ("get-internal-run-time", Fget_internal_run_time, Sget_internal_run_time,
  4512        0, 0, 0,
  4513        doc: /* Return the current run time used by Emacs.
  4514 The time is returned as in the style of `current-time'.
  4515 
  4516 On systems that can't determine the run time, `get-internal-run-time'
  4517 does the same thing as `current-time'.  */)
  4518   (void)
  4519 {
  4520 #ifdef HAVE_GETRUSAGE
  4521   struct rusage usage;
  4522   time_t secs;
  4523   int usecs;
  4524 
  4525   if (getrusage (RUSAGE_SELF, &usage) < 0)
  4526     /* This shouldn't happen.  What action is appropriate?  */
  4527     xsignal0 (Qerror);
  4528 
  4529   /* Sum up user time and system time.  */
  4530   secs = usage.ru_utime.tv_sec + usage.ru_stime.tv_sec;
  4531   usecs = usage.ru_utime.tv_usec + usage.ru_stime.tv_usec;
  4532   if (usecs >= 1000000)
  4533     {
  4534       usecs -= 1000000;
  4535       secs++;
  4536     }
  4537   return make_lisp_s_us (secs, usecs);
  4538 #else /* ! HAVE_GETRUSAGE  */
  4539 #ifdef WINDOWSNT
  4540   return w32_get_internal_run_time ();
  4541 #else /* ! WINDOWSNT  */
  4542   return Fcurrent_time ();
  4543 #endif /* WINDOWSNT  */
  4544 #endif /* HAVE_GETRUSAGE  */
  4545 }
  4546 
  4547 /* Wide character string collation.  */
  4548 
  4549 #ifdef __STDC_ISO_10646__
  4550 # include <wchar.h>
  4551 # include <wctype.h>
  4552 
  4553 # if defined HAVE_NEWLOCALE || defined HAVE_SETLOCALE
  4554 #  include <locale.h>
  4555 # endif
  4556 # ifndef LC_COLLATE
  4557 #  define LC_COLLATE 0
  4558 # endif
  4559 # ifndef LC_COLLATE_MASK
  4560 #  define LC_COLLATE_MASK 0
  4561 # endif
  4562 # ifndef LC_CTYPE
  4563 #  define LC_CTYPE 0
  4564 # endif
  4565 # ifndef LC_CTYPE_MASK
  4566 #  define LC_CTYPE_MASK 0
  4567 # endif
  4568 
  4569 # ifndef HAVE_NEWLOCALE
  4570 #  undef freelocale
  4571 #  undef locale_t
  4572 #  undef newlocale
  4573 #  undef wcscoll_l
  4574 #  undef towlower_l
  4575 #  define freelocale emacs_freelocale
  4576 #  define locale_t emacs_locale_t
  4577 #  define newlocale emacs_newlocale
  4578 #  define wcscoll_l emacs_wcscoll_l
  4579 #  define towlower_l emacs_towlower_l
  4580 
  4581 typedef char const *locale_t;
  4582 
  4583 static locale_t
  4584 newlocale (int category_mask, char const *locale, locale_t loc)
  4585 {
  4586   return locale;
  4587 }
  4588 
  4589 static void
  4590 freelocale (locale_t loc)
  4591 {
  4592 }
  4593 
  4594 static char *
  4595 emacs_setlocale (int category, char const *locale)
  4596 {
  4597 #  ifdef HAVE_SETLOCALE
  4598   errno = 0;
  4599   char *loc = setlocale (category, locale);
  4600   if (loc || errno)
  4601     return loc;
  4602   errno = EINVAL;
  4603 #  else
  4604   errno = ENOTSUP;
  4605 #  endif
  4606   return 0;
  4607 }
  4608 
  4609 static int
  4610 wcscoll_l (wchar_t const *a, wchar_t const *b, locale_t loc)
  4611 {
  4612   int result = 0;
  4613   char *oldloc = emacs_setlocale (LC_COLLATE, NULL);
  4614   int err;
  4615 
  4616   if (! oldloc)
  4617     err = errno;
  4618   else
  4619     {
  4620       USE_SAFE_ALLOCA;
  4621       char *oldcopy = SAFE_ALLOCA (strlen (oldloc) + 1);
  4622       strcpy (oldcopy, oldloc);
  4623       if (! emacs_setlocale (LC_COLLATE, loc))
  4624         err = errno;
  4625       else
  4626         {
  4627           errno = 0;
  4628           result = wcscoll (a, b);
  4629           err = errno;
  4630           if (! emacs_setlocale (LC_COLLATE, oldcopy))
  4631             err = errno;
  4632         }
  4633       SAFE_FREE ();
  4634     }
  4635 
  4636   errno = err;
  4637   return result;
  4638 }
  4639 
  4640 static wint_t
  4641 towlower_l (wint_t wc, locale_t loc)
  4642 {
  4643   wint_t result = wc;
  4644   char *oldloc = emacs_setlocale (LC_CTYPE, NULL);
  4645 
  4646   if (oldloc)
  4647     {
  4648       USE_SAFE_ALLOCA;
  4649       char *oldcopy = SAFE_ALLOCA (strlen (oldloc) + 1);
  4650       strcpy (oldcopy, oldloc);
  4651       if (emacs_setlocale (LC_CTYPE, loc))
  4652         {
  4653           result = towlower (wc);
  4654           emacs_setlocale (LC_COLLATE, oldcopy);
  4655         }
  4656       SAFE_FREE ();
  4657     }
  4658 
  4659   return result;
  4660 }
  4661 # endif
  4662 
  4663 int
  4664 str_collate (Lisp_Object s1, Lisp_Object s2,
  4665              Lisp_Object locale, Lisp_Object ignore_case)
  4666 {
  4667   int res, err;
  4668   ptrdiff_t len, i, i_byte;
  4669   wchar_t *p1, *p2;
  4670 
  4671   USE_SAFE_ALLOCA;
  4672 
  4673   /* Convert byte stream to code points.  */
  4674   len = SCHARS (s1); i = i_byte = 0;
  4675   SAFE_NALLOCA (p1, 1, len + 1);
  4676   while (i < len)
  4677     {
  4678       wchar_t *p = &p1[i];
  4679       *p = fetch_string_char_advance (s1, &i, &i_byte);
  4680     }
  4681   p1[len] = 0;
  4682 
  4683   len = SCHARS (s2); i = i_byte = 0;
  4684   SAFE_NALLOCA (p2, 1, len + 1);
  4685   while (i < len)
  4686     {
  4687       wchar_t *p = &p2[i];
  4688       *p = fetch_string_char_advance (s2, &i, &i_byte);
  4689     }
  4690   p2[len] = 0;
  4691 
  4692   if (STRINGP (locale))
  4693     {
  4694       locale_t loc = newlocale (LC_COLLATE_MASK | LC_CTYPE_MASK,
  4695                                 SSDATA (locale), 0);
  4696       if (!loc)
  4697         error ("Invalid locale %s: %s", SSDATA (locale), emacs_strerror (errno));
  4698 
  4699       if (! NILP (ignore_case))
  4700         for (int i = 1; i < 3; i++)
  4701           {
  4702             wchar_t *p = (i == 1) ? p1 : p2;
  4703             for (; *p; p++)
  4704               *p = towlower_l (*p, loc);
  4705           }
  4706 
  4707       errno = 0;
  4708       res = wcscoll_l (p1, p2, loc);
  4709       err = errno;
  4710       freelocale (loc);
  4711     }
  4712   else
  4713     {
  4714       if (! NILP (ignore_case))
  4715         for (int i = 1; i < 3; i++)
  4716           {
  4717             wchar_t *p = (i == 1) ? p1 : p2;
  4718             for (; *p; p++)
  4719               *p = towlower (*p);
  4720           }
  4721 
  4722       errno = 0;
  4723       res = wcscoll (p1, p2);
  4724       err = errno;
  4725     }
  4726 #  ifndef HAVE_NEWLOCALE
  4727   if (err)
  4728     error ("Invalid locale or string for collation: %s", emacs_strerror (err));
  4729 #  else
  4730   if (err)
  4731     error ("Invalid string for collation: %s", emacs_strerror (err));
  4732 #  endif
  4733 
  4734   SAFE_FREE ();
  4735   return res;
  4736 }
  4737 #endif  /* __STDC_ISO_10646__ */
  4738 
  4739 #ifdef WINDOWSNT
  4740 int
  4741 str_collate (Lisp_Object s1, Lisp_Object s2,
  4742              Lisp_Object locale, Lisp_Object ignore_case)
  4743 {
  4744 
  4745   char *loc = STRINGP (locale) ? SSDATA (locale) : NULL;
  4746   int res, err = errno;
  4747 
  4748   errno = 0;
  4749   res = w32_compare_strings (SSDATA (s1), SSDATA (s2), loc, !NILP (ignore_case));
  4750   if (errno)
  4751     error ("Invalid string for collation: %s", strerror (errno));
  4752 
  4753   errno = err;
  4754   return res;
  4755 }
  4756 #endif  /* WINDOWSNT */
  4757 
  4758 void
  4759 syms_of_sysdep (void)
  4760 {
  4761   defsubr (&Sget_internal_run_time);
  4762 }

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