From 5bb432113402889e931ea3e883111e9132d910f5 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Nov 2023 12:18:25 +0100 Subject: [PATCH] libc: Add login_tty() and forkpty() --- libc/CMakeLists.txt | 1 + libc/include/pty.h | 3 +++ libc/include/utmp.h | 18 ++++++++++++++++++ libc/src/pty.cpp | 24 ++++++++++++++++++++++++ libc/src/utmp.cpp | 22 ++++++++++++++++++++++ 5 files changed, 68 insertions(+) create mode 100644 libc/include/utmp.h create mode 100644 libc/src/utmp.cpp diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt index 47d8c8d6..4788422d 100644 --- a/libc/CMakeLists.txt +++ b/libc/CMakeLists.txt @@ -26,6 +26,7 @@ set(SOURCES src/strtod.cpp src/math.cpp src/pty.cpp + src/utmp.cpp src/sys/stat.cpp src/sys/mman.cpp src/sys/wait.cpp diff --git a/libc/include/pty.h b/libc/include/pty.h index 22afbb97..1a30d329 100644 --- a/libc/include/pty.h +++ b/libc/include/pty.h @@ -14,6 +14,9 @@ extern "C" /* Find an available pseudoterminal pair and initialize it, returning file descriptors for both sides. */ int openpty(int* master, int* slave, char* name, const struct termios* term, const struct winsize* win); + /* Create a new process operating in a pseudoterminal. */ + pid_t forkpty(int* master, char* name, const struct termios* term, const struct winsize* win); + #ifdef __cplusplus } #endif diff --git a/libc/include/utmp.h b/libc/include/utmp.h new file mode 100644 index 00000000..31532265 --- /dev/null +++ b/libc/include/utmp.h @@ -0,0 +1,18 @@ +/* utmp.h: Write entries to utmp files. */ + +#ifndef _UTMP_H +#define _UTMP_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* Prepare a new terminal session on a tty. */ + int login_tty(int fd); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libc/src/pty.cpp b/libc/src/pty.cpp index 879a772b..c017e8df 100644 --- a/libc/src/pty.cpp +++ b/libc/src/pty.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #pragma GCC diagnostic ignored "-Wdeprecated-declarations" @@ -44,4 +45,27 @@ extern "C" return 0; } + + pid_t forkpty(int* master, char* name, const struct termios* term, const struct winsize* win) + { + int slave; + if (openpty(master, &slave, name, term, win) < 0) return -1; + + pid_t child = fork(); + if (child < 0) + { + close(*master); + close(slave); + return -1; + } + if (!child) + { + close(*master); + login_tty(slave); + } + else + close(slave); + + return child; + } } diff --git a/libc/src/utmp.cpp b/libc/src/utmp.cpp new file mode 100644 index 00000000..08b7c6a2 --- /dev/null +++ b/libc/src/utmp.cpp @@ -0,0 +1,22 @@ +#include +#include +#include +#include + +extern "C" +{ + int login_tty(int fd) + { + setsid(); + + if (ioctl(fd, TIOCSCTTY) < 0) return -1; + + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + + close(fd); + + return 0; + } +}