mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	gh-85984: Add POSIX pseudo-terminal functions. (GH-102413)
Signed-off-by: Soumendra Ganguly <soumendraganguly@gmail.com> Co-authored-by: Gregory P. Smith <greg@krypto.org> Co-authored-by: Petr Viktorin <encukou@gmail.com>
This commit is contained in:
		
							parent
							
								
									0f54ee4c6c
								
							
						
					
					
						commit
						e351ca3c20
					
				
					 9 changed files with 468 additions and 11 deletions
				
			
		|  | @ -97,12 +97,16 @@ | ||||||
|     ('c:func', 'free'), |     ('c:func', 'free'), | ||||||
|     ('c:func', 'gettimeofday'), |     ('c:func', 'gettimeofday'), | ||||||
|     ('c:func', 'gmtime'), |     ('c:func', 'gmtime'), | ||||||
|  |     ('c:func', 'grantpt'), | ||||||
|     ('c:func', 'localeconv'), |     ('c:func', 'localeconv'), | ||||||
|     ('c:func', 'localtime'), |     ('c:func', 'localtime'), | ||||||
|     ('c:func', 'main'), |     ('c:func', 'main'), | ||||||
|     ('c:func', 'malloc'), |     ('c:func', 'malloc'), | ||||||
|     ('c:func', 'mktime'), |     ('c:func', 'mktime'), | ||||||
|  |     ('c:func', 'posix_openpt'), | ||||||
|     ('c:func', 'printf'), |     ('c:func', 'printf'), | ||||||
|  |     ('c:func', 'ptsname'), | ||||||
|  |     ('c:func', 'ptsname_r'), | ||||||
|     ('c:func', 'realloc'), |     ('c:func', 'realloc'), | ||||||
|     ('c:func', 'snprintf'), |     ('c:func', 'snprintf'), | ||||||
|     ('c:func', 'sprintf'), |     ('c:func', 'sprintf'), | ||||||
|  | @ -110,6 +114,7 @@ | ||||||
|     ('c:func', 'strftime'), |     ('c:func', 'strftime'), | ||||||
|     ('c:func', 'system'), |     ('c:func', 'system'), | ||||||
|     ('c:func', 'time'), |     ('c:func', 'time'), | ||||||
|  |     ('c:func', 'unlockpt'), | ||||||
|     ('c:func', 'vsnprintf'), |     ('c:func', 'vsnprintf'), | ||||||
|     # Standard C types |     # Standard C types | ||||||
|     ('c:type', 'FILE'), |     ('c:type', 'FILE'), | ||||||
|  |  | ||||||
|  | @ -1122,6 +1122,20 @@ as internal buffering of data. | ||||||
|    .. versionchanged:: 3.12 |    .. versionchanged:: 3.12 | ||||||
|       Added support for pipes on Windows. |       Added support for pipes on Windows. | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | .. function:: grantpt(fd, /) | ||||||
|  | 
 | ||||||
|  |    Grant access to the slave pseudo-terminal device associated with the | ||||||
|  |    master pseudo-terminal device to which the file descriptor *fd* refers. | ||||||
|  |    The file descriptor *fd* is not closed upon failure. | ||||||
|  | 
 | ||||||
|  |    Calls the C standard library function :c:func:`grantpt`. | ||||||
|  | 
 | ||||||
|  |    .. availability:: Unix, not Emscripten, not WASI. | ||||||
|  | 
 | ||||||
|  |    .. versionadded:: 3.13 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| .. function:: isatty(fd, /) | .. function:: isatty(fd, /) | ||||||
| 
 | 
 | ||||||
|    Return ``True`` if the file descriptor *fd* is open and connected to a |    Return ``True`` if the file descriptor *fd* is open and connected to a | ||||||
|  | @ -1429,6 +1443,23 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo | ||||||
|    .. versionadded:: 3.3 |    .. versionadded:: 3.3 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | .. function:: posix_openpt(oflag, /) | ||||||
|  | 
 | ||||||
|  |    Open and return a file descriptor for a master pseudo-terminal device. | ||||||
|  | 
 | ||||||
|  |    Calls the C standard library function :c:func:`posix_openpt`. The *oflag* | ||||||
|  |    argument is used to set file status flags and file access modes as | ||||||
|  |    specified in the manual page of :c:func:`posix_openpt` of your system. | ||||||
|  | 
 | ||||||
|  |    The returned file descriptor is :ref:`non-inheritable <fd_inheritance>`. | ||||||
|  |    If the value :data:`O_CLOEXEC` is available on the system, it is added to | ||||||
|  |    *oflag*. | ||||||
|  | 
 | ||||||
|  |    .. availability:: Unix, not Emscripten, not WASI. | ||||||
|  | 
 | ||||||
|  |    .. versionadded:: 3.13 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| .. function:: preadv(fd, buffers, offset, flags=0, /) | .. function:: preadv(fd, buffers, offset, flags=0, /) | ||||||
| 
 | 
 | ||||||
|    Read from a file descriptor *fd* at a position of *offset* into mutable |    Read from a file descriptor *fd* at a position of *offset* into mutable | ||||||
|  | @ -1486,6 +1517,21 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo | ||||||
|    .. versionadded:: 3.7 |    .. versionadded:: 3.7 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | .. function:: ptsname(fd, /) | ||||||
|  | 
 | ||||||
