Assume POSIX 1003.1-1988 or later for signal.h.

Exceptions: do not assume SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN,
SIGTTOU, SIGUSR1, SIGUSR2, as Microsoft platforms lack these.
* admin/CPP-DEFINES (SIGALRM, SIGCHLD, SIGHUP, SIGKILL, SIGPIPE, SIGQUIT):
Remove.
(SIGTRAP): Remove this one too, as config.h no longer defines it.
* admin/merge-gnulib (GNULIB_MODULES): Add sig2str.
* configure.ac (PTY_OPEN, PTY_TTY_NAME_SPRINTF):
Use SIGCHLD rather than SIGCLD.
* lib/sig2str.c, lib/sig2str.h, m4/sig2str.m4: New files, from gnulib.
* lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate.
* lib/makefile.w32-in (GNULIBOBJS): Add $(BUILD)/sig2str.$(O).
* src/process.c [subprocesses]: Include <c-ctype.h>, <sig2str.h>.
(deleted_pid_list, Fdelete_process, create_process)
(record_child_status_change, handle_child_signal, deliver_child_signal)
(init_process_emacs, syms_of_process):
Assume SIGCHLD is defined.
(parse_signal): Remove.  All uses removed.
(abbr_to_signal): New static function.
(Fsignal_process): Use it to convert signal names to ints.
* src/sysdep.c (sys_suspend) [!DOS_NT]: Use kill (0, ...) rather than
kill (getpgrp (), ...).
(emacs_sigaction_init): Assume SIGCHLD is defined.
(init_signals): Assume SIGALRM, SIGCHLD, SIGHUP, SIGKILL,
SIGPIPE, and SIGQUIT are defined.  Do not worry about SIGCLD any more.
* src/syssignal.h (EMACS_KILLPG): Remove.
All uses replaced by 'kill' with a negative pid.
(SIGCHLD): Remove definition, as we now assume SIGCHLD.
* src/w32proc.c (sys_kill): Support negative pids compatibly with POSIX.

Fixes: debbugs:13026
This commit is contained in:
Paul Eggert 2012-12-07 18:30:51 -08:00
parent 9cdde1e2df
commit d983a10b9a
18 changed files with 515 additions and 187 deletions

View file

