aboutsummaryrefslogtreecommitdiffstats
path: root/src/sysdep.c
diff options
context:
space:
mode:
authorEli Zaretskii2013-03-28 20:13:59 +0200
committerEli Zaretskii2013-03-28 20:13:59 +0200
commitd76bf86f438d4f5f9fe493ab76f02ffc78f3ae2e (patch)
tree04fa8bc7bd2058a316a7ee30f8741d25bfd0b060 /src/sysdep.c
parent2ef26ceb192c7683754cf0b4aa3087f501254332 (diff)
parente74aeda863cd6896e06e92586f87b45d63d67d15 (diff)
downloademacs-d76bf86f438d4f5f9fe493ab76f02ffc78f3ae2e.tar.gz
emacs-d76bf86f438d4f5f9fe493ab76f02ffc78f3ae2e.zip
Merge from trunk and resolve conflicts.
Diffstat (limited to 'src/sysdep.c')
-rw-r--r--src/sysdep.c212
1 files changed, 117 insertions, 95 deletions
diff --git a/src/sysdep.c b/src/sysdep.c
index bc4dc91509f..1d3e646d359 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1,6 +1,6 @@
1/* Interfaces to system-dependent kernel and library entries. 1/* Interfaces to system-dependent kernel and library entries.
2 Copyright (C) 1985-1988, 1993-1995, 1999-2012 2 Copyright (C) 1985-1988, 1993-1995, 1999-2013 Free Software
3 Free Software Foundation, Inc. 3 Foundation, Inc.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
6 6
@@ -30,9 +30,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
30#include <limits.h> 30#include <limits.h>
31#include <unistd.h> 31#include <unistd.h>
32 32
33#include <allocator.h>
34#include <c-ctype.h> 33#include <c-ctype.h>
35#include <careadlinkat.h>
36#include <ignore-value.h> 34#include <ignore-value.h>
37#include <utimens.h> 35#include <utimens.h>
38 36
@@ -40,9 +38,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
40#include "sysselect.h" 38#include "sysselect.h"
41#include "blockinput.h" 39#include "blockinput.h"
42 40
43#ifdef BSD_SYSTEM 41#if defined DARWIN_OS || defined __FreeBSD__
44#include <sys/param.h> 42# include <sys/sysctl.h>
45#include <sys/sysctl.h>
46#endif 43#endif
47 44
48#ifdef __FreeBSD__ 45#ifdef __FreeBSD__
@@ -71,9 +68,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
71 68
72#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */ 69#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
73#include "msdos.h" 70#include "msdos.h"
74#include <sys/param.h>
75#endif 71#endif
76 72
73#include <sys/param.h>
77#include <sys/file.h> 74#include <sys/file.h>
78#include <fcntl.h> 75#include <fcntl.h>
79 76
@@ -266,45 +263,74 @@ init_baud_rate (int fd)
266 263
267#ifndef MSDOS 264#ifndef MSDOS
268 265
269static void 266/* Wait for the subprocess with process id CHILD to terminate or change status.
270wait_for_termination_1 (pid_t pid, int interruptible) 267 CHILD must be a child process that has not been reaped.
268 If STATUS is non-null, store the waitpid-style exit status into *STATUS
269 and tell wait_reading_process_output that it needs to look around.
270 Use waitpid-style OPTIONS when waiting.
271 If INTERRUPTIBLE, this function is interruptible by a signal.
272
273 Return CHILD if successful, 0 if no status is available;
274 the latter is possible only when options & NOHANG. */
275static pid_t
276get_child_status (pid_t child, int *status, int options, bool interruptible)
271{ 277{
272 while (1) 278 pid_t pid;
279
280 /* Invoke waitpid only with a known process ID; do not invoke
281 waitpid with a nonpositive argument. Otherwise, Emacs might
282 reap an unwanted process by mistake. For example, invoking
283 waitpid (-1, ...) can mess up glib by reaping glib's subprocesses,
284 so that another thread running glib won't find them. */
285 eassert (child > 0);
286
287 while ((pid = waitpid (child, status, options)) < 0)
273 { 288 {
274 int status; 289 /* Check that CHILD is a child process that has not been reaped,
275 int wait_result = waitpid (pid, &status, 0); 290 and that STATUS and OPTIONS are valid. Otherwise abort,
276 if (wait_result < 0) 291 as continuing after this internal error could cause Emacs to
277 { 292 become confused and kill innocent-victim processes. */
278 if (errno != EINTR) 293 if (errno != EINTR)
279 break; 294 emacs_abort ();
280 }
281 else
282 {
283 record_child_status_change (wait_result, status);
284 break;
285 }
286 295
287 /* Note: the MS-Windows emulation of waitpid calls QUIT 296 /* Note: the MS-Windows emulation of waitpid calls QUIT
288 internally. */ 297 internally. */
289 if (interruptible) 298 if (interruptible)
290 QUIT; 299 QUIT;
291 } 300 }
292}
293 301
294/* Wait for subprocess with process id `pid' to terminate and 302 /* If successful and status is requested, tell wait_reading_process_output
295 make sure it will get eliminated (not remain forever as a zombie) */ 303 that it needs to wake up and look around. */
304 if (pid && status && input_available_clear_time)
305 *input_available_clear_time = make_emacs_time (0, 0);
306
307 return pid;
308}
296 309
310/* Wait for the subprocess with process id CHILD to terminate.
311 CHILD must be a child process that has not been reaped.
312 If STATUS is non-null, store the waitpid-style exit status into *STATUS
313 and tell wait_reading_process_output that it needs to look around.
314 If INTERRUPTIBLE, this function is interruptible by a signal. */
297void 315void
298wait_for_termination (pid_t pid) 316wait_for_termination (pid_t child, int *status, bool interruptible)
299{ 317{
300 wait_for_termination_1 (pid, 0); 318 get_child_status (child, status, 0, interruptible);
301} 319}
302 320
303/* Like the above, but allow keyboard interruption. */ 321/* Report whether the subprocess with process id CHILD has changed status.
304void 322 Termination counts as a change of status.
305interruptible_wait_for_termination (pid_t pid) 323 CHILD must be a child process that has not been reaped.
324 If STATUS is non-null, store the waitpid-style exit status into *STATUS
325 and tell wait_reading_process_output that it needs to look around.
326 Use waitpid-style OPTIONS to check status, but do not wait.
327
328 Return CHILD if successful, 0 if no status is available because
329 the process's state has not changed. */
330pid_t
331child_status_changed (pid_t child, int *status, int options)
306{ 332{
307 wait_for_termination_1 (pid, 1); 333 return get_child_status (child, status, WNOHANG | options, 0);
308} 334}
309 335
310/* 336/*
@@ -428,20 +454,15 @@ static void restore_signal_handlers (struct save_signal *);
428void 454void
429sys_suspend (void) 455sys_suspend (void)
430{ 456{
431#if defined (SIGTSTP) && !defined (MSDOS) 457#ifndef DOS_NT
432 458 kill (0, SIGTSTP);
433 { 459#else
434 pid_t pgrp = getpgrp ();
435 EMACS_KILLPG (pgrp, SIGTSTP);
436 }
437
438#else /* No SIGTSTP */
439/* On a system where suspending is not implemented, 460/* On a system where suspending is not implemented,
440 instead fork a subshell and let it talk directly to the terminal 461 instead fork a subshell and let it talk directly to the terminal
441 while we wait. */ 462 while we wait. */
442 sys_subshell (); 463 sys_subshell ();
443 464
444#endif /* no SIGTSTP */ 465#endif
445} 466}
446 467
447/* Fork a subshell. */ 468/* Fork a subshell. */
@@ -453,7 +474,8 @@ sys_subshell (void)
453 int st; 474 int st;
454 char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS. */ 475 char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS. */
455#endif 476#endif
456 int pid; 477 pid_t pid;
478 int status;
457 struct save_signal saved_handlers[5]; 479 struct save_signal saved_handlers[5];
458 Lisp_Object dir; 480 Lisp_Object dir;
459 unsigned char *volatile str_volatile = 0; 481 unsigned char *volatile str_volatile = 0;
@@ -491,7 +513,6 @@ sys_subshell (void)
491#ifdef DOS_NT 513#ifdef DOS_NT
492 pid = 0; 514 pid = 0;
493 save_signal_handlers (saved_handlers); 515 save_signal_handlers (saved_handlers);
494 synch_process_alive = 1;
495#else 516#else
496 pid = vfork (); 517 pid = vfork ();
497 if (pid == -1) 518 if (pid == -1)
@@ -505,10 +526,10 @@ sys_subshell (void)
505#ifdef DOS_NT /* MW, Aug 1993 */ 526#ifdef DOS_NT /* MW, Aug 1993 */
506 getcwd (oldwd, sizeof oldwd); 527 getcwd (oldwd, sizeof oldwd);
507 if (sh == 0) 528 if (sh == 0)
508 sh = (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */ 529 sh = egetenv ("SUSPEND"); /* KFS, 1994-12-14 */
509#endif 530#endif
510 if (sh == 0) 531 if (sh == 0)
511 sh = (char *) egetenv ("SHELL"); 532 sh = egetenv ("SHELL");
512 if (sh == 0) 533 if (sh == 0)
513 sh = "sh"; 534 sh = "sh";
514 535
@@ -560,14 +581,12 @@ sys_subshell (void)
560 /* Do this now if we did not do it before. */ 581 /* Do this now if we did not do it before. */
561#ifndef MSDOS 582#ifndef MSDOS
562 save_signal_handlers (saved_handlers); 583 save_signal_handlers (saved_handlers);
563 synch_process_alive = 1;
564#endif 584#endif
565 585
566#ifndef DOS_NT 586#ifndef DOS_NT
567 wait_for_termination (pid); 587 wait_for_termination (pid, &status, 0);
568#endif 588#endif
569 restore_signal_handlers (saved_handlers); 589 restore_signal_handlers (saved_handlers);
570 synch_process_alive = 0;
571} 590}
572 591
573static void 592static void
@@ -692,6 +711,27 @@ init_foreground_group (void)
692 inherited_pgroup = getpid () == pgrp ? 0 : pgrp; 711 inherited_pgroup = getpid () == pgrp ? 0 : pgrp;
693} 712}
694 713
714/* Block and unblock SIGTTOU. */
715
716void
717block_tty_out_signal (void)
718{
719#ifdef SIGTTOU
720 sigset_t blocked;
721 sigemptyset (&blocked);
722 sigaddset (&blocked, SIGTTOU);
723 pthread_sigmask (SIG_BLOCK, &blocked, 0);
724#endif
725}
726
727void
728unblock_tty_out_signal (void)
729{
730#ifdef SIGTTOU
731 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
732#endif
733}
734
695/* Safely set a controlling terminal FD's process group to PGID. 735/* Safely set a controlling terminal FD's process group to PGID.
696 If we are not in the foreground already, POSIX requires tcsetpgrp 736 If we are not in the foreground already, POSIX requires tcsetpgrp
697 to deliver a SIGTTOU signal, which would stop us. This is an 737 to deliver a SIGTTOU signal, which would stop us. This is an
@@ -703,11 +743,10 @@ static void
703tcsetpgrp_without_stopping (int fd, pid_t pgid) 743tcsetpgrp_without_stopping (int fd, pid_t pgid)
704{ 744{
705#ifdef SIGTTOU 745#ifdef SIGTTOU
706 signal_handler_t handler;
707 block_input (); 746 block_input ();
708 handler = signal (SIGTTOU, SIG_IGN); 747 block_tty_out_signal ();
709 tcsetpgrp (fd, pgid); 748 tcsetpgrp (fd, pgid);
710 signal (SIGTTOU, handler); 749 unblock_tty_out_signal ();
711 unblock_input (); 750 unblock_input ();
712#endif 751#endif
713} 752}
@@ -1250,10 +1289,9 @@ reset_sys_modes (struct tty_display_info *tty_out)
1250 if (tty_out->terminal->reset_terminal_modes_hook) 1289 if (tty_out->terminal->reset_terminal_modes_hook)
1251 tty_out->terminal->reset_terminal_modes_hook (tty_out->terminal); 1290 tty_out->terminal->reset_terminal_modes_hook (tty_out->terminal);
1252 1291
1253#ifdef BSD_SYSTEM
1254 /* Avoid possible loss of output when changing terminal modes. */ 1292 /* Avoid possible loss of output when changing terminal modes. */
1255 fsync (fileno (tty_out->output)); 1293 while (fdatasync (fileno (tty_out->output)) != 0 && errno == EINTR)
1256#endif 1294 continue;
1257 1295
1258#ifndef DOS_NT 1296#ifndef DOS_NT
1259#ifdef F_SETOWN 1297#ifdef F_SETOWN
@@ -1491,9 +1529,7 @@ emacs_sigaction_init (struct sigaction *action, signal_handler_t handler)
1491 /* When handling a signal, block nonfatal system signals that are caught 1529 /* When handling a signal, block nonfatal system signals that are caught
1492 by Emacs. This makes race conditions less likely. */ 1530 by Emacs. This makes race conditions less likely. */
1493 sigaddset (&action->sa_mask, SIGALRM); 1531 sigaddset (&action->sa_mask, SIGALRM);
1494#ifdef SIGCHLD
1495 sigaddset (&action->sa_mask, SIGCHLD); 1532 sigaddset (&action->sa_mask, SIGCHLD);
1496#endif
1497#ifdef SIGDANGER 1533#ifdef SIGDANGER
1498 sigaddset (&action->sa_mask, SIGDANGER); 1534 sigaddset (&action->sa_mask, SIGDANGER);
1499#endif 1535#endif
@@ -1638,6 +1674,25 @@ deliver_arith_signal (int sig)
1638 deliver_thread_signal (sig, handle_arith_signal); 1674 deliver_thread_signal (sig, handle_arith_signal);
1639} 1675}
1640 1676
1677#ifdef SIGDANGER
1678
1679/* Handler for SIGDANGER. */
1680static void
1681handle_danger_signal (int sig)
1682{
1683 malloc_warning ("Operating system warns that virtual memory is running low.\n");
1684
1685 /* It might be unsafe to call do_auto_save now. */
1686 force_auto_save_soon ();
1687}
1688
1689static void
1690deliver_danger_signal (int sig)
1691{
1692 deliver_process_signal (sig, handle_danger_signal);
1693}
1694#endif
1695
1641/* Treat SIG as a terminating signal, unless it is already ignored and 1696/* Treat SIG as a terminating signal, unless it is already ignored and
1642 we are in --batch mode. Among other things, this makes nohup work. */ 1697 we are in --batch mode. Among other things, this makes nohup work. */
1643static void 1698static void
@@ -1673,18 +1728,11 @@ init_signals (bool dumping)
1673# ifdef SIGAIO 1728# ifdef SIGAIO
1674 sys_siglist[SIGAIO] = "LAN I/O interrupt"; 1729 sys_siglist[SIGAIO] = "LAN I/O interrupt";
1675# endif 1730# endif
1676# ifdef SIGALRM
1677 sys_siglist[SIGALRM] = "Alarm clock"; 1731 sys_siglist[SIGALRM] = "Alarm clock";
1678# endif
1679# ifdef SIGBUS 1732# ifdef SIGBUS
1680 sys_siglist[SIGBUS] = "Bus error"; 1733 sys_siglist[SIGBUS] = "Bus error";
1681# endif 1734# endif
1682# ifdef SIGCLD
1683 sys_siglist[SIGCLD] = "Child status changed";
1684# endif
1685# ifdef SIGCHLD
1686 sys_siglist[SIGCHLD] = "Child status changed"; 1735 sys_siglist[SIGCHLD] = "Child status changed";
1687# endif
1688# ifdef SIGCONT 1736# ifdef SIGCONT
1689 sys_siglist[SIGCONT] = "Continued"; 1737 sys_siglist[SIGCONT] = "Continued";
1690# endif 1738# endif
@@ -1704,9 +1752,7 @@ init_signals (bool dumping)
1704# ifdef SIGGRANT 1752# ifdef SIGGRANT
1705 sys_siglist[SIGGRANT] = "Monitor mode granted"; 1753 sys_siglist[SIGGRANT] = "Monitor mode granted";
1706# endif 1754# endif
1707# ifdef SIGHUP
1708 sys_siglist[SIGHUP] = "Hangup"; 1755 sys_siglist[SIGHUP] = "Hangup";
1709# endif
1710 sys_siglist[SIGILL] = "Illegal instruction"; 1756 sys_siglist[SIGILL] = "Illegal instruction";
1711 sys_siglist[SIGINT] = "Interrupt"; 1757 sys_siglist[SIGINT] = "Interrupt";
1712# ifdef SIGIO 1758# ifdef SIGIO
@@ -1718,9 +1764,7 @@ init_signals (bool dumping)
1718# ifdef SIGIOT 1764# ifdef SIGIOT
1719 sys_siglist[SIGIOT] = "IOT trap"; 1765 sys_siglist[SIGIOT] = "IOT trap";
1720# endif 1766# endif
1721# ifdef SIGKILL
1722 sys_siglist[SIGKILL] = "Killed"; 1767 sys_siglist[SIGKILL] = "Killed";
1723# endif
1724# ifdef SIGLOST 1768# ifdef SIGLOST
1725 sys_siglist[SIGLOST] = "Resource lost"; 1769 sys_siglist[SIGLOST] = "Resource lost";
1726# endif 1770# endif
@@ -1733,9 +1777,7 @@ init_signals (bool dumping)
1733# ifdef SIGPHONE 1777# ifdef SIGPHONE
1734 sys_siglist[SIGWIND] = "SIGPHONE"; 1778 sys_siglist[SIGWIND] = "SIGPHONE";
1735# endif 1779# endif
1736# ifdef SIGPIPE
1737 sys_siglist[SIGPIPE] = "Broken pipe"; 1780 sys_siglist[SIGPIPE] = "Broken pipe";
1738# endif
1739# ifdef SIGPOLL 1781# ifdef SIGPOLL
1740 sys_siglist[SIGPOLL] = "Pollable event occurred"; 1782 sys_siglist[SIGPOLL] = "Pollable event occurred";
1741# endif 1783# endif
@@ -1748,9 +1790,7 @@ init_signals (bool dumping)
1748# ifdef SIGPWR 1790# ifdef SIGPWR
1749 sys_siglist[SIGPWR] = "Power-fail restart"; 1791 sys_siglist[SIGPWR] = "Power-fail restart";
1750# endif 1792# endif
1751# ifdef SIGQUIT
1752 sys_siglist[SIGQUIT] = "Quit"; 1793 sys_siglist[SIGQUIT] = "Quit";
1753# endif
1754# ifdef SIGRETRACT 1794# ifdef SIGRETRACT
1755 sys_siglist[SIGRETRACT] = "Need to relinquish monitor mode"; 1795 sys_siglist[SIGRETRACT] = "Need to relinquish monitor mode";
1756# endif 1796# endif
@@ -2105,7 +2145,7 @@ emacs_backtrace (int backtrace_limit)
2105void 2145void
2106emacs_abort (void) 2146emacs_abort (void)
2107{ 2147{
2108 terminate_due_to_signal (SIGABRT, 10); 2148 terminate_due_to_signal (SIGABRT, 40);
2109} 2149}
2110#endif 2150#endif
2111 2151
@@ -2203,22 +2243,6 @@ emacs_write (int fildes, const char *buf, ptrdiff_t nbyte)
2203 2243
2204 return (bytes_written); 2244 return (bytes_written);
2205} 2245}
2206
2207static struct allocator const emacs_norealloc_allocator =
2208 { xmalloc, NULL, xfree, memory_full };
2209
2210/* Get the symbolic link value of FILENAME. Return a pointer to a
2211 NUL-terminated string. If readlink fails, return NULL and set
2212 errno. If the value fits in INITIAL_BUF, return INITIAL_BUF.
2213 Otherwise, allocate memory and return a pointer to that memory. If
2214 memory allocation fails, diagnose and fail without returning. If
2215 successful, store the length of the symbolic link into *LINKLEN. */
2216char *
2217emacs_readlink (char const *filename, char initial_buf[READLINK_BUFSIZE])
2218{
2219 return careadlinkat (AT_FDCWD, filename, initial_buf, READLINK_BUFSIZE,
2220 &emacs_norealloc_allocator, careadlinkatcwd);
2221}
2222 2246
2223/* Return a struct timeval that is roughly equivalent to T. 2247/* Return a struct timeval that is roughly equivalent to T.
2224 Use the least timeval not less than T. 2248 Use the least timeval not less than T.
@@ -2515,12 +2539,12 @@ list_system_processes (void)
2515 return proclist; 2539 return proclist;
2516} 2540}
2517 2541
2518#elif defined BSD_SYSTEM 2542#elif defined DARWIN_OS || defined __FreeBSD__
2519 2543
2520Lisp_Object 2544Lisp_Object
2521list_system_processes (void) 2545list_system_processes (void)
2522{ 2546{
2523#if defined DARWIN_OS || defined __NetBSD__ || defined __OpenBSD__ 2547#ifdef DARWIN_OS
2524 int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL}; 2548 int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
2525#else 2549#else
2526 int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PROC}; 2550 int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PROC};
@@ -2546,10 +2570,8 @@ list_system_processes (void)
2546 len /= sizeof (struct kinfo_proc); 2570 len /= sizeof (struct kinfo_proc);
2547 for (i = 0; i < len; i++) 2571 for (i = 0; i < len; i++)
2548 { 2572 {
2549#if defined DARWIN_OS || defined __NetBSD__ 2573#ifdef DARWIN_OS
2550 proclist = Fcons (make_fixnum_or_float (procs[i].kp_proc.p_pid), proclist); 2574 proclist = Fcons (make_fixnum_or_float (procs[i].kp_proc.p_pid), proclist);
2551#elif defined __OpenBSD__
2552 proclist = Fcons (make_fixnum_or_float (procs[i].p_pid), proclist);
2553#else 2575#else
2554 proclist = Fcons (make_fixnum_or_float (procs[i].ki_pid), proclist); 2576 proclist = Fcons (make_fixnum_or_float (procs[i].ki_pid), proclist);
2555#endif 2577#endif
@@ -2669,7 +2691,7 @@ procfs_ttyname (int rdev)
2669 2691
2670 while (!feof (fdev) && !ferror (fdev)) 2692 while (!feof (fdev) && !ferror (fdev))
2671 { 2693 {
2672 if (3 <= fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) 2694 if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3
2673 && major == MAJOR (rdev)) 2695 && major == MAJOR (rdev))
2674 { 2696 {
2675 minor_beg = strtoul (minor, &endp, 0); 2697 minor_beg = strtoul (minor, &endp, 0);
@@ -2709,7 +2731,7 @@ procfs_get_total_memory (void)
2709 2731
2710 while (!feof (fmem) && !ferror (fmem)) 2732 while (!feof (fmem) && !ferror (fmem))
2711 { 2733 {
2712 if (2 <= fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value) 2734 if (fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value) >= 2
2713 && strcmp (entry_name, "MemTotal:") == 0) 2735 && strcmp (entry_name, "MemTotal:") == 0)
2714 { 2736 {
2715 retval = entry_value; 2737 retval = entry_value;