Subject: bug#13026: Assume POSIX 1003.1-1988 or later for signal.h.

From: Paul Eggert <[email-masked]>
Date: Thu, 29 Nov 2012 13:38:04 -0800

On 11/29/12 09:33, Eli Zaretskii wrote:

> This will break the Windows build in more than one way, unless
> accompanied by suitable Windows-only changes.  Is this the entire
> changeset, or did you omit some more changes?

That was the entire changeset.  I didn't know about the problems
on MS-Windows.  I trimmed down the patch, to avoid the issues you
raised, and am attaching a proposed revised patch.  Thanks for
the review.

=== modified file 'ChangeLog'
--- ChangeLog	2012-11-27 03:10:32 +0000
+++ ChangeLog	2012-11-29 06:55:02 +0000
@@ -1,3 +1,9 @@
+2012-11-29  Paul Eggert  <[email-masked]>
+
+	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.
+
 2012-11-27  Eli Zaretskii  <[email-masked]>
 
 	* make-dist (nt): Adjust to changes in names of the *.manifest files.

=== modified file 'admin/CPP-DEFINES'
--- admin/CPP-DEFINES	2012-11-24 17:20:49 +0000
+++ admin/CPP-DEFINES	2012-11-29 06:46:35 +0000
@@ -419,14 +419,7 @@
 PURESIZE
 RUN_TIME_REMAP
 SETUP_SLAVE_PTY
-SIGALRM
-SIGCHLD
-SIGHUP
-SIGKILL
 SIGNALS_VIA_CHARACTERS
-SIGPIPE
-SIGQUIT
-SIGTRAP
 STDC_HEADERS
 SYSTEM_PURESIZE_EXTRA
 SYSTEM_MALLOC

=== modified file 'admin/ChangeLog'
--- admin/ChangeLog	2012-11-24 17:20:49 +0000
+++ admin/ChangeLog	2012-11-29 06:55:02 +0000
@@ -1,3 +1,10 @@
+2012-11-29  Paul Eggert  <[email-masked]>
+
+	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.
+
 2012-11-24  Ken Brown  <[email-masked]>
 
 	* CPP-DEFINES (HAVE_MOUSE): Remove.

=== modified file 'configure.ac'
--- configure.ac	2012-11-27 03:10:32 +0000
+++ configure.ac	2012-11-29 06:46:35 +0000
@@ -3600,7 +3600,7 @@
     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 @@
     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

=== modified file 'src/ChangeLog'
--- src/ChangeLog	2012-11-29 06:00:21 +0000
+++ src/ChangeLog	2012-11-29 21:33:52 +0000
@@ -1,3 +1,24 @@
+2012-11-29  Paul Eggert  <[email-masked]>
+
+	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 (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.
+	(Fsignal_process): Assume SIGHUP, SIGQUIT, SIGKILL, SIGPIPE,
+	SIGALRM and SIGCHLD are defined.
+	* 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-11-29  Dmitry Antipov  <[email-masked]>
 
 	* xdisp.c (window_outdated): Remove eassert since it hits

=== modified file 'src/callproc.c'
--- src/callproc.c	2012-11-29 00:36:22 +0000
+++ src/callproc.c	2012-11-29 06:46:35 +0000
@@ -97,7 +97,7 @@
   CONS_TO_INTEGER (Fcar (fdpid), int, fd);
   CONS_TO_INTEGER (Fcdr (fdpid), pid_t, pid);
   emacs_close (fd);
-  EMACS_KILLPG (pid, SIGKILL);
+  kill (-pid, SIGKILL);
   synch_process_alive = 0;
   return Qnil;
 }
@@ -134,7 +134,7 @@
       return Qnil;
     }
 
-  if (EMACS_KILLPG (pid, SIGINT) == 0)
+  if (kill (-pid, SIGINT) == 0)
     {
       ptrdiff_t count = SPECPDL_INDEX ();
       record_unwind_protect (call_process_kill, fdpid);

=== modified file 'src/keyboard.c'
--- src/keyboard.c	2012-11-27 05:17:07 +0000
+++ src/keyboard.c	2012-11-29 21:33:52 +0000
@@ -10689,7 +10689,7 @@
       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.

=== modified file 'src/process.c'
--- src/process.c	2012-11-27 05:17:07 +0000
+++ src/process.c	2012-11-29 21:33:52 +0000
@@ -773,13 +773,11 @@
 }

-#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;
    otherwise they might fill up the kernel's process table.  */
 static Lisp_Object deleted_pid_list;
-#endif
 
 DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0,
        doc: /* Delete PROCESS: kill it and forget about it immediately.
@@ -802,7 +800,6 @@
     }
   else if (p->infd >= 0)
     {
-#ifdef SIGCHLD
       Lisp_Object symbol;
       pid_t pid = p->pid;
 
@@ -820,7 +817,6 @@
 	deleted_pid_list
 	  = Fdelete (make_fixnum_or_float (pid), deleted_pid_list);
       else
-#endif
 	{
 	  Fkill_process (process, Qnil);
 	  /* Do this now, since remove_process will make the
@@ -1578,9 +1574,7 @@
 #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 +1674,11 @@
 
   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
 
 #if HAVE_WORKING_VFORK
   /* child_setup must clobber environ on systems with true vfork.
@@ -1800,10 +1792,8 @@
       /* 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);
@@ -1828,9 +1818,7 @@
     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)
@@ -4622,7 +4610,7 @@
 		 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 ();
@@ -4820,10 +4808,8 @@
 #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.  */