@ -1,3 +1,12 @@
2012-12-08 Paul Eggert <eggert@cs.ucla.edu>
Assume POSIX 1003.1-1988 or later for signal.h (Bug#13026).
* configure.ac (PTY_OPEN, PTY_TTY_NAME_SPRINTF):
Use SIGCHLD rather than SIGCLD.
* lib/sig2str.c, lib/sig2str.h, m4/sig2str.m4: New files, from gnulib.
* lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate.
* lib/makefile.w32-in (GNULIBOBJS): Add $(BUILD)/sig2str.$(O).
2012-12-06 Glenn Morris <rgm@gnu.org>
* configure.ac: Handle info/ files with or without ".info" extension.

View file

@ -419,14 +419,7 @@ PTY_TTY_NAME_SPRINTF
PURESIZE
RUN_TIME_REMAP
SETUP_SLAVE_PTY
SIGALRM
SIGCHLD
SIGHUP
SIGKILL
SIGNALS_VIA_CHARACTERS
SIGPIPE
SIGQUIT
SIGTRAP
STDC_HEADERS
SYSTEM_PURESIZE_EXTRA
SYSTEM_MALLOC

View file

@ -1,3 +1,11 @@
2012-12-03 Paul Eggert <eggert@cs.ucla.edu>
Assume POSIX 1003.1-1988 or later for signal.h (Bug#13026).
* CPP-DEFINES (SIGALRM, SIGCHLD, SIGHUP, SIGKILL, SIGPIPE, SIGQUIT):
Remove.
(SIGTRAP): Remove this one too, as config.h no longer defines it.
* merge-gnulib (GNULIB_MODULES): Add sig2str.
2012-11-24 Ken Brown <kbrown@cornell.edu>
* CPP-DEFINES (HAVE_MOUSE): Remove.

View file

@ -32,7 +32,7 @@ GNULIB_MODULES='
fcntl-h filemode getloadavg getopt-gnu gettime gettimeofday
ignore-value intprops largefile lstat
manywarnings mktime pselect pthread_sigmask readlink
socklen stat-time stdalign stdarg stdbool stdio
sig2str socklen stat-time stdalign stdarg stdbool stdio
strftime strtoimax strtoumax symlink sys_stat
sys_time time timer-time timespec-add timespec-sub utimens
warnings

View file

@ -3600,7 +3600,7 @@ case $opsys in
AC_DEFINE(PTY_ITERATION, [])
dnl Not used, because PTY_ITERATION is defined.
AC_DEFINE(FIRST_PTY_LETTER, ['q'])
AC_DEFINE(PTY_OPEN, [ { struct sigaction ocstat, cstat; struct stat stb; char * name; sigemptyset(&cstat.sa_mask); cstat.sa_handler = SIG_DFL; cstat.sa_flags = 0; sigaction(SIGCLD, &cstat, &ocstat); name = _getpty (&fd, O_RDWR | O_NDELAY, 0600, 0); sigaction(SIGCLD, &ocstat, (struct sigaction *)0); if (name == 0) return -1; if (fd < 0) return -1; if (fstat (fd, &stb) < 0) return -1; strcpy (pty_name, name); }])
AC_DEFINE(PTY_OPEN, [ { struct sigaction ocstat, cstat; struct stat stb; char * name; sigemptyset(&cstat.sa_mask); cstat.sa_handler = SIG_DFL; cstat.sa_flags = 0; sigaction(SIGCHLD, &cstat, &ocstat); name = _getpty (&fd, O_RDWR | O_NDELAY, 0600, 0); sigaction(SIGCHLD, &ocstat, (struct sigaction *)0); if (name == 0) return -1; if (fd < 0) return -1; if (fstat (fd, &stb) < 0) return -1; strcpy (pty_name, name); }])
dnl No need to get the pty name at all.
AC_DEFINE(PTY_NAME_SPRINTF, [])
dnl No need to use sprintf to get the tty name--we get that from _getpty.
@ -3611,12 +3611,12 @@ case $opsys in
dnl On SysVr4, grantpt(3) forks a subprocess, so keep sigchld_handler()
dnl from intercepting that death. If any child but grantpt's should die
dnl within, it should be caught after sigrelse(2).
AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptsname (int), *ptyname; int grantpt_result; sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGCLD); pthread_sigmask (SIG_BLOCK, &blocked, 0); grantpt_result = grantpt (fd); pthread_sigmask (SIG_UNBLOCK, &blocked, 0); if (grantpt_result == -1 || unlockpt (fd) == -1 || !(ptyname = ptsname (fd))) { emacs_close (fd); return -1; } snprintf (pty_name, sizeof pty_name, "%s", ptyname); }])
AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptsname (int), *ptyname; int grantpt_result; sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGCHLD); pthread_sigmask (SIG_BLOCK, &blocked, 0); grantpt_result = grantpt (fd); pthread_sigmask (SIG_UNBLOCK, &blocked, 0); if (grantpt_result == -1 || unlockpt (fd) == -1 || !(ptyname = ptsname (fd))) { emacs_close (fd); return -1; } snprintf (pty_name, sizeof pty_name, "%s", ptyname); }])
;;
unixware )
dnl Comments are as per sol2*.
AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptsname (int), *ptyname; int grantpt_result; sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGCLD); pthread_sigmask (SIG_BLOCK, &blocked, 0); grantpt_result = grantpt (fd); pthread_sigmask (SIG_UNBLOCK, &blocked, 0); if (grantpt_result == -1) fatal("could not grant slave pty"); if (unlockpt(fd) == -1) fatal("could not unlock slave pty"); if (!(ptyname = ptsname(fd))) fatal ("could not enable slave pty"); snprintf (pty_name, sizeof pty_name, "%s", ptyname); }])
AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptsname (int), *ptyname; int grantpt_result; sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGCHLD); pthread_sigmask (SIG_BLOCK, &blocked, 0); grantpt_result = grantpt (fd); pthread_sigmask (SIG_UNBLOCK, &blocked, 0); if (grantpt_result == -1) fatal("could not grant slave pty"); if (unlockpt(fd) == -1) fatal("could not unlock slave pty"); if (!(ptyname = ptsname(fd))) fatal ("could not enable slave pty"); snprintf (pty_name, sizeof pty_name, "%s", ptyname); }])
;;
esac

View file

@ -21,7 +21,7 @@
# the same distribution terms as the rest of that program.
#
# Generated by gnulib-tool.
# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=at-internal --avoid=errno --avoid=fchdir --avoid=fcntl --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=openat-die --avoid=openat-h --avoid=raise --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl-h filemode getloadavg getopt-gnu gettime gettimeofday ignore-value intprops largefile lstat manywarnings mktime pselect pthread_sigmask readlink socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub utimens warnings
# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=at-internal --avoid=errno --avoid=fchdir --avoid=fcntl --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=openat-die --avoid=openat-h --avoid=raise --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl-h filemode getloadavg getopt-gnu gettime gettimeofday ignore-value intprops largefile lstat manywarnings mktime pselect pthread_sigmask readlink sig2str socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub utimens warnings
MOSTLYCLEANFILES += core *.stackdump
@ -457,6 +457,15 @@ EXTRA_DIST += root-uid.h
## end gnulib module root-uid
## begin gnulib module sig2str
EXTRA_DIST += sig2str.c sig2str.h
EXTRA_libgnu_a_SOURCES += sig2str.c
## end gnulib module sig2str
## begin gnulib module signal-h
BUILT_SOURCES += signal.h

View file

