bpo-32593: Drop FreeBSD 9 and older support (#5232)

Drop support of FreeBSD 9 and older.
diff --git a/Doc/library/time.rst b/Doc/library/time.rst
index ccbb3f3..3eddc3f 100644
--- a/Doc/library/time.rst
+++ b/Doc/library/time.rst
@@ -792,7 +792,7 @@
 
    High-resolution per-process timer from the CPU.
 
-   Availability: FreeBSD 3 or later, NetBSD 7 or later, OpenBSD.
+   Availability: FreeBSD, NetBSD 7 or later, OpenBSD.
 
    .. versionadded:: 3.7
 
@@ -812,7 +812,7 @@
    suspended, providing accurate uptime measurement, both absolute and
    interval.
 
-   Availability: FreeBSD 7 or later, OpenBSD 5.5 or later.
+   Availability: FreeBSD, OpenBSD 5.5 or later.
 
    .. versionadded:: 3.7
 
diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst
index 54a3f14..0418aa6 100644
--- a/Doc/whatsnew/3.7.rst
+++ b/Doc/whatsnew/3.7.rst
@@ -806,6 +806,11 @@
 Removed
 =======
 
+Platform Support Removals
+-------------------------
+
+* FreeBSD 9 and older are no longer supported.
+
 API and Feature Removals
 ------------------------
 
diff --git a/Include/py_curses.h b/Include/py_curses.h
index 597f419..0eebc36 100644
--- a/Include/py_curses.h
+++ b/Include/py_curses.h
@@ -12,31 +12,15 @@
 #endif
 #endif /* __APPLE__ */
 
-#ifdef __FreeBSD__
-/*
-** On FreeBSD, [n]curses.h and stdlib.h/wchar.h use different guards
-** against multiple definition of wchar_t and wint_t.
-*/
-#ifdef _XOPEN_SOURCE_EXTENDED
-#ifndef __FreeBSD_version
-#include <osreldate.h>
-#endif
-#if __FreeBSD_version >= 500000
-#ifndef __wchar_t
-#define __wchar_t
-#endif
-#ifndef __wint_t
-#define __wint_t
-#endif
-#else
-#ifndef _WCHAR_T
-#define _WCHAR_T
-#endif
-#ifndef _WINT_T
-#define _WINT_T
-#endif
-#endif
-#endif
+/* On FreeBSD, [n]curses.h and stdlib.h/wchar.h use different guards
+   against multiple definition of wchar_t and wint_t. */
+#if defined(__FreeBSD__) && defined(_XOPEN_SOURCE_EXTENDED)
+# ifndef __wchar_t
+#   define __wchar_t
+# endif
+# ifndef __wint_t
+#   define __wint_t
+# endif
 #endif
 
 #if !defined(HAVE_CURSES_IS_PAD) && defined(WINDOW_HAS_FLAGS)
diff --git a/Include/pyport.h b/Include/pyport.h
index f2e247a..c1f4c7f 100644
--- a/Include/pyport.h
+++ b/Include/pyport.h
@@ -564,18 +564,8 @@
  * workaround was provided by Tim Robbins of FreeBSD project.
  */
 
-#ifdef __FreeBSD__
-#include <osreldate.h>
-#if (__FreeBSD_version >= 500040 && __FreeBSD_version < 602113) || \
-    (__FreeBSD_version >= 700000 && __FreeBSD_version < 700054) || \
-    (__FreeBSD_version >= 800000 && __FreeBSD_version < 800001)
-# define _PY_PORT_CTYPE_UTF8_ISSUE
-#endif
-#endif
-
-
 #if defined(__APPLE__)
-# define _PY_PORT_CTYPE_UTF8_ISSUE
+#  define _PY_PORT_CTYPE_UTF8_ISSUE
 #endif
 
 #ifdef _PY_PORT_CTYPE_UTF8_ISSUE
diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py
index 4140f03..e4b0536 100644
--- a/Lib/test/test_asyncio/test_events.py
+++ b/Lib/test/test_asyncio/test_events.py
@@ -1471,8 +1471,6 @@
     @unittest.skipUnless(sys.platform != 'win32',
                          "Don't support pipes for Windows")
     @unittest.skipIf(sys.platform == 'darwin', 'test hangs on MacOS')
-    # Issue #20495: The test hangs on FreeBSD 7.2 but pass on FreeBSD 9
-    @support.requires_freebsd_version(8)
     def test_read_pty_output(self):
         proto = MyReadPipeProto(loop=self.loop)
 
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index 3aee5f1..c6345e9 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -4107,8 +4107,6 @@
     def test_interrupted_write_buffered(self):
         self.check_interrupted_write(b"xy", b"xy", mode="wb")
 
-    # Issue #22331: The test hangs on FreeBSD 7.2
-    @support.requires_freebsd_version(8)
     def test_interrupted_write_text(self):
         self.check_interrupted_write("xy", b"xy", mode="w", encoding="ascii")
 
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
index 54049d2..eee2ed0 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -773,14 +773,7 @@
                               :func:`select` or :func:`poll` call by
                               :func:`asyncore.loop`.
         """
-        try:
-            asyncore.loop(poll_interval, map=self._map)
-        except OSError:
-            # On FreeBSD 8, closing the server repeatably
-            # raises this error. We swallow it if the
-            # server has been closed.
-            if self.connected or self.accepting:
-                raise
+        asyncore.loop(poll_interval, map=self._map)
 
     def stop(self, timeout=None):
         """
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index 83e214d..02611d2 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -782,9 +782,7 @@
         value_str = value.decode(sys.getfilesystemencoding(), 'surrogateescape')
         self.assertEqual(os.environ['bytes'], value_str)
 
-    # On FreeBSD < 7 and OS X < 10.6, unsetenv() doesn't return a value (issue
-    # #13415).
-    @support.requires_freebsd_version(7)
+    # On OS X < 10.6, unsetenv() doesn't return a value (bpo-13415).
     @support.requires_mac_ver(10, 6)
     def test_unset_error(self):
         if sys.platform == "win32":
diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py
index 44b8d6a..6c50406 100644
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -559,6 +559,7 @@
         self.assertRaises(TypeError, posix.minor)
         self.assertRaises((ValueError, OverflowError), posix.minor, -1)
 
+        # FIXME: reenable these tests on FreeBSD with the kernel fix
         if sys.platform.startswith('freebsd') and dev >= 0x1_0000_0000:
             self.skipTest("bpo-31044: on FreeBSD CURRENT, minor() truncates "
                           "64-bit dev to 32-bit")
diff --git a/Lib/test/test_resource.py b/Lib/test/test_resource.py
index cc9c570..4b85278 100644
--- a/Lib/test/test_resource.py
+++ b/Lib/test/test_resource.py
@@ -138,7 +138,6 @@
             with contextlib.suppress(AttributeError):
                 self.assertIsInstance(getattr(resource, 'RLIMIT_' + attr), int)
 
-    @support.requires_freebsd_version(9)
     def test_freebsd_contants(self):
         for attr in ['SWAP', 'SBSIZE', 'NPTS']:
             with contextlib.suppress(AttributeError):
diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
index f17123c..48b7a39 100644
--- a/Lib/test/test_signal.py
+++ b/Lib/test/test_signal.py
@@ -56,9 +56,6 @@
         self.assertEqual(signal.getsignal(signal.SIGHUP), hup)
 
     # Issue 3864, unknown if this affects earlier versions of freebsd also
-    @unittest.skipIf(sys.platform=='freebsd6',
-        'inter process signals not reliable (do not mix well with threading) '
-        'on freebsd6')
     def test_interprocess_signal(self):
         dirname = os.path.dirname(__file__)
         script = os.path.join(dirname, 'signalinterproctester.py')
@@ -651,7 +648,7 @@
         self.assertEqual(self.hndl_called, True)
 
     # Issue 3864, unknown if this affects earlier versions of freebsd also
-    @unittest.skipIf(sys.platform in ('freebsd6', 'netbsd5'),
+    @unittest.skipIf(sys.platform in ('netbsd5',),
         'itimer not reliable (does not mix well with threading) on some BSDs.')
     def test_itimer_virtual(self):
         self.itimer = signal.ITIMER_VIRTUAL
@@ -673,9 +670,6 @@
         # and the handler should have been called
         self.assertEqual(self.hndl_called, True)
 
-    # Issue 3864, unknown if this affects earlier versions of freebsd also
-    @unittest.skipIf(sys.platform=='freebsd6',
-        'itimer not reliable (does not mix well with threading) on freebsd6')
     def test_itimer_prof(self):
         self.itimer = signal.ITIMER_PROF
         signal.signal(signal.SIGPROF, self.sig_prof)
@@ -762,16 +756,6 @@
 
             signal.signal(signum, handler)
 
-            if sys.platform == 'freebsd6':
-                # Issue #12392 and #12469: send a signal to the main thread
-                # doesn't work before the creation of the first thread on
-                # FreeBSD 6
-                def noop():
-                    pass
-                thread = threading.Thread(target=noop)
-                thread.start()
-                thread.join()
-
             tid = threading.get_ident()
             try:
                 signal.pthread_kill(tid, signum)
@@ -1010,9 +994,6 @@
         """
         assert_python_ok('-c', code)
 
-    @unittest.skipIf(sys.platform == 'freebsd6',
-        "issue #12392: send a signal to the main thread doesn't work "
-        "before the creation of the first thread on FreeBSD 6")
     @unittest.skipUnless(hasattr(signal, 'pthread_kill'),
                          'need signal.pthread_kill()')
     def test_pthread_kill_main_thread(self):
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index 43688ea..22d142c 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -2598,9 +2598,6 @@
     def _testRecvmsgShorter(self):
         self.sendToServer(MSG)
 
-    # FreeBSD < 8 doesn't always set the MSG_TRUNC flag when a truncated
-    # datagram is received (issue #13001).
-    @support.requires_freebsd_version(8)
     def testRecvmsgTrunc(self):
         # Receive part of message, check for truncation indicators.
         msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock,
@@ -2610,7 +2607,6 @@
         self.assertEqual(ancdata, [])
         self.checkFlags(flags, eor=False)
 
-    @support.requires_freebsd_version(8)
     def _testRecvmsgTrunc(self):
         self.sendToServer(MSG)
 
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py
index 007581d..db70dfa 100644
--- a/Lib/test/test_threading.py
+++ b/Lib/test/test_threading.py
@@ -25,8 +25,7 @@
 # #12316 and #11870), and fork() from a worker thread is known to trigger
 # problems with some operating systems (issue #3863): skip problematic tests
 # on platforms known to behave badly.
-platforms_to_skip = ('freebsd4', 'freebsd5', 'freebsd6', 'netbsd5',
-                     'hp-ux11')
+platforms_to_skip = ('netbsd5', 'hp-ux11')
 
 
 # A trivial mutable counter.
diff --git a/Lib/unittest/test/test_break.py b/Lib/unittest/test/test_break.py
index 2c75019..aa2c69e 100644
--- a/Lib/unittest/test/test_break.py
+++ b/Lib/unittest/test/test_break.py
@@ -10,8 +10,6 @@
 
 @unittest.skipUnless(hasattr(os, 'kill'), "Test requires os.kill")
 @unittest.skipIf(sys.platform =="win32", "Test cannot run on Windows")
-@unittest.skipIf(sys.platform == 'freebsd6', "Test kills regrtest on freebsd6 "
-    "if threads have been used")
 class TestBreak(unittest.TestCase):
     int_handler = None
 
@@ -267,22 +265,16 @@
 
 @unittest.skipUnless(hasattr(os, 'kill'), "Test requires os.kill")
 @unittest.skipIf(sys.platform =="win32", "Test cannot run on Windows")
-@unittest.skipIf(sys.platform == 'freebsd6', "Test kills regrtest on freebsd6 "
-    "if threads have been used")
 class TestBreakDefaultIntHandler(TestBreak):
     int_handler = signal.default_int_handler
 
 @unittest.skipUnless(hasattr(os, 'kill'), "Test requires os.kill")
 @unittest.skipIf(sys.platform =="win32", "Test cannot run on Windows")
-@unittest.skipIf(sys.platform == 'freebsd6', "Test kills regrtest on freebsd6 "
-    "if threads have been used")
 class TestBreakSignalIgnored(TestBreak):
     int_handler = signal.SIG_IGN
 
 @unittest.skipUnless(hasattr(os, 'kill'), "Test requires os.kill")
 @unittest.skipIf(sys.platform =="win32", "Test cannot run on Windows")
-@unittest.skipIf(sys.platform == 'freebsd6', "Test kills regrtest on freebsd6 "
-    "if threads have been used")
 class TestBreakSignalDefault(TestBreak):
     int_handler = signal.SIG_DFL
 
diff --git a/Misc/NEWS.d/next/Build/2018-01-18-11-10-52.bpo-32593.XIrf3v.rst b/Misc/NEWS.d/next/Build/2018-01-18-11-10-52.bpo-32593.XIrf3v.rst
new file mode 100644
index 0000000..e033cf2
--- /dev/null
+++ b/Misc/NEWS.d/next/Build/2018-01-18-11-10-52.bpo-32593.XIrf3v.rst
@@ -0,0 +1 @@
+Drop support of FreeBSD 9 and older.
diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h
index b7463c0..6971405 100644
--- a/Python/thread_pthread.h
+++ b/Python/thread_pthread.h
@@ -56,16 +56,6 @@
 #endif
 #endif
 
-/* Before FreeBSD 5.4, system scope threads was very limited resource
-   in default setting.  So the process scope is preferred to get
-   enough number of threads to work. */
-#ifdef __FreeBSD__
-#include <osreldate.h>
-#if __FreeBSD_version >= 500000 && __FreeBSD_version < 504101
-#undef PTHREAD_SYSTEM_SCHED_SUPPORTED
-#endif
-#endif
-
 #if !defined(pthread_attr_default)
 #  define pthread_attr_default ((pthread_attr_t *)NULL)
 #endif
diff --git a/configure.ac b/configure.ac
index 39e2e8e..03b0f50 100644
--- a/configure.ac
+++ b/configure.ac
@@ -481,10 +481,6 @@
   # but used in struct sockaddr.sa_family. Reported by Tim Rice.
   SCO_SV/3.2)
     define_xopen_source=no;;
-  # On FreeBSD 4, the math functions C89 does not cover are never defined
-  # with _XOPEN_SOURCE and __BSD_VISIBLE does not re-enable them.
-  FreeBSD/4.*)
-    define_xopen_source=no;;
   # On MacOS X 10.2, a bug in ncurses.h means that it craps out if
   # _XOPEN_EXTENDED_SOURCE is defined. Apparently, this is fixed in 10.3, which
   # identifies itself as Darwin/7.*
diff --git a/setup.py b/setup.py
index c23628a..1da40a4 100644
--- a/setup.py
+++ b/setup.py
@@ -1571,12 +1571,6 @@
             macros = dict()
             libraries = []
 
-        elif host_platform in ('freebsd4', 'freebsd5', 'freebsd6', 'freebsd7', 'freebsd8'):
-            # FreeBSD's P1003.1b semaphore support is very experimental
-            # and has many known problems. (as of June 2008)
-            macros = dict()
-            libraries = []
-
         elif host_platform.startswith('openbsd'):
             macros = dict()
             libraries = []