Skip to content

Commit ae553b3

Browse files
authored
bpo-41818: Add os.login_tty() for *nix. (#29658)
* Add `os.login_tty(fd)` for Unix. Reviewed-by: Christian Heimes <christian@python.org> Signed-off-by: Gregory P. Smith [Google LLC] <greg@krypto.org>
1 parent 42fee93 commit ae553b3

File tree

7 files changed

+184
-14
lines changed

7 files changed

+184
-14
lines changed

Doc/library/os.rst

+11
Original file line numberDiff line numberDiff line change
@@ -1000,6 +1000,17 @@ as internal buffering of data.
10001000
.. versionadded:: 3.3
10011001

10021002

1003+
.. function:: login_tty(fd)
1004+
1005+
Prepare the tty of which fd is a file descriptor for a new login session.
1006+
Make the calling process a session leader; make the tty the controlling tty,
1007+
the stdin, the stdout, and the stderr of the calling process; close fd.
1008+
1009+
.. availability:: Unix.
1010+
1011+
.. versionadded:: 3.11
1012+
1013+
10031014
.. function:: lseek(fd, pos, how)
10041015

10051016
Set the current position of file descriptor *fd* to position *pos*, modified
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
New function os.login_tty() for Unix.

Modules/clinic/posixmodule.c.h

+40-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/posixmodule.c

+60-9
Original file line numberDiff line numberDiff line change
@@ -7274,22 +7274,21 @@ os_sched_getaffinity_impl(PyObject *module, pid_t pid)
72747274
# define DEV_PTY_FILE "/dev/ptmx"
72757275
#endif
72767276

7277-
#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
7277+
#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_LOGIN_TTY) || defined(HAVE_DEV_PTMX)
72787278
#ifdef HAVE_PTY_H
72797279
#include <pty.h>
7280-
#else
7281-
#ifdef HAVE_LIBUTIL_H
7280+
#ifdef HAVE_UTMP_H
7281+
#include <utmp.h>
7282+
#endif /* HAVE_UTMP_H */
7283+
#elif defined(HAVE_LIBUTIL_H)
72827284
#include <libutil.h>
7283-
#else
7284-
#ifdef HAVE_UTIL_H
7285+
#elif defined(HAVE_UTIL_H)
72857286
#include <util.h>
7286-
#endif /* HAVE_UTIL_H */
7287-
#endif /* HAVE_LIBUTIL_H */
72887287
#endif /* HAVE_PTY_H */
72897288
#ifdef HAVE_STROPTS_H
72907289
#include <stropts.h>
72917290
#endif
7292-
#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
7291+
#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_LOGIN_TTY) || defined(HAVE_DEV_PTMX) */
72937292

72947293

72957294
#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
@@ -7392,6 +7391,56 @@ os_openpty_impl(PyObject *module)
73927391
#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
73937392

73947393

7394+
#if defined(HAVE_SETSID) && defined(TIOCSCTTY)
7395+
#define HAVE_FALLBACK_LOGIN_TTY 1
7396+
#endif /* defined(HAVE_SETSID) && defined(TIOCSCTTY) */
7397+
7398+
#if defined(HAVE_LOGIN_TTY) || defined(HAVE_FALLBACK_LOGIN_TTY)
7399+
/*[clinic input]
7400+
os.login_tty
7401+
7402+
fd: fildes
7403+
/
7404+
7405+
Prepare the tty of which fd is a file descriptor for a new login session.
7406+
7407+
Make the calling process a session leader; make the tty the
7408+
controlling tty, the stdin, the stdout, and the stderr of the
7409+
calling process; close fd.
7410+
[clinic start generated code]*/
7411+
7412+
static PyObject *
7413+
os_login_tty_impl(PyObject *module, int fd)
7414+
/*[clinic end generated code: output=495a79911b4cc1bc input=5f298565099903a2]*/
7415+
{
7416+
#ifdef HAVE_LOGIN_TTY
7417+
if (login_tty(fd) == -1) {
7418+
return posix_error();
7419+
}
7420+
#else /* defined(HAVE_FALLBACK_LOGIN_TTY) */
7421+
/* Establish a new session. */
7422+
if (setsid() == -1) {
7423+
return posix_error();
7424+
}
7425+
7426+
/* The tty becomes the controlling terminal. */
7427+
if (ioctl(fd, TIOCSCTTY, (char *)NULL) == -1) {
7428+
return posix_error();
7429+
}
7430+
7431+
/* The tty becomes stdin/stdout/stderr */
7432+
if (dup2(fd, 0) == -1 || dup2(fd, 1) == -1 || dup2(fd, 2) == -1) {
7433+
return posix_error();
7434+
}
7435+
if (fd > 2) {
7436+
close(fd);
7437+
}
7438+
#endif /* HAVE_LOGIN_TTY */
7439+
Py_RETURN_NONE;
7440+
}
7441+
#endif /* defined(HAVE_LOGIN_TTY) || defined(HAVE_FALLBACK_LOGIN_TTY) */
7442+
7443+
73957444
#ifdef HAVE_FORKPTY
73967445
/*[clinic input]
73977446
os.forkpty
@@ -7427,8 +7476,9 @@ os_forkpty_impl(PyObject *module)
74277476
/* parent: release the import lock. */
74287477
PyOS_AfterFork_Parent();
74297478
}
7430-
if (pid == -1)
7479+
if (pid == -1) {
74317480
return posix_error();
7481+
}
74327482
return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
74337483
}
74347484
#endif /* HAVE_FORKPTY */
@@ -14797,6 +14847,7 @@ static PyMethodDef posix_methods[] = {
1479714847
OS_SCHED_SETAFFINITY_METHODDEF
1479814848
OS_SCHED_GETAFFINITY_METHODDEF
1479914849
OS_OPENPTY_METHODDEF
14850+
OS_LOGIN_TTY_METHODDEF
1480014851
OS_FORKPTY_METHODDEF
1480114852
OS_GETEGID_METHODDEF
1480214853
OS_GETEUID_METHODDEF

configure

+61-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

configure.ac

+5-2
Original file line numberDiff line numberDiff line change
@@ -2508,7 +2508,7 @@ AC_CHECK_HEADERS([ \
25082508
sys/random.h sys/resource.h sys/select.h sys/sendfile.h sys/socket.h sys/soundcard.h sys/stat.h \
25092509
sys/statvfs.h sys/sys_domain.h sys/syscall.h sys/sysmacros.h sys/termio.h sys/time.h sys/times.h \
25102510
sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h sys/xattr.h sysexits.h syslog.h \
2511-
termios.h util.h utime.h \
2511+
termios.h util.h utime.h utmp.h \
25122512
])
25132513
AC_HEADER_DIRENT
25142514
AC_HEADER_MAJOR
@@ -4670,14 +4670,17 @@ PY_CHECK_FUNC([setgroups], [
46704670
#endif
46714671
])
46724672

4673-
# check for openpty and forkpty
4673+
# check for openpty, login_tty, and forkpty
46744674

46754675
AC_CHECK_FUNCS(openpty,,
46764676
AC_CHECK_LIB(util,openpty,
46774677
[AC_DEFINE(HAVE_OPENPTY) LIBS="$LIBS -lutil"],
46784678
AC_CHECK_LIB(bsd,openpty, [AC_DEFINE(HAVE_OPENPTY) LIBS="$LIBS -lbsd"])
46794679
)
46804680
)
4681+
AC_SEARCH_LIBS([login_tty], [util],
4682+
[AC_DEFINE([HAVE_LOGIN_TTY], [1], [Define to 1 if you have the `login_tty' function.])]
4683+
)
46814684
AC_CHECK_FUNCS(forkpty,,
46824685
AC_CHECK_LIB(util,forkpty,
46834686
[AC_DEFINE(HAVE_FORKPTY) LIBS="$LIBS -lutil"],

pyconfig.h.in

+6
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,9 @@
721721
/* Define to 1 if you have the `log2' function. */
722722
#undef HAVE_LOG2
723723

724+
/* Define to 1 if you have the `login_tty' function. */
725+
#undef HAVE_LOGIN_TTY
726+
724727
/* Define to 1 if the system has the type `long double'. */
725728
#undef HAVE_LONG_DOUBLE
726729

@@ -1389,6 +1392,9 @@
13891392
/* Define to 1 if you have the <utime.h> header file. */
13901393
#undef HAVE_UTIME_H
13911394

1395+
/* Define to 1 if you have the <utmp.h> header file. */
1396+
#undef HAVE_UTMP_H
1397+
13921398
/* Define to 1 if you have the `uuid_create' function. */
13931399
#undef HAVE_UUID_CREATE
13941400

0 commit comments

Comments
 (0)