@ -1,4 +1,4 @@
# -*- Makefile -*- for GNU Emacs on the Microsoft Windows API.
2# -*- Makefile -*- for GNU Emacs on the Microsoft Windows API.
# Copyright (C) 2011-2012 Free Software Foundation, Inc.
# This file is part of GNU Emacs.
@ -42,6 +42,7 @@ GNULIBOBJS = $(BLD)/c-ctype.$(O) \
$(BLD)/sha1.$(O) \
$(BLD)/sha256.$(O) \
$(BLD)/sha512.$(O) \
$(BLD)/sig2str.$(O) \
$(BLD)/stat-time.$(O) \
$(BLD)/timespec.$(O) \
$(BLD)/u64.$(O) \
@ -322,4 +323,3 @@ getopt_h:
execinfo.h: execinfo.in.h
$(CP) execinfo.in.h $@

345
lib/sig2str.c Normal file
View file

@ -0,0 +1,345 @@
/* sig2str.c -- convert between signal names and numbers
Copyright (C) 2002, 2004, 2006, 2009-2012 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Written by Paul Eggert. */
#include <config.h>
#include <limits.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "sig2str.h"
#ifndef SIGRTMIN
# define SIGRTMIN 0
# undef SIGRTMAX
#endif
#ifndef SIGRTMAX
# define SIGRTMAX (SIGRTMIN - 1)
#endif
#define NUMNAME(name) { SIG##name, #name }
/* Signal names and numbers. Put the preferred name first. */
static struct numname { int num; char const name[8]; } numname_table[] =
{
/* Signals required by POSIX 1003.1-2001 base, listed in
traditional numeric order where possible. */
#ifdef SIGHUP
NUMNAME (HUP),
#endif
#ifdef SIGINT
NUMNAME (INT),
#endif
#ifdef SIGQUIT
NUMNAME (QUIT),
#endif
#ifdef SIGILL
NUMNAME (ILL),
#endif
#ifdef SIGTRAP
NUMNAME (TRAP),
#endif
#ifdef SIGABRT
NUMNAME (ABRT),
#endif
#ifdef SIGFPE
NUMNAME (FPE),
#endif
#ifdef SIGKILL
NUMNAME (KILL),
#endif
#ifdef SIGSEGV
NUMNAME (SEGV),
#endif
/* On Haiku, SIGSEGV == SIGBUS, but we prefer SIGSEGV to match
strsignal.c output, so SIGBUS must be listed second. */
#ifdef SIGBUS
NUMNAME (BUS),
#endif
#ifdef SIGPIPE
NUMNAME (PIPE),
#endif
#ifdef SIGALRM
NUMNAME (ALRM),
#endif
#ifdef SIGTERM
NUMNAME (TERM),
#endif
#ifdef SIGUSR1
NUMNAME (USR1),
#endif
#ifdef SIGUSR2
NUMNAME (USR2),
#endif
#ifdef SIGCHLD
NUMNAME (CHLD),
#endif
#ifdef SIGURG
NUMNAME (URG),
#endif
#ifdef SIGSTOP
NUMNAME (STOP),
#endif
#ifdef SIGTSTP
NUMNAME (TSTP),
#endif
#ifdef SIGCONT
NUMNAME (CONT),
#endif
#ifdef SIGTTIN
NUMNAME (TTIN),
#endif
#ifdef SIGTTOU
NUMNAME (TTOU),
#endif
/* Signals required by POSIX 1003.1-2001 with the XSI extension. */
#ifdef SIGSYS
NUMNAME (SYS),
#endif
#ifdef SIGPOLL
NUMNAME (POLL),
#endif
#ifdef SIGVTALRM
NUMNAME (VTALRM),
#endif
#ifdef SIGPROF
NUMNAME (PROF),
#endif
#ifdef SIGXCPU
NUMNAME (XCPU),
#endif
#ifdef SIGXFSZ
NUMNAME (XFSZ),
#endif
/* Unix Version 7. */
#ifdef SIGIOT
NUMNAME (IOT), /* Older name for ABRT. */
#endif
#ifdef SIGEMT
NUMNAME (EMT),
#endif
/* USG Unix. */
#ifdef SIGPHONE
NUMNAME (PHONE),
#endif
#ifdef SIGWIND
NUMNAME (WIND),
#endif
/* Unix System V. */
#ifdef SIGCLD
NUMNAME (CLD),
#endif
#ifdef SIGPWR
NUMNAME (PWR),
#endif
/* GNU/Linux 2.2 and Solaris 8. */
#ifdef SIGCANCEL
NUMNAME (CANCEL),
#endif
#ifdef SIGLWP
NUMNAME (LWP),
#endif
#ifdef SIGWAITING
NUMNAME (WAITING),
#endif
#ifdef SIGFREEZE
NUMNAME (FREEZE),
#endif
#ifdef SIGTHAW
NUMNAME (THAW),
#endif
#ifdef SIGLOST
NUMNAME (LOST),
#endif
#ifdef SIGWINCH
NUMNAME (WINCH),
#endif
/* GNU/Linux 2.2. */
#ifdef SIGINFO
NUMNAME (INFO),
#endif
#ifdef SIGIO
NUMNAME (IO),
#endif
#ifdef SIGSTKFLT
NUMNAME (STKFLT),
#endif
/* AIX 5L. */
#ifdef SIGDANGER
NUMNAME (DANGER),
#endif
#ifdef SIGGRANT
NUMNAME (GRANT),
#endif
#ifdef SIGMIGRATE
NUMNAME (MIGRATE),
#endif
#ifdef SIGMSG
NUMNAME (MSG),
#endif
#ifdef SIGPRE
NUMNAME (PRE),
#endif
#ifdef SIGRETRACT
NUMNAME (RETRACT),
#endif
#ifdef SIGSAK
NUMNAME (SAK),
#endif
#ifdef SIGSOUND
NUMNAME (SOUND),
#endif
/* Older AIX versions. */
#ifdef SIGALRM1
NUMNAME (ALRM1), /* unknown; taken from Bash 2.05 */
#endif
#ifdef SIGKAP
NUMNAME (KAP), /* Older name for SIGGRANT. */
#endif
#ifdef SIGVIRT
NUMNAME (VIRT), /* unknown; taken from Bash 2.05 */
#endif
#ifdef SIGWINDOW
NUMNAME (WINDOW), /* Older name for SIGWINCH. */
#endif
/* BeOS */
#ifdef SIGKILLTHR
NUMNAME (KILLTHR),
#endif
/* Older HP-UX versions. */
#ifdef SIGDIL
NUMNAME (DIL),
#endif
/* Korn shell and Bash, of uncertain vintage. */
{ 0, "EXIT" }
};
#define NUMNAME_ENTRIES (sizeof numname_table / sizeof numname_table[0])
/* ISDIGIT differs from isdigit, as follows:
- Its arg may be any int or unsigned int; it need not be an unsigned char
or EOF.
- It's typically faster.
POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
isdigit unless it's important to use the locale's definition
of "digit" even when the host does not conform to POSIX. */
#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)
/* Convert the signal name SIGNAME to a signal number. Return the
signal number if successful, -1 otherwise. */
static int
str2signum (char const *signame)
{
if (ISDIGIT (*signame))
{
char *endp;
long int n = strtol (signame, &endp, 10);
if (! *endp && n <= SIGNUM_BOUND)
return n;
}
else
{
unsigned int i;
for (i = 0; i < NUMNAME_ENTRIES; i++)
if (strcmp (numname_table[i].name, signame) == 0)
return numname_table[i].num;
{
char *endp;
int rtmin = SIGRTMIN;
int rtmax = SIGRTMAX;
if (0 < rtmin && strncmp (signame, "RTMIN", 5) == 0)
{
long int n = strtol (signame + 5, &endp, 10);
if (! *endp && 0 <= n && n <= rtmax - rtmin)
return rtmin + n;
}
else if (0 < rtmax && strncmp (signame, "RTMAX", 5) == 0)
{
long int n = strtol (signame + 5, &endp, 10);
if (! *endp && rtmin - rtmax <= n && n <= 0)
return rtmax + n;
}
}
}
return -1;
}
/* Convert the signal name SIGNAME to the signal number *SIGNUM.
Return 0 if successful, -1 otherwise. */
int
str2sig (char const *signame, int *signum)
{
*signum = str2signum (signame);
return *signum < 0 ? -1 : 0;
}
/* Convert SIGNUM to a signal name in SIGNAME. SIGNAME must point to
a buffer of at least SIG2STR_MAX bytes. Return 0 if successful, -1
otherwise. */
int
sig2str (int signum, char *signame)
{
unsigned int i;
for (i = 0; i < NUMNAME_ENTRIES; i++)
if (numname_table[i].num == signum)
{
strcpy (signame, numname_table[i].name);
return 0;
}
{
int rtmin = SIGRTMIN;
int rtmax = SIGRTMAX;
if (! (rtmin <= signum && signum <= rtmax))
return -1;
if (signum <= rtmin + (rtmax - rtmin) / 2)
{
int delta = signum - rtmin;
sprintf (signame, delta ? "RTMIN+%d" : "RTMIN", delta);
}
else
{
int delta = rtmax - signum;
sprintf (signame, delta ? "RTMAX-%d" : "RTMAX", delta);
}
return 0;
}
}

