https://github.com/python/cpython/commit/dbfc37a5f86196c642e63aee91be70752ad8604c
commit: dbfc37a5f86196c642e63aee91be70752ad8604c
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: Yhg1s <[email protected]>
date: 2024-09-29T18:06:53-07:00
summary:

[3.13] gh-123797: Check for runtime availability of `ptsname_r` on macos 
(GH-123806) (#124270)

gh-123797: Check for runtime availability of `ptsname_r` on macos (GH-123806)
(cherry picked from commit 3e36e5aef18e326f5d1081d73ee8d8fefa1d82f8)

Co-authored-by: sobolevn <[email protected]>

files:
A Misc/NEWS.d/next/macOS/2024-09-07-12-14-54.gh-issue-123797.yFDeug.rst
M Lib/test/test_posix.py
M Modules/posixmodule.c

diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py
index 908354cb8574d1..5d2decffd720f0 100644
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -2140,6 +2140,13 @@ def test_stat(self):
             with self.assertRaisesRegex(NotImplementedError, "dir_fd 
unavailable"):
                 os.stat("file", dir_fd=0)
 
+    def test_ptsname_r(self):
+        self._verify_available("HAVE_PTSNAME_R")
+        if self.mac_ver >= (10, 13, 4):
+            self.assertIn("HAVE_PTSNAME_R", posix._have_functions)
+        else:
+            self.assertNotIn("HAVE_PTSNAME_R", posix._have_functions)
+
     def test_access(self):
         self._verify_available("HAVE_FACCESSAT")
         if self.mac_ver >= (10, 10):
diff --git 
a/Misc/NEWS.d/next/macOS/2024-09-07-12-14-54.gh-issue-123797.yFDeug.rst 
b/Misc/NEWS.d/next/macOS/2024-09-07-12-14-54.gh-issue-123797.yFDeug.rst
new file mode 100644
index 00000000000000..f126bd0d39bf59
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2024-09-07-12-14-54.gh-issue-123797.yFDeug.rst
@@ -0,0 +1 @@
+Check for runtime availability of ``ptsname_r`` function on macos.
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 124d608508b3cd..51e34b5f4b74fc 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -125,6 +125,7 @@
 #  define HAVE_PWRITEV_RUNTIME __builtin_available(macOS 11.0, iOS 14.0, tvOS 
14.0, watchOS 7.0, *)
 #  define HAVE_MKFIFOAT_RUNTIME __builtin_available(macOS 13.0, iOS 16.0, tvOS 
16.0, watchOS 9.0, *)
 #  define HAVE_MKNODAT_RUNTIME __builtin_available(macOS 13.0, iOS 16.0, tvOS 
16.0, watchOS 9.0, *)
+#  define HAVE_PTSNAME_R_RUNTIME __builtin_available(macOS 10.13.4, iOS 11.3, 
tvOS 11.3, watchOS 4.3, *)
 
 #  define HAVE_POSIX_SPAWN_SETSID_RUNTIME __builtin_available(macOS 10.15, *)
 
@@ -206,6 +207,10 @@
 #    define HAVE_MKNODAT_RUNTIME (mknodat != NULL)
 #  endif
 
+#  ifdef HAVE_PTSNAME_R
+#    define HAVE_PTSNAME_R_RUNTIME (ptsname_r != NULL)
+#  endif
+
 #endif
 
 #ifdef HAVE_FUTIMESAT
@@ -231,6 +236,7 @@
 #  define HAVE_PWRITEV_RUNTIME 1
 #  define HAVE_MKFIFOAT_RUNTIME 1
 #  define HAVE_MKNODAT_RUNTIME 1
+#  define HAVE_PTSNAME_R_RUNTIME 1
 #endif
 
 
@@ -8635,6 +8641,19 @@ os_unlockpt_impl(PyObject *module, int fd)
 #endif /* HAVE_UNLOCKPT */
 
 #if defined(HAVE_PTSNAME) || defined(HAVE_PTSNAME_R)
+static PyObject *
+py_ptsname(int fd)
+{
+    // POSIX manpage: Upon failure, ptsname() shall return a null pointer
+    // and may set errno. Always initialize errno to avoid undefined behavior.
+    errno = 0;
+    char *name = ptsname(fd);
+    if (name == NULL) {
+        return posix_error();
+    }
+    return PyUnicode_DecodeFSDefault(name);
+}
+
 /*[clinic input]
 os.ptsname
 
@@ -8656,22 +8675,22 @@ os_ptsname_impl(PyObject *module, int fd)
     int ret;
     char name[MAXPATHLEN+1];
 
-    ret = ptsname_r(fd, name, sizeof(name));
+    if (HAVE_PTSNAME_R_RUNTIME) {
+        ret = ptsname_r(fd, name, sizeof(name));
+    }
+    else {
+        // fallback to ptsname() if ptsname_r() is not available in runtime.
+        return py_ptsname(fd);
+    }
     if (ret != 0) {
         errno = ret;
         return posix_error();
     }
-#else
-    char *name;
-
-    name = ptsname(fd);
-    /* POSIX manpage: Upon failure, ptsname() shall return a null pointer and 
may set errno.
-       *MAY* set errno? Hmm... */
-    if (name == NULL)
-        return posix_error();
-#endif /* HAVE_PTSNAME_R */
 
     return PyUnicode_DecodeFSDefault(name);
+#else
+    return py_ptsname(fd);
+#endif /* HAVE_PTSNAME_R */
 }
 #endif /* defined(HAVE_PTSNAME) || defined(HAVE_PTSNAME_R) */
 
@@ -17739,6 +17758,9 @@ PROBE(probe_futimens, HAVE_FUTIMENS_RUNTIME)
 PROBE(probe_utimensat, HAVE_UTIMENSAT_RUNTIME)
 #endif
 
+#ifdef HAVE_PTSNAME_R
+PROBE(probe_ptsname_r, HAVE_PTSNAME_R_RUNTIME)
+#endif
 
 
 
@@ -17879,6 +17901,10 @@ static const struct have_function {
     { "HAVE_UTIMENSAT", probe_utimensat },
 #endif
 
+#ifdef HAVE_PTSNAME_R
+    { "HAVE_PTSNAME_R", probe_ptsname_r },
+#endif
+
 #ifdef MS_WINDOWS
     { "MS_WINDOWS", NULL },
 #endif

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to