@@ -5686,7 +5672,7 @@
 
    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,
@@ -5824,7 +5810,7 @@
   if (!NILP (current_group))
     {
       if (ioctl (p->infd, TIOCSIGSEND, signo) == -1)
-	EMACS_KILLPG (gid, signo);
+	kill (-gid, signo);
     }
   else
     {
@@ -5832,7 +5818,7 @@
       kill (gid, signo);
     }
 #else /* ! defined (TIOCSIGSEND) */
-  EMACS_KILLPG (gid, signo);
+  kill (-gid, signo);
 #endif /* ! defined (TIOCSIGSEND) */
 }
 
@@ -5992,8 +5978,6 @@
       if (!strncmp (name, "SIG", 3) || !strncmp (name, "sig", 3))
 	name += 3;
 
-      if (0)
-	;
 #ifdef SIGUSR1
       parse_signal ("usr1", SIGUSR1);
 #endif
@@ -6001,21 +5985,15 @@
       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);
@@ -6024,12 +6002,8 @@
 #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
@@ -6042,9 +6016,7 @@
 #ifdef SIGCONT
       parse_signal ("cont", SIGCONT);
 #endif
-#ifdef SIGCHLD
       parse_signal ("chld", SIGCHLD);
-#endif
 #ifdef SIGTTIN
       parse_signal ("ttin", SIGTTIN);
 #endif
@@ -6214,7 +6186,6 @@
 void
 record_child_status_change (pid_t pid, int w)
 {
-#ifdef SIGCHLD
 
   /* Record at most one child only if we already know one child that
      has exited.  */
@@ -6303,11 +6274,8 @@
       if (input_available_clear_time)
 	*input_available_clear_time = make_emacs_time (0, 0);
     }
-#endif
 }
 
-#ifdef SIGCHLD
-
 static void
 handle_child_signal (int sig)
 {
@@ -6319,8 +6287,6 @@
 {
   deliver_process_signal (sig, handle_child_signal);
 }
-
-#endif /* SIGCHLD */
 
 
 static Lisp_Object
@@ -7169,7 +7135,6 @@
 
   inhibit_sentinels = 0;
 
-#ifdef SIGCHLD
 #ifndef CANNOT_DUMP
   if (! noninteractive || initialized)
 #endif
@@ -7178,7 +7143,6 @@
       emacs_sigaction_init (&action, deliver_child_signal);
       sigaction (SIGCHLD, &action, 0);
     }
-#endif
 
   FD_ZERO (&input_wait_mask);
   FD_ZERO (&non_keyboard_wait_mask);
@@ -7205,9 +7169,7 @@
 #endif
 
   Vprocess_alist = Qnil;
-#ifdef SIGCHLD
   deleted_pid_list = Qnil;
-#endif
   for (i = 0; i < MAXDESC; i++)
     {
       chan_process[i] = Qnil;
@@ -7334,9 +7296,7 @@
   DEFSYM (Qlast_nonmenu_event, "last-nonmenu-event");
 
   staticpro (&Vprocess_alist);
-#ifdef SIGCHLD
   staticpro (&deleted_pid_list);
-#endif
 
 #endif	/* subprocesses */

=== modified file 'src/sysdep.c'
--- src/sysdep.c	2012-11-27 03:10:32 +0000
+++ src/sysdep.c	2012-11-29 21:33:52 +0000
@@ -428,20 +428,15 @@
 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.  */
@@ -1491,9 +1486,7 @@
   /* 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
@@ -1673,18 +1666,11 @@
 # 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
@@ -1704,9 +1690,7 @@
 # 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
@@ -1718,9 +1702,7 @@
 # ifdef SIGIOT
       sys_siglist[SIGIOT] = "IOT trap";
 # endif
-# ifdef SIGKILL
       sys_siglist[SIGKILL] = "Killed";
-# endif
 # ifdef SIGLOST
       sys_siglist[SIGLOST] = "Resource lost";
 # endif
@@ -1733,9 +1715,7 @@
 # ifdef SIGPHONE
       sys_siglist[SIGWIND] = "SIGPHONE";
 # endif
-# ifdef SIGPIPE
       sys_siglist[SIGPIPE] = "Broken pipe";
-# endif
 # ifdef SIGPOLL
       sys_siglist[SIGPOLL] = "Pollable event occurred";
 # endif
@@ -1748,9 +1728,7 @@
 # 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

=== modified file 'src/syssignal.h'
--- src/syssignal.h	2012-10-07 02:26:03 +0000
+++ src/syssignal.h	2012-11-29 06:46:35 +0000
@@ -54,26 +54,6 @@
 # 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

=== modified file 'src/w32proc.c'
--- src/w32proc.c	2012-11-27 03:10:32 +0000
+++ src/w32proc.c	2012-11-29 06:46:35 +0000
@@ -2139,6 +2139,10 @@
   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)
     {