43
lib/sig2str.h Normal file
View file

@ -0,0 +1,43 @@
/* sig2str.h -- convert between signal names and numbers
Copyright (C) 2002, 2005, 2009-2012 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Written by Paul Eggert. */
#include <signal.h>
/* Don't override system declarations of SIG2STR_MAX, sig2str, str2sig. */
#ifndef SIG2STR_MAX
# include "intprops.h"
/* Size of a buffer needed to hold a signal name like "HUP". */
# define SIG2STR_MAX (sizeof "SIGRTMAX" + INT_STRLEN_BOUND (int) - 1)
int sig2str (int, char *);
int str2sig (char const *, int *);
#endif
/* An upper bound on signal numbers allowed by the system. */
#if defined _sys_nsig
# define SIGNUM_BOUND (_sys_nsig - 1)
#elif defined NSIG
# define SIGNUM_BOUND (NSIG - 1)
#else
# define SIGNUM_BOUND 64
#endif

View file

@ -87,6 +87,7 @@ AC_DEFUN([gl_EARLY],
# Code from module pthread_sigmask:
# Code from module readlink:
# Code from module root-uid:
# Code from module sig2str:
# Code from module signal-h:
# Code from module snippet/_Noreturn:
# Code from module snippet/arg-nonnull:
@ -245,6 +246,11 @@ AC_DEFUN([gl_INIT],
gl_PREREQ_READLINK
fi
gl_UNISTD_MODULE_INDICATOR([readlink])
gl_FUNC_SIG2STR
if test $ac_cv_func_sig2str = no; then
AC_LIBOBJ([sig2str])
gl_PREREQ_SIG2STR
fi
gl_SIGNAL_H
gl_TYPE_SOCKLEN_T
gt_TYPE_SSIZE_T
@ -681,6 +687,8 @@ AC_DEFUN([gl_FILE_LIST], [
lib/sha256.h
lib/sha512.c
lib/sha512.h
lib/sig2str.c
lib/sig2str.h
lib/signal.in.h
lib/stat-time.c
lib/stat-time.h
@ -760,6 +768,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/sha1.m4
m4/sha256.m4
m4/sha512.m4
m4/sig2str.m4
m4/signal_h.m4
m4/socklen.m4
m4/ssize_t.m4

15
m4/sig2str.m4 Normal file
View file

@ -0,0 +1,15 @@
# serial 7
dnl Copyright (C) 2002, 2005-2006, 2009-2012 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_SIG2STR],
[
AC_CHECK_FUNCS([sig2str])
])
# Prerequisites of lib/sig2str.c.
AC_DEFUN([gl_PREREQ_SIG2STR], [
:
])

View file

@ -1,3 +1,26 @@
2012-12-08 Paul Eggert <eggert@cs.ucla.edu>
Assume POSIX 1003.1-1988 or later for signal.h (Bug#13026).
Exceptions: do not assume SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN,
SIGTTOU, SIGUSR1, SIGUSR2, as Microsoft platforms lack these.
* process.c [subprocesses]: Include <c-ctype.h>, <sig2str.h>.
(deleted_pid_list, Fdelete_process, create_process)
(record_child_status_change, handle_child_signal, deliver_child_signal)
(init_process_emacs, syms_of_process):
Assume SIGCHLD is defined.
(parse_signal): Remove. All uses removed.
(abbr_to_signal): New static function.
(Fsignal_process): Use it to convert signal names to ints.
* sysdep.c (sys_suspend) [!DOS_NT]: Use kill (0, ...) rather than
kill (getpgrp (), ...).
(emacs_sigaction_init): Assume SIGCHLD is defined.
(init_signals): Assume SIGALRM, SIGCHLD, SIGHUP, SIGKILL,
SIGPIPE, and SIGQUIT are defined. Do not worry about SIGCLD any more.
* syssignal.h (EMACS_KILLPG): Remove.
All uses replaced by 'kill' with a negative pid.
(SIGCHLD): Remove definition, as we now assume SIGCHLD.
* w32proc.c (sys_kill): Support negative pids compatibly with POSIX.
2012-12-07 Paul Eggert <eggert@cs.ucla.edu>
* sysdep.c (get_child_status): Abort on internal error (Bug#13086).

View file

@ -87,12 +87,10 @@ static int synch_process_fd;
static void
block_child_signal (void)
{
#ifdef SIGCHLD
sigset_t blocked;
sigemptyset (&blocked);
sigaddset (&blocked, SIGCHLD);
pthread_sigmask (SIG_BLOCK, &blocked, 0);
#endif
}
/* Unblock SIGCHLD. */
@ -100,9 +98,7 @@ block_child_signal (void)
static void
unblock_child_signal (void)
{
#ifdef SIGCHLD
pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
#endif
}
/* If P is reapable, record it as a deleted process and kill it.
@ -118,7 +114,7 @@ record_kill_process (struct Lisp_Process *p)
{
p->alive = 0;
record_deleted_pid (p->pid);
EMACS_KILLPG (p->pid, SIGKILL);
kill (- p->pid, SIGKILL);
}
unblock_child_signal ();
@ -164,7 +160,7 @@ call_process_cleanup (Lisp_Object arg)
if (synch_process_pid)
{
ptrdiff_t count = SPECPDL_INDEX ();
EMACS_KILLPG (synch_process_pid, SIGINT);
kill (-synch_process_pid, SIGINT);
record_unwind_protect (call_process_kill, make_number (0));
message1 ("Waiting for process to die...(type C-g again to kill it instantly)");
immediate_quit = 1;

View file

@ -10688,7 +10688,7 @@ handle_interrupt (bool in_signal_handler)
fflush (stdout);
reset_all_sys_modes ();
#ifdef SIGTSTP /* Support possible in later USG versions */
#ifdef SIGTSTP
/*
* On systems which can suspend the current process and return to the original
* shell, this command causes the user to end up back at the shell.

View file

@ -91,6 +91,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <pty.h>
#endif
#include <c-ctype.h>
#include <sig2str.h>
#endif /* subprocesses */
#include "systime.h"
@ -773,7 +776,6 @@ get_process (register Lisp_Object name)
}
#ifdef SIGCHLD
/* Fdelete_process promises to immediately forget about the process, but in
reality, Emacs needs to remember those processes until they have been
treated by the SIGCHLD handler and waitpid has been invoked on them;
@ -781,17 +783,14 @@ get_process (register Lisp_Object name)
Some processes created by call-process are also put onto this list. */
static Lisp_Object deleted_pid_list;
#endif
void
record_deleted_pid (pid_t pid)
{
#ifdef SIGCHLD
deleted_pid_list = Fcons (make_fixnum_or_float (pid),
/* GC treated elements set to nil. */
Fdelq (Qnil, deleted_pid_list));
#endif
}
DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0,
@ -1581,9 +1580,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
#ifndef WINDOWSNT
int wait_child_setup[2];
#endif
#ifdef SIGCHLD
sigset_t blocked;
#endif
/* Use volatile to protect variables from being clobbered by vfork. */
volatile int forkin, forkout;
volatile int pty_flag = 0;
@ -1680,13 +1677,11 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
block_input ();
#ifdef SIGCHLD
/* Block SIGCHLD until we have a chance to store the new fork's
pid in its process structure. */
sigemptyset (&blocked);
sigaddset (&blocked, SIGCHLD);
pthread_sigmask (SIG_BLOCK, &blocked, 0);
#endif
#ifndef WINDOWSNT
pid = vfork ();
@ -1794,10 +1789,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
/* Emacs ignores SIGPIPE, but the child should not. */
signal (SIGPIPE, SIG_DFL);
#ifdef SIGCHLD
/* Stop blocking signals in the child. */
pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
#endif
if (pty_flag)
child_setup_tty (xforkout);
@ -1818,9 +1811,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
XPROCESS (process)->alive = 1;
/* Stop blocking signals in the parent. */
#ifdef SIGCHLD
pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
#endif
unblock_input ();
if (pid < 0)
@ -4612,7 +4603,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
yielding EBADF here or at select() call above.
So, SIGHUP is ignored (see def of PTY_TTY_NAME_SPRINTF
in m/ibmrt-aix.h), and here we just ignore the select error.
Cleanup occurs c/o status_notify after SIGCLD. */
Cleanup occurs c/o status_notify after SIGCHLD. */
no_avail = 1; /* Cannot depend on values returned */
#else
emacs_abort ();
@ -4810,10 +4801,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
#endif /* HAVE_PTYS */
/* If we can detect process termination, don't consider the
process gone just because its pipe is closed. */
#ifdef SIGCHLD
else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc))
;
#endif
else
{
/* Preserve status of processes already terminated. */
@ -5676,7 +5665,7 @@ return t unconditionally. */)
If we can, we try to signal PROCESS by sending control characters
down the pty. This allows us to signal inferiors who have changed
their uid, for which killpg would return an EPERM error. */
their uid, for which kill would return an EPERM error. */
static void
process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group,
@ -5814,7 +5803,7 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group,
if (!NILP (current_group))
{
if (ioctl (p->infd, TIOCSIGSEND, signo) == -1)
EMACS_KILLPG (gid, signo);
kill (-gid, signo);
}
else
{
@ -5822,7 +5811,7 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group,
kill (gid, signo);
}
#else /* ! defined (TIOCSIGSEND) */
EMACS_KILLPG (gid, signo);
kill (-gid, signo);
#endif /* ! defined (TIOCSIGSEND) */
}
@ -5927,6 +5916,27 @@ traffic. */)
return process;
}
/* Return the integer value of the signal whose abbreviation is ABBR,
or a negative number if there is no such signal. */
static int
abbr_to_signal (char const *name)
{
int i, signo;
char sigbuf[20]; /* Large enough for all valid signal abbreviations. */
if (!strncmp (name, "SIG", 3) || !strncmp (name, "sig", 3))
name += 3;
for (i = 0; i < sizeof sigbuf; i++)
{
sigbuf[i] = c_toupper (name[i]);
if (! sigbuf[i])
return str2sig (sigbuf, &signo) == 0 ? signo : -1;
}
return -1;
}
DEFUN ("signal-process", Fsignal_process, Ssignal_process,
2, 2, "sProcess (name or number): \nnSignal code: ",
doc: /* Send PROCESS the signal with code SIGCODE.
@ -5937,6 +5947,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */)
(Lisp_Object process, Lisp_Object sigcode)
{
pid_t pid;
int signo;
if (STRINGP (process))
{
@ -5966,12 +5977,11 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */)
error ("Cannot signal process %s", SDATA (XPROCESS (process)->name));
}
#define parse_signal(NAME, VALUE) \
else if (!xstrcasecmp (name, NAME)) \
XSETINT (sigcode, VALUE)
if (INTEGERP (sigcode))
{
CHECK_TYPE_RANGED_INTEGER (int, sigcode);
signo = XINT (sigcode);
}
else
{
char *name;
@ -5979,96 +5989,12 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */)
CHECK_SYMBOL (sigcode);
name = SSDATA (SYMBOL_NAME (sigcode));
if (!strncmp (name, "SIG", 3) || !strncmp (name, "sig", 3))
name += 3;
if (0)
;
#ifdef SIGUSR1
parse_signal ("usr1", SIGUSR1);
#endif
#ifdef SIGUSR2
parse_signal ("usr2", SIGUSR2);
#endif
parse_signal ("term", SIGTERM);
#ifdef SIGHUP
parse_signal ("hup", SIGHUP);
#endif
parse_signal ("int", SIGINT);
#ifdef SIGQUIT
parse_signal ("quit", SIGQUIT);
#endif
parse_signal ("ill", SIGILL);
parse_signal ("abrt", SIGABRT);
#ifdef SIGEMT
parse_signal ("emt", SIGEMT);
#endif
#ifdef SIGKILL
parse_signal ("kill", SIGKILL);
#endif
parse_signal ("fpe", SIGFPE);
#ifdef SIGBUS
parse_signal ("bus", SIGBUS);
#endif
parse_signal ("segv", SIGSEGV);
#ifdef SIGSYS
parse_signal ("sys", SIGSYS);
#endif
#ifdef SIGPIPE
parse_signal ("pipe", SIGPIPE);
#endif
#ifdef SIGALRM
parse_signal ("alrm", SIGALRM);
#endif
#ifdef SIGURG
parse_signal ("urg", SIGURG);
#endif
#ifdef SIGSTOP
parse_signal ("stop", SIGSTOP);
#endif
#ifdef SIGTSTP
parse_signal ("tstp", SIGTSTP);
#endif
#ifdef SIGCONT
parse_signal ("cont", SIGCONT);
#endif
#ifdef SIGCHLD
parse_signal ("chld", SIGCHLD);
#endif
#ifdef SIGTTIN
parse_signal ("ttin", SIGTTIN);
#endif
#ifdef SIGTTOU
parse_signal ("ttou", SIGTTOU);
#endif
#ifdef SIGIO
parse_signal ("io", SIGIO);
#endif
#ifdef SIGXCPU
parse_signal ("xcpu", SIGXCPU);
#endif
#ifdef SIGXFSZ
parse_signal ("xfsz", SIGXFSZ);
#endif
#ifdef SIGVTALRM
parse_signal ("vtalrm", SIGVTALRM);
#endif
#ifdef SIGPROF
parse_signal ("prof", SIGPROF);
#endif
#ifdef SIGWINCH
parse_signal ("winch", SIGWINCH);
#endif
#ifdef SIGINFO
parse_signal ("info", SIGINFO);
#endif
else
signo = abbr_to_signal (name);
if (signo < 0)
error ("Undefined signal name %s", name);
}
#undef parse_signal
return make_number (kill (pid, XINT (sigcode)));
return make_number (kill (pid, signo));
}
DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0,
@ -6150,8 +6076,6 @@ process has been transmitted to the serial port. */)
return process;
}
#ifdef SIGCHLD
/* The main Emacs thread records child processes in three places:
- Vprocess_alist, for asynchronous subprocesses, which are child
@ -6268,8 +6192,6 @@ deliver_child_signal (int sig)
{
deliver_process_signal (sig, handle_child_signal);
}
#endif /* SIGCHLD */
static Lisp_Object
@ -7118,7 +7040,6 @@ init_process_emacs (void)
inhibit_sentinels = 0;
#ifdef SIGCHLD
#ifndef CANNOT_DUMP
if (! noninteractive || initialized)
#endif
@ -7127,7 +7048,6 @@ init_process_emacs (void)
emacs_sigaction_init (&action, deliver_child_signal);
sigaction (SIGCHLD, &action, 0);
}
#endif
FD_ZERO (&input_wait_mask);
FD_ZERO (&non_keyboard_wait_mask);
@ -7154,9 +7074,7 @@ init_process_emacs (void)
#endif
Vprocess_alist = Qnil;
#ifdef SIGCHLD
deleted_pid_list = Qnil;
#endif
for (i = 0; i < MAXDESC; i++)
{
chan_process[i] = Qnil;
@ -7283,9 +7201,7 @@ syms_of_process (void)
DEFSYM (Qlast_nonmenu_event, "last-nonmenu-event");
staticpro (&Vprocess_alist);
#ifdef SIGCHLD
staticpro (&deleted_pid_list);
#endif
#endif /* subprocesses */

View file

@ -457,20 +457,15 @@ static void restore_signal_handlers (struct save_signal *);
void
sys_suspend (void)
{
#if defined (SIGTSTP) && !defined (MSDOS)
{
pid_t pgrp = getpgrp ();
EMACS_KILLPG (pgrp, SIGTSTP);
}
#else /* No SIGTSTP */
#ifndef DOS_NT
kill (0, SIGTSTP);
#else
/* On a system where suspending is not implemented,
instead fork a subshell and let it talk directly to the terminal
while we wait. */
sys_subshell ();
#endif /* no SIGTSTP */
#endif
}
/* Fork a subshell. */
@ -1518,9 +1513,7 @@ emacs_sigaction_init (struct sigaction *action, signal_handler_t handler)
/* When handling a signal, block nonfatal system signals that are caught
by Emacs. This makes race conditions less likely. */
sigaddset (&action->sa_mask, SIGALRM);
#ifdef SIGCHLD
sigaddset (&action->sa_mask, SIGCHLD);
#endif
#ifdef SIGDANGER
sigaddset (&action->sa_mask, SIGDANGER);
#endif
@ -1700,18 +1693,11 @@ init_signals (bool dumping)
# ifdef SIGAIO
sys_siglist[SIGAIO] = "LAN I/O interrupt";
# endif
# ifdef SIGALRM
sys_siglist[SIGALRM] = "Alarm clock";
# endif
# ifdef SIGBUS
sys_siglist[SIGBUS] = "Bus error";
# endif
# ifdef SIGCLD
sys_siglist[SIGCLD] = "Child status changed";
# endif
# ifdef SIGCHLD
sys_siglist[SIGCHLD] = "Child status changed";
# endif
# ifdef SIGCONT
sys_siglist[SIGCONT] = "Continued";
# endif
@ -1731,9 +1717,7 @@ init_signals (bool dumping)
# ifdef SIGGRANT
sys_siglist[SIGGRANT] = "Monitor mode granted";
# endif
# ifdef SIGHUP
sys_siglist[SIGHUP] = "Hangup";
# endif
sys_siglist[SIGILL] = "Illegal instruction";
sys_siglist[SIGINT] = "Interrupt";
# ifdef SIGIO
@ -1745,9 +1729,7 @@ init_signals (bool dumping)
# ifdef SIGIOT
sys_siglist[SIGIOT] = "IOT trap";
# endif
# ifdef SIGKILL
sys_siglist[SIGKILL] = "Killed";
# endif
# ifdef SIGLOST
sys_siglist[SIGLOST] = "Resource lost";
# endif
@ -1760,9 +1742,7 @@ init_signals (bool dumping)
# ifdef SIGPHONE
sys_siglist[SIGWIND] = "SIGPHONE";
# endif
# ifdef SIGPIPE
sys_siglist[SIGPIPE] = "Broken pipe";
# endif
# ifdef SIGPOLL
sys_siglist[SIGPOLL] = "Pollable event occurred";
# endif
@ -1775,9 +1755,7 @@ init_signals (bool dumping)
# ifdef SIGPWR
sys_siglist[SIGPWR] = "Power-fail restart";
# endif
# ifdef SIGQUIT
sys_siglist[SIGQUIT] = "Quit";
# endif
# ifdef SIGRETRACT
sys_siglist[SIGRETRACT] = "Need to relinquish monitor mode";
# endif

View file

@ -54,26 +54,6 @@ char const *safe_strsignal (int) ATTRIBUTE_CONST;
# define emacs_raise(sig) raise (sig)
#endif
/* On bsd, [man says] kill does not accept a negative number to kill a pgrp.
Must do that using the killpg call. */
#ifdef BSD_SYSTEM
#define EMACS_KILLPG(gid, signo) (killpg ( (gid), (signo)))
#else
#ifdef WINDOWSNT
#define EMACS_KILLPG(gid, signo) (kill (gid, signo))
#else
#define EMACS_KILLPG(gid, signo) (kill (-(gid), (signo)))
#endif
#endif
/* Define SIGCHLD as an alias for SIGCLD. There are many conditionals
testing SIGCHLD. */
#ifdef SIGCLD
#ifndef SIGCHLD
#define SIGCHLD SIGCLD
#endif /* SIGCHLD */
#endif /* ! defined (SIGCLD) */
#ifndef HAVE_STRSIGNAL
# define strsignal(sig) safe_strsignal (sig)
#endif

View file

@ -2122,6 +2122,10 @@ sys_kill (int pid, int sig)
int need_to_free = 0;
int rc = 0;
/* Each process is in its own process group. */
if (pid < 0)
pid = -pid;
/* Only handle signals that will result in the process dying */
if (sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP)
{