Kernel/init: /dev/tty is now custom symlink to controlling terminal

kernel now passes the name of default console to init process so init
knows which file to open as stdio. before /dev/tty was referencing the
system wide current terminal which was inherited from cmdline. This
doesn't work anymore as we have pseudo terminals implemented that can
chage the current terminal during runtime :D
This commit is contained in:
Bananymous 2024-11-17 22:38:52 +02:00
parent 458a362f98
commit aaff5a65e1
4 changed files with 51 additions and 38 deletions

View File

@ -185,7 +185,7 @@ namespace Kernel
BAN::ErrorOr<long> sys_load_keymap(const char* path); BAN::ErrorOr<long> sys_load_keymap(const char* path);
TTY& tty() { ASSERT(m_controlling_terminal); return *m_controlling_terminal; } BAN::RefPtr<TTY> controlling_terminal() { return m_controlling_terminal; }
static Process& current() { return Thread::current().process(); } static Process& current() { return Thread::current().process(); }

View File

@ -20,6 +20,42 @@
namespace Kernel namespace Kernel
{ {
class DevTTY : public TmpInode
{
public:
static BAN::ErrorOr<BAN::RefPtr<DevTTY>> create(mode_t mode, uid_t uid, gid_t gid)
{
return TRY(BAN::RefPtr<DevTTY>::create(mode | Inode::Mode::IFLNK, uid, gid));
}
protected:
BAN::ErrorOr<BAN::String> link_target_impl() override
{
auto terminal = Process::current().controlling_terminal();
if (!terminal)
return BAN::Error::from_errno(ENODEV);
return TRY(BAN::String::formatted("/dev/{}", terminal->name()));
}
bool can_read_impl() const override { return false; }
bool can_write_impl() const override { return false; }
bool has_error_impl() const override { return false; }
private:
DevTTY(mode_t mode, uid_t uid, gid_t gid)
: TmpInode(
DevFileSystem::get(),
MUST(DevFileSystem::get().allocate_inode(create_inode_info(mode, uid, gid))),
create_inode_info(mode, uid, gid)
)
{
ASSERT(this->mode().iflnk());
}
private:
friend class BAN::RefPtr<DevTTY>;
};
static BAN::RefPtr<TTY> s_tty; static BAN::RefPtr<TTY> s_tty;
static dev_t next_tty_rdev() static dev_t next_tty_rdev()
@ -51,20 +87,6 @@ namespace Kernel
{ {
s_tty = this; s_tty = this;
clear(); clear();
auto inode_or_error = DevFileSystem::get().root_inode()->find_inode("tty"_sv);
if (inode_or_error.is_error())
{
if (inode_or_error.error().get_error_code() == ENOENT)
DevFileSystem::get().add_inode("tty"_sv, MUST(TmpSymlinkInode::create_new(DevFileSystem::get(), 0666, 0, 0, s_tty->name())));
else
dwarnln("{}", inode_or_error.error());
return;
}
auto inode = inode_or_error.release_value();
if (inode->mode().iflnk())
MUST(static_cast<TmpSymlinkInode&>(*inode.ptr()).set_link_target(name()));
} }
BAN::ErrorOr<void> TTY::tty_ctrl(int command, int flags) BAN::ErrorOr<void> TTY::tty_ctrl(int command, int flags)
@ -138,6 +160,8 @@ namespace Kernel
auto* thread = MUST(Thread::create_kernel(&TTY::keyboard_task, nullptr, nullptr)); auto* thread = MUST(Thread::create_kernel(&TTY::keyboard_task, nullptr, nullptr));
MUST(Processor::scheduler().add_thread(thread)); MUST(Processor::scheduler().add_thread(thread));
DevFileSystem::get().add_inode("tty", MUST(DevTTY::create(0666, 0, 0)));
initialized = true; initialized = true;
} }

View File

@ -255,6 +255,10 @@ static void init2(void*)
TTY::initialize_devices(); TTY::initialize_devices();
MUST(Process::create_userspace({ 0, 0, 0, 0 }, "/usr/bin/init"_sv, {})); MUST(Process::create_userspace({ 0, 0, 0, 0 }, "/usr/bin/init"_sv, {}));
auto console_path = MUST(BAN::String::formatted("/dev/{}", cmdline.console));
auto console_path_sv = console_path.sv();
MUST(Process::create_userspace({ 0, 0, 0, 0 }, "/usr/bin/init"_sv, BAN::Span<BAN::StringView>(&console_path_sv, 1)));
} }
extern "C" void ap_main() extern "C" void ap_main()

View File

@ -2,7 +2,6 @@
#include <BAN/Optional.h> #include <BAN/Optional.h>
#include <BAN/Vector.h> #include <BAN/Vector.h>
#include <ctype.h>
#include <fcntl.h> #include <fcntl.h>
#include <pwd.h> #include <pwd.h>
#include <stdio.h> #include <stdio.h>
@ -11,18 +10,16 @@
#include <sys/banan-os.h> #include <sys/banan-os.h>
#include <termios.h> #include <termios.h>
void initialize_stdio() int main(int argc, char** argv)
{ {
const char* tty = "/dev/tty"; ASSERT(argc == 2);
if (open(tty, O_RDONLY | O_TTY_INIT) != 0) _exit(1);
if (open(tty, O_WRONLY) != 1) _exit(1);
if (open(tty, O_WRONLY) != 2) _exit(1);
if (open("/dev/debug", O_WRONLY) != 3) _exit(1);
}
int main() const char* tty_name = argv[1];
{
initialize_stdio(); if (open(tty_name, O_RDONLY | O_TTY_INIT) != 0) _exit(1);
if (open(tty_name, O_WRONLY) != 1) _exit(1);
if (open(tty_name, O_WRONLY) != 2) _exit(1);
if (open("/dev/debug", O_WRONLY) != 3) _exit(1);
if (signal(SIGINT, [](int) {}) == SIG_ERR) if (signal(SIGINT, [](int) {}) == SIG_ERR)
perror("signal"); perror("signal");
@ -80,18 +77,6 @@ int main()
if (pwd == nullptr) if (pwd == nullptr)
continue; continue;
if (chown("/dev/tty", pwd->pw_uid, pwd->pw_gid) == -1)
{
perror("chown");
continue;
}
if (chmod("/dev/tty", 0600) == -1)
{
perror("chmod");
continue;
}
pid_t pid = fork(); pid_t pid = fork();
if (pid == 0) if (pid == 0)
{ {