libc+apps: Start implementing POSIX-compliant termios.h wrappers around tty ioctls
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
apio 2023-07-12 19:23:06 +02:00
parent 2951d6d112
commit 546d900454
Signed by: apio
GPG Key ID: B8A7D06E42258954
12 changed files with 90 additions and 27 deletions

View File

@ -1,10 +1,9 @@
#include <bits/termios.h>
#include <luna/String.h>
#include <os/ArgumentParser.h>
#include <os/File.h>
#include <signal.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>
Result<int> luna_main(int argc, char** argv)
@ -31,11 +30,7 @@ Result<int> luna_main(int argc, char** argv)
{
signal(SIGTTOU, SIG_IGN);
if (isatty(STDIN_FILENO))
{
pid_t pgid = getpgid(0);
ioctl(STDIN_FILENO, TIOCSPGRP, &pgid);
}
if (isatty(STDIN_FILENO)) tcsetpgrp(STDIN_FILENO, getpgid(0));
auto input = os::File::standard_input();

View File

@ -1,4 +1,3 @@
#include <bits/termios.h>
#include <errno.h>
#include <luna/String.h>
#include <luna/Vector.h>
@ -12,8 +11,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/utsname.h>
#include <termios.h>
#include <unistd.h>
using os::File;
@ -85,8 +84,7 @@ Result<int> luna_main(int argc, char** argv)
signal(SIGTTOU, SIG_IGN);
signal(SIGINT, sigint_handler);
pid_t pgid = getpgid(0);
ioctl(STDIN_FILENO, TIOCSPGRP, &pgid);
tcsetpgrp(STDIN_FILENO, getpgid(0));
}
while (1)
@ -138,8 +136,7 @@ Result<int> luna_main(int argc, char** argv)
if (interactive)
{
setpgid(0, 0);
pid_t pgid = getpgid(0);
ioctl(STDIN_FILENO, TIOCSPGRP, &pgid);
tcsetpgrp(STDIN_FILENO, getpid());
}
TRY(execute_command(cmd.view()));
}
@ -147,11 +144,7 @@ Result<int> luna_main(int argc, char** argv)
int status;
TRY(os::Process::wait(child, &status));
if (interactive)
{
pid_t pgid = getpgid(0);
ioctl(STDIN_FILENO, TIOCSPGRP, &pgid);
}
if (interactive) tcsetpgrp(STDIN_FILENO, getpgid(0));
if (WIFSIGNALED(status))
{

View File

@ -1,17 +1,16 @@
#include <bits/termios.h>
#include <os/ArgumentParser.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>
static struct termios orig;
void restore_terminal()
{
ioctl(fileno(stdin), TCSETS, &orig);
tcsetattr(STDIN_FILENO, TCSANOW, &orig);
}
void signal_handler(int signo)
@ -29,14 +28,13 @@ char* getpass()
return nullptr;
}
pid_t pgid = getpgid(0);
ioctl(STDIN_FILENO, TIOCSPGRP, &pgid);
tcsetpgrp(STDIN_FILENO, getpgid(0));
fputs("Password: ", stdout);
if (ioctl(fileno(stdin), TCGETS, &orig) < 0)
if (tcgetattr(STDIN_FILENO, &orig) < 0)
{
perror("ioctl(TCGETS)");
perror("tcgetattr");
return nullptr;
}
@ -52,9 +50,9 @@ char* getpass()
struct termios tc = orig;
tc.c_lflag &= ~ECHO;
if (ioctl(fileno(stdin), TCSETS, &tc) < 0)
if (tcsetattr(STDIN_FILENO, TCSANOW, &tc) < 0)
{
perror("ioctl(TCSETS)");
perror("tcsetattr");
return nullptr;
}

View File

@ -193,6 +193,11 @@ Result<u64> ConsoleDevice::ioctl(int request, void* arg)
g_foreground_process_group = pgid;
return 0;
}
case TIOCGPGRP: {
pid_t pgid = g_foreground_process_group.value_or((pid_t)next_thread_id());
if (!MemoryManager::copy_to_user_typed((pid_t*)arg, &pgid)) return err(EFAULT);
return 0;
}
default: return err(EINVAL);
}
}

View File

@ -28,6 +28,11 @@ Result<Thread*> new_thread()
return thread;
}
u64 next_thread_id()
{
return g_next_id.load();
}
Result<int> Thread::allocate_fd(int min)
{
if (min < 0 || min >= FD_MAX) return err(EINVAL);

View File

@ -159,4 +159,6 @@ bool is_in_kernel(Registers* regs);
Result<Thread*> new_thread();
u64 next_thread_id();
extern LinkedList<Thread> g_threads;

View File

@ -22,6 +22,7 @@ set(SOURCES
src/locale.cpp
src/scanf.cpp
src/signal.cpp
src/termios.cpp
src/sys/stat.cpp
src/sys/mman.cpp
src/sys/wait.cpp

View File

@ -19,5 +19,6 @@ struct termios
#define TCGETS 0
#define TCSETS 1
#define TIOCSPGRP 2
#define TIOCGPGRP 3
#endif

26
libc/include/termios.h Normal file
View File

@ -0,0 +1,26 @@
/* termios.h: Terminal device control. */
#ifndef _TERMIOS_H
#define _TERMIOS_H
#include <bits/termios.h>
#include <sys/types.h>
#define TCSANOW 0
#ifdef __cplusplus
extern "C"
{
#endif
/* Fetch attributes associated with a terminal file descriptor. */
int tcgetattr(int fd, struct termios* termp);
/* Set attributes associated with a terminal file descriptor. */
int tcsetattr(int fd, int act, const struct termios* termp);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -174,6 +174,12 @@ extern "C"
/* Check whether a file descriptor refers to a terminal device. */
int isatty(int fd);
/* Fetch the process group associated with a terminal file descriptor. */
pid_t tcgetpgrp(int fd);
/* Set the process group associated with a terminal file descriptor. */
int tcsetpgrp(int fd, pid_t pgrp);
#ifdef __cplusplus
}
#endif

17
libc/src/termios.cpp Normal file
View File

@ -0,0 +1,17 @@
#include <luna/Check.h>
#include <sys/ioctl.h>
#include <termios.h>
extern "C"
{
int tcgetattr(int fd, struct termios* termp)
{
return ioctl(fd, TCGETS, termp);
}
int tcsetattr(int fd, int act, const struct termios* termp)
{
check(act == TCSANOW);
return ioctl(fd, TCSETS, termp);
}
}

View File

@ -1,4 +1,5 @@
#include <bits/errno-return.h>
#include <bits/termios.h>
#include <fcntl.h>
#include <luna/StringBuilder.h>
#include <luna/Vector.h>
@ -6,6 +7,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/utsname.h>
@ -484,4 +486,16 @@ extern "C"
}
return (int)rc;
}
pid_t tcgetpgrp(int fd)
{
pid_t pgid;
if (ioctl(fd, TIOCGPGRP, &pgid) < 0) return -1;
return pgid;
}
int tcsetpgrp(int fd, pid_t pgid)
{
return ioctl(fd, TIOCSPGRP, &pgid);
}
}