mirror of
https://github.com/python/cpython.git
synced 2025-11-01 02:38:53 +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
|
|
@ -8358,6 +8358,149 @@ error:
|
|||
#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 */
|
||||
#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
|
||||
# define DEV_PTY_FILE "/dev/ptc"
|
||||
|
|
@ -16275,6 +16418,10 @@ static PyMethodDef posix_methods[] = {
|
|||
OS_SCHED_YIELD_METHODDEF
|
||||
OS_SCHED_SETAFFINITY_METHODDEF
|
||||
OS_SCHED_GETAFFINITY_METHODDEF
|
||||
OS_POSIX_OPENPT_METHODDEF
|
||||
OS_GRANTPT_METHODDEF
|
||||
OS_UNLOCKPT_METHODDEF
|
||||
OS_PTSNAME_METHODDEF
|
||||
OS_OPENPTY_METHODDEF
|
||||
OS_LOGIN_TTY_METHODDEF
|
||||
OS_FORKPTY_METHODDEF
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue