X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/0877d0dc24ee792b9b14592869ea1aa0934aee58..067428c1717acd28f205c2cff93f0583eb347f4c:/src/sysdep.c
diff --git a/src/sysdep.c b/src/sysdep.c
index 049eb85afe..faca7fae46 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -22,7 +22,7 @@ along with GNU Emacs. If not, see . */
#define SYSTIME_INLINE EXTERN_INLINE
#include
-#include
+#include "sysstdio.h"
#ifdef HAVE_PWD_H
#include
#include
@@ -30,9 +30,7 @@ along with GNU Emacs. If not, see . */
#include
#include
-#include
#include
-#include
#include
#include
@@ -40,9 +38,8 @@ along with GNU Emacs. If not, see . */
#include "sysselect.h"
#include "blockinput.h"
-#ifdef BSD_SYSTEM
-#include
-#include
+#if defined DARWIN_OS || defined __FreeBSD__
+# include
#endif
#ifdef __FreeBSD__
@@ -71,9 +68,9 @@ along with GNU Emacs. If not, see . */
#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
#include "msdos.h"
-#include
#endif
+#include
#include
#include
@@ -285,7 +282,7 @@ get_child_status (pid_t child, int *status, int options, bool interruptible)
reap an unwanted process by mistake. For example, invoking
waitpid (-1, ...) can mess up glib by reaping glib's subprocesses,
so that another thread running glib won't find them. */
- eassert (0 < child);
+ eassert (child > 0);
while ((pid = waitpid (child, status, options)) < 0)
{
@@ -529,10 +526,10 @@ sys_subshell (void)
#ifdef DOS_NT /* MW, Aug 1993 */
getcwd (oldwd, sizeof oldwd);
if (sh == 0)
- sh = (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */
+ sh = egetenv ("SUSPEND"); /* KFS, 1994-12-14 */
#endif
if (sh == 0)
- sh = (char *) egetenv ("SHELL");
+ sh = egetenv ("SHELL");
if (sh == 0)
sh = "sh";
@@ -546,8 +543,6 @@ sys_subshell (void)
#endif
}
- close_process_descs (); /* Close Emacs's pipes/ptys */
-
#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
{
char *epwd = getenv ("PWD");
@@ -714,6 +709,27 @@ init_foreground_group (void)
inherited_pgroup = getpid () == pgrp ? 0 : pgrp;
}
+/* Block and unblock SIGTTOU. */
+
+void
+block_tty_out_signal (void)
+{
+#ifdef SIGTTOU
+ sigset_t blocked;
+ sigemptyset (&blocked);
+ sigaddset (&blocked, SIGTTOU);
+ pthread_sigmask (SIG_BLOCK, &blocked, 0);
+#endif
+}
+
+void
+unblock_tty_out_signal (void)
+{
+#ifdef SIGTTOU
+ pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
+#endif
+}
+
/* Safely set a controlling terminal FD's process group to PGID.
If we are not in the foreground already, POSIX requires tcsetpgrp
to deliver a SIGTTOU signal, which would stop us. This is an
@@ -725,11 +741,10 @@ static void
tcsetpgrp_without_stopping (int fd, pid_t pgid)
{
#ifdef SIGTTOU
- signal_handler_t handler;
block_input ();
- handler = signal (SIGTTOU, SIG_IGN);
+ block_tty_out_signal ();
tcsetpgrp (fd, pgid);
- signal (SIGTTOU, handler);
+ unblock_tty_out_signal ();
unblock_input ();
#endif
}
@@ -1272,10 +1287,9 @@ reset_sys_modes (struct tty_display_info *tty_out)
if (tty_out->terminal->reset_terminal_modes_hook)
tty_out->terminal->reset_terminal_modes_hook (tty_out->terminal);
-#ifdef BSD_SYSTEM
/* Avoid possible loss of output when changing terminal modes. */
- fsync (fileno (tty_out->output));
-#endif
+ while (fdatasync (fileno (tty_out->output)) != 0 && errno == EINTR)
+ continue;
#ifndef DOS_NT
#ifdef F_SETOWN
@@ -1614,6 +1628,8 @@ deliver_thread_signal (int sig, signal_handler_t handler)
# undef sys_siglist
# ifdef _sys_siglist
# define sys_siglist _sys_siglist
+# elif HAVE_DECL___SYS_SIGLIST
+# define sys_siglist __sys_siglist
# else
# define sys_siglist my_sys_siglist
static char const *sys_siglist[NSIG];
@@ -1658,6 +1674,25 @@ deliver_arith_signal (int sig)
deliver_thread_signal (sig, handle_arith_signal);
}
+#ifdef SIGDANGER
+
+/* Handler for SIGDANGER. */
+static void
+handle_danger_signal (int sig)
+{
+ malloc_warning ("Operating system warns that virtual memory is running low.\n");
+
+ /* It might be unsafe to call do_auto_save now. */
+ force_auto_save_soon ();
+}
+
+static void
+deliver_danger_signal (int sig)
+{
+ deliver_process_signal (sig, handle_danger_signal);
+}
+#endif
+
/* Treat SIG as a terminating signal, unless it is already ignored and
we are in --batch mode. Among other things, this makes nohup work. */
static void
@@ -2114,15 +2149,53 @@ emacs_abort (void)
}
#endif
+/* Open FILE for Emacs use, using open flags OFLAG and mode MODE.
+ Arrange for subprograms to not inherit the file descriptor.
+ Prefer a method that is multithread-safe, if available.
+ Do not fail merely because the open was interrupted by a signal.
+ Allow the user to quit. */
+
int
-emacs_open (const char *path, int oflag, int mode)
+emacs_open (const char *file, int oflags, int mode)
{
- register int rtnval;
-
- while ((rtnval = open (path, oflag, mode)) == -1
- && (errno == EINTR))
+ int fd;
+ oflags |= O_CLOEXEC;
+ while ((fd = open (file, oflags, mode)) < 0 && errno == EINTR)
QUIT;
- return (rtnval);
+ if (! O_CLOEXEC && 0 <= fd)
+ fcntl (fd, F_SETFD, FD_CLOEXEC);
+ return fd;
+}
+
+/* Open FILE as a stream for Emacs use, with mode MODE.
+ Act like emacs_open with respect to threads, signals, and quits. */
+
+FILE *
+emacs_fopen (char const *file, char const *mode)
+{
+ int fd, omode, oflags;
+ int bflag = 0;
+ char const *m = mode;
+
+ switch (*m++)
+ {
+ case 'r': omode = O_RDONLY; oflags = 0; break;
+ case 'w': omode = O_WRONLY; oflags = O_CREAT | O_TRUNC; break;
+ case 'a': omode = O_WRONLY; oflags = O_CREAT | O_APPEND; break;
+ default: emacs_abort ();
+ }
+
+ while (*m)
+ switch (*m++)
+ {
+ case '+': omode = O_RDWR; break;
+ case 'b': bflag = O_BINARY; break;
+ case 't': bflag = O_TEXT; break;
+ default: /* Ignore. */ break;
+ }
+
+ fd = emacs_open (file, omode | oflags | bflag, 0666);
+ return fd < 0 ? 0 : fdopen (fd, mode);
}
int
@@ -2208,22 +2281,6 @@ emacs_write (int fildes, const char *buf, ptrdiff_t nbyte)
return (bytes_written);
}
-
-static struct allocator const emacs_norealloc_allocator =
- { xmalloc, NULL, xfree, memory_full };
-
-/* Get the symbolic link value of FILENAME. Return a pointer to a
- NUL-terminated string. If readlink fails, return NULL and set
- errno. If the value fits in INITIAL_BUF, return INITIAL_BUF.
- Otherwise, allocate memory and return a pointer to that memory. If
- memory allocation fails, diagnose and fail without returning. If
- successful, store the length of the symbolic link into *LINKLEN. */
-char *
-emacs_readlink (char const *filename, char initial_buf[READLINK_BUFSIZE])
-{
- return careadlinkat (AT_FDCWD, filename, initial_buf, READLINK_BUFSIZE,
- &emacs_norealloc_allocator, careadlinkatcwd);
-}
/* Return a struct timeval that is roughly equivalent to T.
Use the least timeval not less than T.
@@ -2520,12 +2577,12 @@ list_system_processes (void)
return proclist;
}
-#elif defined BSD_SYSTEM
+#elif defined DARWIN_OS || defined __FreeBSD__
Lisp_Object
list_system_processes (void)
{
-#if defined DARWIN_OS || defined __NetBSD__ || defined __OpenBSD__
+#ifdef DARWIN_OS
int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
#else
int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PROC};
@@ -2551,10 +2608,8 @@ list_system_processes (void)
len /= sizeof (struct kinfo_proc);
for (i = 0; i < len; i++)
{
-#if defined DARWIN_OS || defined __NetBSD__
+#ifdef DARWIN_OS
proclist = Fcons (make_fixnum_or_float (procs[i].kp_proc.p_pid), proclist);
-#elif defined __OpenBSD__
- proclist = Fcons (make_fixnum_or_float (procs[i].p_pid), proclist);
#else
proclist = Fcons (make_fixnum_or_float (procs[i].ki_pid), proclist);
#endif
@@ -2618,7 +2673,7 @@ get_up_time (void)
EMACS_TIME up = make_emacs_time (0, 0);
block_input ();
- fup = fopen ("/proc/uptime", "r");
+ fup = emacs_fopen ("/proc/uptime", "r");
if (fup)
{
@@ -2663,7 +2718,7 @@ procfs_ttyname (int rdev)
char name[PATH_MAX];
block_input ();
- fdev = fopen ("/proc/tty/drivers", "r");
+ fdev = emacs_fopen ("/proc/tty/drivers", "r");
if (fdev)
{
@@ -2674,7 +2729,7 @@ procfs_ttyname (int rdev)
while (!feof (fdev) && !ferror (fdev))
{
- if (3 <= fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor)
+ if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3
&& major == MAJOR (rdev))
{
minor_beg = strtoul (minor, &endp, 0);
@@ -2705,7 +2760,7 @@ procfs_get_total_memory (void)
unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */
block_input ();
- fmem = fopen ("/proc/meminfo", "r");
+ fmem = emacs_fopen ("/proc/meminfo", "r");
if (fmem)
{
@@ -2714,7 +2769,7 @@ procfs_get_total_memory (void)
while (!feof (fmem) && !ferror (fmem))
{
- if (2 <= fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value)
+ if (fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value) >= 2
&& strcmp (entry_name, "MemTotal:") == 0)
{
retval = entry_value;