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;