|  |    Return the name of the slave pseudo-terminal device associated with the | ||||||
|  |    master pseudo-terminal device to which the file descriptor *fd* refers. | ||||||
|  |    The file descriptor *fd* is not closed upon failure. | ||||||
|  | 
 | ||||||
|  |    Calls the reentrant C standard library function :c:func:`ptsname_r` if | ||||||
|  |    it is available; otherwise, the C standard library function | ||||||
|  |    :c:func:`ptsname`, which is not guaranteed to be thread-safe, is called. | ||||||
|  | 
 | ||||||
|  |    .. availability:: Unix, not Emscripten, not WASI. | ||||||
|  | 
 | ||||||
|  |    .. versionadded:: 3.13 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| .. function:: pwrite(fd, str, offset, /) | .. function:: pwrite(fd, str, offset, /) | ||||||
| 
 | 
 | ||||||
|    Write the bytestring in *str* to file descriptor *fd* at position of |    Write the bytestring in *str* to file descriptor *fd* at position of | ||||||
|  | @ -1738,6 +1784,19 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo | ||||||
|    .. availability:: Unix. |    .. availability:: Unix. | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | .. function:: unlockpt(fd, /) | ||||||
|  | 
 | ||||||
|  |    Unlock the slave pseudo-terminal device associated with the master | ||||||
|  |    pseudo-terminal device to which the file descriptor *fd* refers. | ||||||
|  |    The file descriptor *fd* is not closed upon failure. | ||||||
|  | 
 | ||||||
|  |    Calls the C standard library function :c:func:`unlockpt`. | ||||||
|  | 
 | ||||||
|  |    .. availability:: Unix, not Emscripten, not WASI. | ||||||
|  | 
 | ||||||
|  |    .. versionadded:: 3.13 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| .. function:: write(fd, str, /) | .. function:: write(fd, str, /) | ||||||
| 
 | 
 | ||||||
|    Write the bytestring in *str* to file descriptor *fd*. |    Write the bytestring in *str* to file descriptor *fd*. | ||||||
|  |  | ||||||
|  | @ -4536,13 +4536,46 @@ def test_dup2(self): | ||||||
|         self.assertEqual(os.dup2(fd, fd3, inheritable=False), fd3) |         self.assertEqual(os.dup2(fd, fd3, inheritable=False), fd3) | ||||||
|         self.assertFalse(os.get_inheritable(fd3)) |         self.assertFalse(os.get_inheritable(fd3)) | ||||||
| 
 | 
 | ||||||
|     @unittest.skipUnless(hasattr(os, 'openpty'), "need os.openpty()") | @unittest.skipUnless(hasattr(os, 'openpty'), "need os.openpty()") | ||||||
|  | class PseudoterminalTests(unittest.TestCase): | ||||||
|  |     def open_pty(self): | ||||||
|  |         """Open a pty fd-pair, and schedule cleanup for it""" | ||||||
|  |         main_fd, second_fd = os.openpty() | ||||||
|  |         self.addCleanup(os.close, main_fd) | ||||||
|  |         self.addCleanup(os.close, second_fd) | ||||||
|  |         return main_fd, second_fd | ||||||
|  | 
 | ||||||
|     def test_openpty(self): |     def test_openpty(self): | ||||||
|         master_fd, slave_fd = os.openpty() |         main_fd, second_fd = self.open_pty() | ||||||
|         self.addCleanup(os.close, master_fd) |         self.assertEqual(os.get_inheritable(main_fd), False) | ||||||
|         self.addCleanup(os.close, slave_fd) |         self.assertEqual(os.get_inheritable(second_fd), False) | ||||||
|         self.assertEqual(os.get_inheritable(master_fd), False) | 
 | ||||||
|         self.assertEqual(os.get_inheritable(slave_fd), False) |     @unittest.skipUnless(hasattr(os, 'ptsname'), "need os.ptsname()") | ||||||
|  |     @unittest.skipUnless(hasattr(os, 'O_RDWR'), "need os.O_RDWR") | ||||||
|  |     @unittest.skipUnless(hasattr(os, 'O_NOCTTY'), "need os.O_NOCTTY") | ||||||
|  |     def test_open_via_ptsname(self): | ||||||
|  |         main_fd, second_fd = self.open_pty() | ||||||
|  |         second_path = os.ptsname(main_fd) | ||||||
|  |         reopened_second_fd = os.open(second_path, os.O_RDWR|os.O_NOCTTY) | ||||||
|  |         self.addCleanup(os.close, reopened_second_fd) | ||||||
|  |         os.write(reopened_second_fd, b'foo') | ||||||
|  |         self.assertEqual(os.read(main_fd, 3), b'foo') | ||||||
|  | 
 | ||||||
