Issue #8407: The signal handler writes the signal number as a single byte
instead of a nul byte into the wakeup file descriptor. So it is possible to
wait more than one signal and know which signals were raised.
diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst
index 473eda2..68a5d2c 100644
--- a/Doc/library/signal.rst
+++ b/Doc/library/signal.rst
@@ -262,13 +262,17 @@
 
 .. function:: set_wakeup_fd(fd)
 
-   Set the wakeup fd to *fd*.  When a signal is received, a ``'\0'`` byte is
-   written to the fd.  This can be used by a library to wakeup a poll or select
-   call, allowing the signal to be fully processed.
+   Set the wakeup file descriptor to *fd*.  When a signal is received, the
+   signal number is written as a single byte into the fd.  This can be used by
+   a library to wakeup a poll or select call, allowing the signal to be fully
+   processed.
 
    The old wakeup fd is returned.  *fd* must be non-blocking.  It is up to the
    library to remove any bytes before calling poll or select again.
 
+   Use for example ``struct.unpack('%uB' % len(data), data)`` to decode the
+   signal numbers list.
+
    When threads are enabled, this function can only be called from the main thread;
    attempting to call it from other threads will cause a :exc:`ValueError`
    exception to be raised.
diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst
index 14f06af..37f96ce 100644
--- a/Doc/whatsnew/3.3.rst
+++ b/Doc/whatsnew/3.3.rst
@@ -131,6 +131,10 @@
   * :func:`~signal.sigpending`: examine pending functions ;
   * :func:`~signal.sigwait`: wait a signal.
 
+* The signal handler writes the signal number as a single byte instead of
+  a nul byte into the wakeup file descriptor. So it is possible to wait more
+  than one signal and know which signals were raised.
+
 
 Optimizations
 =============
diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
index c1054ed..80b9744 100644
--- a/Lib/test/test_signal.py
+++ b/Lib/test/test_signal.py
@@ -5,6 +5,7 @@
 import pickle
 import select
 import signal
+import struct
 import subprocess
 import traceback
 import sys, os, time, errno
@@ -236,6 +237,11 @@
     TIMEOUT_FULL = 10
     TIMEOUT_HALF = 5
 
+    def check_signum(self, *signals):
+        data = os.read(self.read, len(signals)+1)
+        raised = struct.unpack('%uB' % len(data), data)
+        self.assertSequenceEqual(raised, signals)
+
     def test_wakeup_fd_early(self):
         import select
 
@@ -249,6 +255,7 @@
         select.select([self.read], [], [], self.TIMEOUT_FULL)
         after_time = time.time()
         self.assertTrue(after_time - mid_time < self.TIMEOUT_HALF)
+        self.check_signum(signal.SIGALRM)
 
     def test_wakeup_fd_during(self):
         import select
@@ -260,6 +267,14 @@
             [self.read], [], [], self.TIMEOUT_FULL)
         after_time = time.time()
         self.assertTrue(after_time - before_time < self.TIMEOUT_HALF)
+        self.check_signum(signal.SIGALRM)
+
+    def test_signum(self):
+        old_handler = signal.signal(signal.SIGUSR1, lambda x,y:None)
+        self.addCleanup(signal.signal, signal.SIGUSR1, old_handler)
+        os.kill(os.getpid(), signal.SIGUSR1)
+        os.kill(os.getpid(), signal.SIGALRM)
+        self.check_signum(signal.SIGUSR1, signal.SIGALRM)
 
     def setUp(self):
         import fcntl
diff --git a/Misc/NEWS b/Misc/NEWS
index 274931c..ef78ab7 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -140,6 +140,10 @@
 Library
 -------
 
+- Issue #8407: The signal handler writes the signal number as a single byte
+  instead of a nul byte into the wakeup file descriptor. So it is possible to
+  wait more than one signal and know which signals were raised.
+
 - Issue #8407: Add pthread_kill(), sigpending() and sigwait() functions to the
   signal module.
 
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index 7285079..7e07b3e 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -176,6 +176,7 @@
 static void
 trip_signal(int sig_num)
 {
+    unsigned char byte;
     Handlers[sig_num].tripped = 1;
     if (is_tripped)
         return;
@@ -183,8 +184,10 @@
        cleared in PyErr_CheckSignals() before .tripped. */
     is_tripped = 1;
     Py_AddPendingCall(checksignals_witharg, NULL);
-    if (wakeup_fd != -1)
-        write(wakeup_fd, "\0", 1);
+    if (wakeup_fd != -1) {
+        byte = (unsigned char)sig_num;
+        write(wakeup_fd, &byte, 1);
+    }
 }
 
 static void