|  |     @unittest.skipUnless(hasattr(os, 'posix_openpt'), "need os.posix_openpt()") | ||||||
|  |     @unittest.skipUnless(hasattr(os, 'grantpt'), "need os.grantpt()") | ||||||
|  |     @unittest.skipUnless(hasattr(os, 'unlockpt'), "need os.unlockpt()") | ||||||
|  |     @unittest.skipUnless(hasattr(os, 'ptsname'), "need os.ptsname()") | ||||||
|  |     @unittest.skipUnless(hasattr(os, 'O_RDWR'), "need os.O_RDWR") | ||||||
|  |     @unittest.skipUnless(hasattr(os, 'O_NOCTTY'), "need os.O_NOCTTY") | ||||||
|  |     def test_posix_pty_functions(self): | ||||||
|  |         mother_fd = os.posix_openpt(os.O_RDWR|os.O_NOCTTY) | ||||||
|  |         self.addCleanup(os.close, mother_fd) | ||||||
|  |         os.grantpt(mother_fd) | ||||||
|  |         os.unlockpt(mother_fd) | ||||||
|  |         son_path = os.ptsname(mother_fd) | ||||||
|  |         son_fd = os.open(son_path, os.O_RDWR|os.O_NOCTTY) | ||||||
|  |         self.addCleanup(os.close, son_fd) | ||||||
|  |         self.assertEqual(os.ptsname(mother_fd), os.ttyname(son_fd)) | ||||||
| 
 | 
 | ||||||
|     @unittest.skipUnless(hasattr(os, 'spawnl'), "need os.openpty()") |     @unittest.skipUnless(hasattr(os, 'spawnl'), "need os.openpty()") | ||||||
|     def test_pipe_spawnl(self): |     def test_pipe_spawnl(self): | ||||||
|  |  | ||||||
|  | @ -0,0 +1,2 @@ | ||||||
|  | Add POSIX pseudo-terminal functions :func:`os.posix_openpt`, | ||||||
|  | :func:`os.grantpt`, :func:`os.unlockpt`, and :func:`os.ptsname`. | ||||||
							
								
								
									
										168
									
								
								Modules/clinic/posixmodule.c.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										168
									
								
								Modules/clinic/posixmodule.c.h
									
										
									
										generated
									
									
									
								
							|  | @ -4465,6 +4465,156 @@ exit: | ||||||
| 
 | 
 | ||||||
| #endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETAFFINITY) */ | #endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETAFFINITY) */ | ||||||
| 
 | 
 | ||||||
|  | #if defined(HAVE_POSIX_OPENPT) | ||||||
|  | 
 | ||||||
|  | PyDoc_STRVAR(os_posix_openpt__doc__, | ||||||
|  | "posix_openpt($module, oflag, /)\n" | ||||||
|  | "--\n" | ||||||
|  | "\n" | ||||||
|  | "Open and return a file descriptor for a master pseudo-terminal device.\n" | ||||||
|  | "\n" | ||||||
|  | "Performs a posix_openpt() C function call. The oflag argument is used to\n" | ||||||
|  | "set file status flags and file access modes as specified in the manual page\n" | ||||||
|  | "of posix_openpt() of your system."); | ||||||
|  | 
 | ||||||
|  | #define OS_POSIX_OPENPT_METHODDEF    \ | ||||||
|  |     {"posix_openpt", (PyCFunction)os_posix_openpt, METH_O, os_posix_openpt__doc__}, | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | os_posix_openpt_impl(PyObject *module, int oflag); | ||||||
|  | 
 | ||||||
|  | static PyObject * | ||||||
|  | os_posix_openpt(PyObject *module, PyObject *arg) | ||||||
|  | { | ||||||
|  |     PyObject *return_value = NULL; | ||||||
|  |     int oflag; | ||||||
|  |     int _return_value; | ||||||
|  | 
 | ||||||
|  |     oflag = PyLong_AsInt(arg); | ||||||
|  |     if (oflag == -1 && PyErr_Occurred()) { | ||||||
|  |         goto exit; | ||||||
|  |     } | ||||||
|  |     _return_value = os_posix_openpt_impl(module, oflag); | ||||||
|  |     if ((_return_value == -1) && PyErr_Occurred()) { | ||||||
|  |         goto exit; | ||||||
|  |     } | ||||||
|  |     return_value = PyLong_FromLong((long)_return_value); | ||||||
|  | 
 | ||||||
|  | exit: | ||||||
|  |     return return_value; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif /* defined(HAVE_POSIX_OPENPT) */ | ||||||
|  | 
 | ||||||
|  | #if defined(HAVE_GRANTPT) | ||||||
|  | 
 | ||||||
|  | PyDoc_STRVAR(os_grantpt__doc__, | ||||||
|  | "grantpt($module, fd, /)\n" | ||||||
|  | "--\n" | ||||||
|  | "\n" | ||||||
|  | "Grant access to the slave pseudo-terminal device.\n" | ||||||
|  | "\n" | ||||||
|  | "  fd\n" | ||||||
|  | "    File descriptor of a master pseudo-terminal device.\n" | ||||||
|  | "\n" | ||||||
|  | "Performs a grantpt() C function call."); | ||||||
|  | 
 | ||||||
|  | #define OS_GRANTPT_METHODDEF    \ | ||||||
|  |     {"grantpt", (PyCFunction)os_grantpt, METH_O, os_grantpt__doc__}, | ||||||
|  | 
 | ||||||
|  | static PyObject * | ||||||
|  | os_grantpt_impl(PyObject *module, int fd); | ||||||
|  | 
 | ||||||
|  | static PyObject * | ||||||
|  | os_grantpt(PyObject *module, PyObject *arg) | ||||||
|  | { | ||||||
|  |     PyObject *return_value = NULL; | ||||||
|  |     int fd; | ||||||
|  | 
 | ||||||
|  |     if (!_PyLong_FileDescriptor_Converter(arg, &fd)) { | ||||||
|  |         goto exit; | ||||||
|  |     } | ||||||
|  |     return_value = os_grantpt_impl(module, fd); | ||||||
|  | 
 | ||||||
|  | exit: | ||||||
|  |     return return_value; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif /* defined(HAVE_GRANTPT) */ | ||||||
|  | 
 | ||||||
|  | #if defined(HAVE_UNLOCKPT) | ||||||
|  | 
 | ||||||
|  | PyDoc_STRVAR(os_unlockpt__doc__, | ||||||
|  | "unlockpt($module, fd, /)\n" | ||||||
|  | "--\n" | ||||||
|  | "\n" | ||||||
|  | "Unlock a pseudo-terminal master/slave pair.\n" | ||||||
|  | "\n" | ||||||
|  | "  fd\n" | ||||||
|  | "    File descriptor of a master pseudo-terminal device.\n" | ||||||
|  | "\n" | ||||||
|  | "Performs an unlockpt() C function call."); | ||||||
|  | 
 | ||||||
|  | #define OS_UNLOCKPT_METHODDEF    \ | ||||||
|  |     {"unlockpt", (PyCFunction)os_unlockpt, METH_O, os_unlockpt__doc__}, | ||||||
|  | 
 | ||||||
|  | static PyObject * | ||||||
|  | os_unlockpt_impl(PyObject *module, int fd); | ||||||
|  | 
 | ||||||
|  | static PyObject * | ||||||
|  | os_unlockpt(PyObject *module, PyObject *arg) | ||||||
|  | { | ||||||
|  |     PyObject *return_value = NULL; | ||||||
|  |     int fd; | ||||||
|  | 
 | ||||||
|  |     if (!_PyLong_FileDescriptor_Converter(arg, &fd)) { | ||||||
|  |         goto exit; | ||||||
|  |     } | ||||||
|  |     return_value = os_unlockpt_impl(module, fd); | ||||||
|  | 
 | ||||||
|  | exit: | ||||||
|  |     return return_value; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif /* defined(HAVE_UNLOCKPT) */ | ||||||
|  | 
 | ||||||
|  | #if (defined(HAVE_PTSNAME) || defined(HAVE_PTSNAME_R)) | ||||||
|  | 
 | ||||||
|  | PyDoc_STRVAR(os_ptsname__doc__, | ||||||
|  | "ptsname($module, fd, /)\n" | ||||||
|  | "--\n" | ||||||
|  | "\n" | ||||||
|  | "Return the name of the slave pseudo-terminal device.\n" | ||||||
|  | "\n" | ||||||
|  | "  fd\n" | ||||||
|  | "    File descriptor of a master pseudo-terminal device.\n" | ||||||
|  | "\n" | ||||||
|  | "If the ptsname_r() C function is available, it is called;\n" | ||||||
|  | "otherwise, performs a ptsname() C function call."); | ||||||
|  | 
 | ||||||
|  | #define OS_PTSNAME_METHODDEF    \ | ||||||
|  |     {"ptsname", (PyCFunction)os_ptsname, METH_O, os_ptsname__doc__}, | ||||||
|  | 
 | ||||||
|  | static PyObject * | ||||||
|  | os_ptsname_impl(PyObject *module, int fd); | ||||||
|  | 
 | ||||||
|  | static PyObject * | ||||||
|  | os_ptsname(PyObject *module, PyObject *arg) | ||||||
|  | { | ||||||
|  |     PyObject *return_value = NULL; | ||||||
|  |     int fd; | ||||||
|  | 
 | ||||||
|  |     if (!_PyLong_FileDescriptor_Converter(arg, &fd)) { | ||||||
|  |         goto exit; | ||||||
|  |     } | ||||||
|  |     return_value = os_ptsname_impl(module, fd); | ||||||
|  | 
 | ||||||
|  | exit: | ||||||
|  |     return return_value; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif /* (defined(HAVE_PTSNAME) || defined(HAVE_PTSNAME_R)) */ | ||||||
|  | 
 | ||||||
| #if (defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)) | #if (defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)) | ||||||
| 
 | 
 | ||||||
| PyDoc_STRVAR(os_openpty__doc__, | PyDoc_STRVAR(os_openpty__doc__, | ||||||
|  | @ -11991,6 +12141,22 @@ os__supports_virtual_terminal(PyObject *module, PyObject *Py_UNUSED(ignored)) | ||||||
|     #define OS_SCHED_GETAFFINITY_METHODDEF |     #define OS_SCHED_GETAFFINITY_METHODDEF | ||||||
| #endif /* !defined(OS_SCHED_GETAFFINITY_METHODDEF) */ | #endif /* !defined(OS_SCHED_GETAFFINITY_METHODDEF) */ | ||||||
| 
 | 
 | ||||||
|  | #ifndef OS_POSIX_OPENPT_METHODDEF | ||||||
|  |     #define OS_POSIX_OPENPT_METHODDEF | ||||||
|  | #endif /* !defined(OS_POSIX_OPENPT_METHODDEF) */ | ||||||
|  | 
 | ||||||
|  | #ifndef OS_GRANTPT_METHODDEF | ||||||
|  |     #define OS_GRANTPT_METHODDEF | ||||||
|  | #endif /* !defined(OS_GRANTPT_METHODDEF) */ | ||||||
|  | 
 | ||||||
|  | #ifndef OS_UNLOCKPT_METHODDEF | ||||||
|  |     #define OS_UNLOCKPT_METHODDEF | ||||||
|  | #endif /* !defined(OS_UNLOCKPT_METHODDEF) */ | ||||||
|  | 
 | ||||||
|  | #ifndef OS_PTSNAME_METHODDEF | ||||||
|  |     #define OS_PTSNAME_METHODDEF | ||||||
|  | #endif /* !defined(OS_PTSNAME_METHODDEF) */ | ||||||
|  | 
 | ||||||
| #ifndef OS_OPENPTY_METHODDEF | #ifndef OS_OPENPTY_METHODDEF | ||||||
|     #define OS_OPENPTY_METHODDEF |     #define OS_OPENPTY_METHODDEF | ||||||
| #endif /* !defined(OS_OPENPTY_METHODDEF) */ | #endif /* !defined(OS_OPENPTY_METHODDEF) */ | ||||||
|  | @ -12422,4 +12588,4 @@ os__supports_virtual_terminal(PyObject *module, PyObject *Py_UNUSED(ignored)) | ||||||
| #ifndef OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF | #ifndef OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF | ||||||
|     #define OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF |     #define OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF | ||||||
| #endif /* !defined(OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF) */ | #endif /* !defined(OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF) */ | ||||||
| /*[clinic end generated code: output=18c128534c355d84 input=a9049054013a1b77]*/ | /*[clinic end generated code: output=43e4e557c771358a input=a9049054013a1b77]*/ | ||||||
|  |  | ||||||
|  | @ -8358,6 +8358,149 @@ os_sched_getaffinity_impl(PyObject *module, pid_t pid) | ||||||
| #endif /* HAVE_SCHED_H */ | #endif /* HAVE_SCHED_H */ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | #ifdef HAVE_POSIX_OPENPT | ||||||
|  | /*[clinic input]
 | ||||||
|  | os.posix_openpt -> int | ||||||
|  | 
 | ||||||
|  |     oflag: int | ||||||
|  |     / | ||||||
|  | 
 | ||||||
|  | Open and return a file descriptor for a master pseudo-terminal device. | ||||||
|  | 
 | ||||||
|  | Performs a posix_openpt() C function call. The oflag argument is used to | ||||||
|  | set file status flags and file access modes as specified in the manual page | ||||||
|  | of posix_openpt() of your system. | ||||||
|  | [clinic start generated code]*/ | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | os_posix_openpt_impl(PyObject *module, int oflag) | ||||||
|  | /*[clinic end generated code: output=ee0bc2624305fc79 input=0de33d0e29693caa]*/ | ||||||
|  | { | ||||||
|  |     int fd; | ||||||
|  | 
 | ||||||
|  | #if defined(O_CLOEXEC) | ||||||
|  |     oflag |= O_CLOEXEC; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     fd = posix_openpt(oflag); | ||||||
|  |     if (fd == -1) { | ||||||
|  |         posix_error(); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Just in case, likely a no-op given O_CLOEXEC above.
 | ||||||
|  |     if (_Py_set_inheritable(fd, 0, NULL) < 0) { | ||||||
|  |         close(fd); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return fd; | ||||||
|  | } | ||||||
|  | #endif /* HAVE_POSIX_OPENPT */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAVE_GRANTPT | ||||||
|  | /*[clinic input]
 | ||||||
|  | os.grantpt | ||||||
|  | 
 | ||||||
|  |     fd: fildes | ||||||
|  |         File descriptor of a master pseudo-terminal device. | ||||||
|  |     / | ||||||
|  | 
 | ||||||
|  | Grant access to the slave pseudo-terminal device. | ||||||
|  | 
 | ||||||
|  | Performs a grantpt() C function call. | ||||||
|  | [clinic start generated code]*/ | ||||||
|  | 
 | ||||||
|  | static PyObject * | ||||||
|  | os_grantpt_impl(PyObject *module, int fd) | ||||||
|  | /*[clinic end generated code: output=dfd580015cf548ab input=0668e3b96760e849]*/ | ||||||
|  | { | ||||||
|  |     int ret; | ||||||
|  |     int saved_errno; | ||||||
|  |     PyOS_sighandler_t sig_saved; | ||||||
|  | 
 | ||||||
|  |     sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL); | ||||||
|  | 
 | ||||||
|  |     ret = grantpt(fd); | ||||||
|  |     if (ret == -1) | ||||||
|  |         saved_errno = errno; | ||||||
|  | 
 | ||||||
|  |     PyOS_setsig(SIGCHLD, sig_saved); | ||||||
|  | 
 | ||||||
|  |     if (ret == -1) { | ||||||
|  |         errno = saved_errno; | ||||||
|  |         return posix_error(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Py_RETURN_NONE; | ||||||
|  | } | ||||||
|  | #endif /* HAVE_GRANTPT */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAVE_UNLOCKPT | ||||||
|  | /*[clinic input]
 | ||||||
|  | os.unlockpt | ||||||
|  | 
 | ||||||
|  |     fd: fildes | ||||||
|  |         File descriptor of a master pseudo-terminal device. | ||||||
|  |     / | ||||||
|  | 
 | ||||||
|  | Unlock a pseudo-terminal master/slave pair. | ||||||
|  | 
 | ||||||
|  | Performs an unlockpt() C function call. | ||||||
|  | [clinic start generated code]*/ | ||||||
|  | 
 | ||||||
|  | static PyObject * | ||||||
|  | os_unlockpt_impl(PyObject *module, int fd) | ||||||
|  | /*[clinic end generated code: output=e08d354dec12d30c input=de7ab1f59f69a2b4]*/ | ||||||
|  | { | ||||||
|  |     if (unlockpt(fd) == -1) | ||||||
|  |         return posix_error(); | ||||||
|  | 
 | ||||||
|  |     Py_RETURN_NONE; | ||||||
|  | } | ||||||
|  | #endif /* HAVE_UNLOCKPT */ | ||||||
|  | 
 | ||||||
|  | #if defined(HAVE_PTSNAME) || defined(HAVE_PTSNAME_R) | ||||||
|  | /*[clinic input]
 | ||||||
|  | os.ptsname | ||||||
|  | 
 | ||||||
|  |     fd: fildes | ||||||
|  |         File descriptor of a master pseudo-terminal device. | ||||||
|  |     / | ||||||
|  | 
 | ||||||
|  | Return the name of the slave pseudo-terminal device. | ||||||
|  | 
 | ||||||
|  | If the ptsname_r() C function is available, it is called; | ||||||
|  | otherwise, performs a ptsname() C function call. | ||||||
|  | [clinic start generated code]*/ | ||||||
|  | 
 | ||||||
|  | static PyObject * | ||||||
|  | os_ptsname_impl(PyObject *module, int fd) | ||||||
|  | /*[clinic end generated code: output=ef300fadc5675872 input=1369ccc0546f3130]*/ | ||||||
|  | { | ||||||
|  | #ifdef HAVE_PTSNAME_R | ||||||
|  |     int ret; | ||||||
|  |     char name[MAXPATHLEN+1]; | ||||||
|  | 
 | ||||||
|  |     ret = ptsname_r(fd, name, sizeof(name)); | ||||||
|  |     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); | ||||||
|  | } | ||||||
|  | #endif /* defined(HAVE_PTSNAME) || defined(HAVE_PTSNAME_R) */ | ||||||
|  | 
 | ||||||
| /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */ | /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */ | ||||||
| #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX) | #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX) | ||||||
| #  define DEV_PTY_FILE "/dev/ptc" | #  define DEV_PTY_FILE "/dev/ptc" | ||||||
|  | @ -16275,6 +16418,10 @@ static PyMethodDef posix_methods[] = { | ||||||
|     OS_SCHED_YIELD_METHODDEF |     OS_SCHED_YIELD_METHODDEF | ||||||
|     OS_SCHED_SETAFFINITY_METHODDEF |     OS_SCHED_SETAFFINITY_METHODDEF | ||||||
|     OS_SCHED_GETAFFINITY_METHODDEF |     OS_SCHED_GETAFFINITY_METHODDEF | ||||||
|  |     OS_POSIX_OPENPT_METHODDEF | ||||||
|  |     OS_GRANTPT_METHODDEF | ||||||
|  |     OS_UNLOCKPT_METHODDEF | ||||||
|  |     OS_PTSNAME_METHODDEF | ||||||
|     OS_OPENPTY_METHODDEF |     OS_OPENPTY_METHODDEF | ||||||
|     OS_LOGIN_TTY_METHODDEF |     OS_LOGIN_TTY_METHODDEF | ||||||
|     OS_FORKPTY_METHODDEF |     OS_FORKPTY_METHODDEF | ||||||
|  |  | ||||||
							
								
								
									
										30
									
								
								configure
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								configure
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -17637,6 +17637,12 @@ if test "x$ac_cv_func_getwd" = xyes | ||||||
| then : | then : | ||||||
|   printf "%s\n" "#define HAVE_GETWD 1" >>confdefs.h |   printf "%s\n" "#define HAVE_GETWD 1" >>confdefs.h | ||||||
| 
 | 
 | ||||||
|  | fi | ||||||
|  | ac_fn_c_check_func "$LINENO" "grantpt" "ac_cv_func_grantpt" | ||||||
|  | if test "x$ac_cv_func_grantpt" = xyes | ||||||
|  | then : | ||||||
|  |   printf "%s\n" "#define HAVE_GRANTPT 1" >>confdefs.h | ||||||
|  | 
 | ||||||
| fi | fi | ||||||
| ac_fn_c_check_func "$LINENO" "if_nameindex" "ac_cv_func_if_nameindex" | ac_fn_c_check_func "$LINENO" "if_nameindex" "ac_cv_func_if_nameindex" | ||||||
| if test "x$ac_cv_func_if_nameindex" = xyes | if test "x$ac_cv_func_if_nameindex" = xyes | ||||||
|  | @ -17823,6 +17829,12 @@ if test "x$ac_cv_func_posix_fallocate" = xyes | ||||||
| then : | then : | ||||||
|   printf "%s\n" "#define HAVE_POSIX_FALLOCATE 1" >>confdefs.h |   printf "%s\n" "#define HAVE_POSIX_FALLOCATE 1" >>confdefs.h | ||||||
| 
 | 
 | ||||||
|  | fi | ||||||
|  | ac_fn_c_check_func "$LINENO" "posix_openpt" "ac_cv_func_posix_openpt" | ||||||
|  | if test "x$ac_cv_func_posix_openpt" = xyes | ||||||
|  | then : | ||||||
|  |   printf "%s\n" "#define HAVE_POSIX_OPENPT 1" >>confdefs.h | ||||||
|  | 
 | ||||||
| fi | fi | ||||||
| ac_fn_c_check_func "$LINENO" "posix_spawn" "ac_cv_func_posix_spawn" | ac_fn_c_check_func "$LINENO" "posix_spawn" "ac_cv_func_posix_spawn" | ||||||
| if test "x$ac_cv_func_posix_spawn" = xyes | if test "x$ac_cv_func_posix_spawn" = xyes | ||||||
|  | @ -17877,6 +17889,18 @@ if test "x$ac_cv_func_pthread_kill" = xyes | ||||||
| then : | then : | ||||||
|   printf "%s\n" "#define HAVE_PTHREAD_KILL 1" >>confdefs.h |   printf "%s\n" "#define HAVE_PTHREAD_KILL 1" >>confdefs.h | ||||||
| 
 | 
 | ||||||
|  | fi | ||||||
|  | ac_fn_c_check_func "$LINENO" "ptsname" "ac_cv_func_ptsname" | ||||||
|  | if test "x$ac_cv_func_ptsname" = xyes | ||||||
|  | then : | ||||||
|  |   printf "%s\n" "#define HAVE_PTSNAME 1" >>confdefs.h | ||||||
|  | 
 | ||||||
|  | fi | ||||||
|  | ac_fn_c_check_func "$LINENO" "ptsname_r" "ac_cv_func_ptsname_r" | ||||||
|  | if test "x$ac_cv_func_ptsname_r" = xyes | ||||||
|  | then : | ||||||
|  |   printf "%s\n" "#define HAVE_PTSNAME_R 1" >>confdefs.h | ||||||
|  | 
 | ||||||
| fi | fi | ||||||
| ac_fn_c_check_func "$LINENO" "pwrite" "ac_cv_func_pwrite" | ac_fn_c_check_func "$LINENO" "pwrite" "ac_cv_func_pwrite" | ||||||
| if test "x$ac_cv_func_pwrite" = xyes | if test "x$ac_cv_func_pwrite" = xyes | ||||||
|  | @ -18285,6 +18309,12 @@ if test "x$ac_cv_func_unlinkat" = xyes | ||||||
| then : | then : | ||||||
|   printf "%s\n" "#define HAVE_UNLINKAT 1" >>confdefs.h |   printf "%s\n" "#define HAVE_UNLINKAT 1" >>confdefs.h | ||||||
| 
 | 
 | ||||||
|  | fi | ||||||
|  | ac_fn_c_check_func "$LINENO" "unlockpt" "ac_cv_func_unlockpt" | ||||||
|  | if test "x$ac_cv_func_unlockpt" = xyes | ||||||
|  | then : | ||||||
|  |   printf "%s\n" "#define HAVE_UNLOCKPT 1" >>confdefs.h | ||||||
|  | 
 | ||||||
| fi | fi | ||||||
| ac_fn_c_check_func "$LINENO" "utimensat" "ac_cv_func_utimensat" | ac_fn_c_check_func "$LINENO" "utimensat" "ac_cv_func_utimensat" | ||||||
| if test "x$ac_cv_func_utimensat" = xyes | if test "x$ac_cv_func_utimensat" = xyes | ||||||
|  |  | ||||||
|  | @ -4791,12 +4791,12 @@ AC_CHECK_FUNCS([ \ | ||||||
|   getgrnam_r getgrouplist getgroups gethostname getitimer getloadavg getlogin \ |   getgrnam_r getgrouplist getgroups gethostname getitimer getloadavg getlogin \ | ||||||
|   getpeername getpgid getpid getppid getpriority _getpty \ |   getpeername getpgid getpid getppid getpriority _getpty \ | ||||||
|   getpwent getpwnam_r getpwuid getpwuid_r getresgid getresuid getrusage getsid getspent \ |   getpwent getpwnam_r getpwuid getpwuid_r getresgid getresuid getrusage getsid getspent \ | ||||||
|   getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \ |   getspnam getuid getwd grantpt if_nameindex initgroups kill killpg lchown linkat \ | ||||||
|   lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \ |   lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \ | ||||||
|   mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \ |   mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \ | ||||||
|   pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \ |   pipe2 plock poll posix_fadvise posix_fallocate posix_openpt posix_spawn posix_spawnp \ | ||||||
|   posix_spawn_file_actions_addclosefrom_np \ |   posix_spawn_file_actions_addclosefrom_np \ | ||||||
|   pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \ |   pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill ptsname ptsname_r \ | ||||||
|   pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \ |   pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \ | ||||||
|   rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \ |   rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \ | ||||||
|   sched_setparam sched_setscheduler sem_clockwait sem_getvalue sem_open \ |   sched_setparam sched_setscheduler sem_clockwait sem_getvalue sem_open \ | ||||||
|  | @ -4806,7 +4806,7 @@ AC_CHECK_FUNCS([ \ | ||||||
|   sigfillset siginterrupt sigpending sigrelse sigtimedwait sigwait \ |   sigfillset siginterrupt sigpending sigrelse sigtimedwait sigwait \ | ||||||
|   sigwaitinfo snprintf splice strftime strlcpy strsignal symlinkat sync \ |   sigwaitinfo snprintf splice strftime strlcpy strsignal symlinkat sync \ | ||||||
|   sysconf system tcgetpgrp tcsetpgrp tempnam timegm times tmpfile \ |   sysconf system tcgetpgrp tcsetpgrp tempnam timegm times tmpfile \ | ||||||
|   tmpnam tmpnam_r truncate ttyname umask uname unlinkat utimensat utimes vfork \ |   tmpnam tmpnam_r truncate ttyname umask uname unlinkat unlockpt utimensat utimes vfork \ | ||||||
|   wait wait3 wait4 waitid waitpid wcscoll wcsftime wcsxfrm wmemcmp writev \ |   wait wait3 wait4 waitid waitpid wcscoll wcsftime wcsxfrm wmemcmp writev \ | ||||||
| ]) | ]) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -601,6 +601,9 @@ | ||||||
|    bcopy. */ |    bcopy. */ | ||||||
| #undef HAVE_GLIBC_MEMMOVE_BUG | #undef HAVE_GLIBC_MEMMOVE_BUG | ||||||
| 
 | 
 | ||||||
|  | /* Define to 1 if you have the `grantpt' function. */ | ||||||
|  | #undef HAVE_GRANTPT | ||||||
|  | 
 | ||||||
| /* Define to 1 if you have the <grp.h> header file. */ | /* Define to 1 if you have the <grp.h> header file. */ | ||||||
| #undef HAVE_GRP_H | #undef HAVE_GRP_H | ||||||
| 
 | 
 | ||||||
|  | @ -899,6 +902,9 @@ | ||||||
| /* Define to 1 if you have the `posix_fallocate' function. */ | /* Define to 1 if you have the `posix_fallocate' function. */ | ||||||
| #undef HAVE_POSIX_FALLOCATE | #undef HAVE_POSIX_FALLOCATE | ||||||
| 
 | 
 | ||||||
|  | /* Define to 1 if you have the `posix_openpt' function. */ | ||||||
|  | #undef HAVE_POSIX_OPENPT | ||||||
|  | 
 | ||||||
| /* Define to 1 if you have the `posix_spawn' function. */ | /* Define to 1 if you have the `posix_spawn' function. */ | ||||||
| #undef HAVE_POSIX_SPAWN | #undef HAVE_POSIX_SPAWN | ||||||
| 
 | 
 | ||||||
|  | @ -951,6 +957,12 @@ | ||||||
| /* Define if platform requires stubbed pthreads support */ | /* Define if platform requires stubbed pthreads support */ | ||||||
| #undef HAVE_PTHREAD_STUBS | #undef HAVE_PTHREAD_STUBS | ||||||
| 
 | 
 | ||||||
|  | /* Define to 1 if you have the `ptsname' function. */ | ||||||
|  | #undef HAVE_PTSNAME | ||||||
|  | 
 | ||||||
|  | /* Define to 1 if you have the `ptsname_r' function. */ | ||||||
|  | #undef HAVE_PTSNAME_R | ||||||
|  | 
 | ||||||
| /* Define to 1 if you have the <pty.h> header file. */ | /* Define to 1 if you have the <pty.h> header file. */ | ||||||
| #undef HAVE_PTY_H | #undef HAVE_PTY_H | ||||||
| 
 | 
 | ||||||
|  | @ -1459,6 +1471,9 @@ | ||||||
| /* Define to 1 if you have the `unlinkat' function. */ | /* Define to 1 if you have the `unlinkat' function. */ | ||||||
| #undef HAVE_UNLINKAT | #undef HAVE_UNLINKAT | ||||||
| 
 | 
 | ||||||
|  | /* Define to 1 if you have the `unlockpt' function. */ | ||||||
|  | #undef HAVE_UNLOCKPT | ||||||
|  | 
 | ||||||
| /* Define to 1 if you have the `unshare' function. */ | /* Define to 1 if you have the `unshare' function. */ | ||||||
| #undef HAVE_UNSHARE | #undef HAVE_UNSHARE | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Soumendra Ganguly
						Soumendra Ganguly