Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ userland/musl-*
userland/llvm-project-*
userland/build/
initrd/bin/*
initrd/usr/
!initrd/bin/.gitkeep

# OS files
Expand Down
2 changes: 1 addition & 1 deletion kernel/mm/vma.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ constexpr uint32_t VMA_FLAG_DEVICE = (1u << 5);

constexpr uintptr_t MMAP_BASE_DEFAULT = 0x00000080000000ULL;
constexpr uintptr_t USER_STACK_TOP = 0x00007FFFFFF00000ULL;
constexpr size_t USER_STACK_PAGES = 8; // 32 KiB
constexpr size_t USER_STACK_PAGES = 128; // 512 KiB
constexpr size_t USER_STACK_GUARD_PAGES = 1;

struct vma {
Expand Down
83 changes: 81 additions & 2 deletions kernel/pty/pty.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,40 @@
#include "common/ring_buffer.h"
#include "fs/fstypes.h"
#include "mm/heap.h"
#include "mm/uaccess.h"
#include "dynpriv/dynpriv.h"
#include "sync/poll.h"
#include "sync/wait_queue.h"
#include "terminal/terminal.h"

namespace pty {

constexpr uint32_t TCGETS = 0x5401;
constexpr uint32_t TCSETS = 0x5402;
constexpr uint32_t TCSETSW = 0x5403;
constexpr uint32_t TCSETSF = 0x5404;
constexpr uint32_t TIOCGWINSZ = 0x5413;
constexpr uint32_t TIOCSWINSZ = 0x5414;

constexpr uint32_t LINUX_ECHO = 0x0008;
constexpr uint32_t LINUX_ICANON = 0x0002;

struct linux_termios {
uint32_t c_iflag;
uint32_t c_oflag;
uint32_t c_cflag;
uint32_t c_lflag;
uint8_t c_line;
uint8_t c_cc[19];
};

struct linux_winsize {
uint16_t ws_row;
uint16_t ws_col;
uint16_t ws_xpixel;
uint16_t ws_ypixel;
};

__PRIVILEGED_BSS static uint32_t g_next_pty_id;

__PRIVILEGED_CODE void pty_channel::ref_destroy(pty_channel* self) {
Expand Down Expand Up @@ -179,15 +207,66 @@ static void pty_slave_close(resource::resource_object* obj) {
obj->impl = nullptr;
}

static int32_t do_tcgets(pty_channel* chan, uint64_t arg) {
linux_termios t = {};

if (chan->m_ld.mode != terminal::LD_MODE_RAW) {
t.c_lflag = LINUX_ICANON | LINUX_ECHO;
}

int32_t rc = mm::uaccess::copy_to_user(
reinterpret_cast<void*>(arg), &t, sizeof(t));

return (rc == mm::uaccess::OK) ? resource::OK : resource::ERR_INVAL;
}

static int32_t do_tcsets(pty_channel* chan, uint64_t arg) {
linux_termios t = {};
int32_t rc = mm::uaccess::copy_from_user(
&t, reinterpret_cast<const void*>(arg), sizeof(t));

if (rc != mm::uaccess::OK) {
return resource::ERR_INVAL;
}

uint32_t mode = (t.c_lflag & LINUX_ICANON)
? terminal::STLX_TCSETS_COOKED
: terminal::STLX_TCSETS_RAW;

terminal::ld_set_mode(&chan->m_ld, mode);
return resource::OK;
}

static int32_t do_tiocgwinsz(uint64_t arg) {
linux_winsize w = { 24, 80, 0, 0 };
int32_t rc = mm::uaccess::copy_to_user(
reinterpret_cast<void*>(arg), &w, sizeof(w));

return (rc == mm::uaccess::OK) ? resource::OK : resource::ERR_INVAL;
}

static int32_t pty_termios_ioctl(pty_channel* chan, uint32_t cmd, uint64_t arg) {
switch (cmd) {
case TCGETS: return do_tcgets(chan, arg);
case TCSETS:
case TCSETSW:
case TCSETSF: return do_tcsets(chan, arg);
case TIOCGWINSZ: return do_tiocgwinsz(arg);
case TIOCSWINSZ: return resource::OK;
case terminal::STLX_TCSETS_RAW:
case terminal::STLX_TCSETS_COOKED: return terminal::ld_set_mode(&chan->m_ld, cmd);
default: return resource::ERR_INVAL;
}
}

static int32_t pty_slave_ioctl(
resource::resource_object* obj, uint32_t cmd, uint64_t arg
) {
(void)arg;
if (!obj || !obj->impl) {
return resource::ERR_INVAL;
}
auto* ep = static_cast<pty_endpoint*>(obj->impl);
return terminal::ld_set_mode(&ep->channel->m_ld, cmd);
return pty_termios_ioctl(ep->channel.ptr(), cmd, arg);
Comment thread
FlareCoding marked this conversation as resolved.
}

static uint32_t pty_master_poll(
Expand Down
26 changes: 26 additions & 0 deletions kernel/syscall/handlers/sys_fd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1161,8 +1161,13 @@ DEFINE_SYSCALL3(getdents64, fd, dirp, count) {
}

namespace {
constexpr uint64_t F_GETFD = 1;
constexpr uint64_t F_SETFD = 2;
constexpr uint64_t F_GETFL = 3;
constexpr uint64_t F_SETFL = 4;

constexpr int64_t FD_CLOEXEC = 1;

constexpr uint32_t SETFL_MASK = fs::O_NONBLOCK | fs::O_APPEND;
} // anonymous namespace

Expand All @@ -1172,6 +1177,27 @@ DEFINE_SYSCALL3(fcntl, fd, cmd, arg) {
return syscall::EIO;
}

if (cmd == F_GETFD) {
uint32_t flags = 0;
int32_t rc = resource::get_handle_flags(
&task->handles, static_cast<resource::handle_t>(fd), &flags);
if (rc != resource::HANDLE_OK) {
return syscall::EBADF;
}
return FD_CLOEXEC;
}

if (cmd == F_SETFD) {
uint32_t flags = 0;
int32_t rc = resource::get_handle_flags(
&task->handles, static_cast<resource::handle_t>(fd), &flags);
if (rc != resource::HANDLE_OK) {
return syscall::EBADF;
}
(void)arg;
return 0;
Comment thread
cursor[bot] marked this conversation as resolved.
}

if (cmd == F_GETFL) {
uint32_t flags = 0;
int32_t rc = resource::get_handle_flags(
Expand Down
6 changes: 4 additions & 2 deletions kernel/terminal/terminal.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ namespace terminal {
constexpr int32_t OK = 0;
constexpr int32_t ERR = -1;

constexpr uint32_t STLX_TCSETS_RAW = 0x5401;
constexpr uint32_t STLX_TCSETS_COOKED = 0x5402;
// Stellux-internal line-discipline mode-switch ioctls.
// Encoded as _IO('s', N) so they do not collide with Linux's tty ioctl
constexpr uint32_t STLX_TCSETS_RAW = 0x7301;
constexpr uint32_t STLX_TCSETS_COOKED = 0x7302;

/**
* @brief Initialize the global console terminal. Creates the input ring
Expand Down
28 changes: 21 additions & 7 deletions userland/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ endif
# Output directories
BIN_DIR := $(USERLAND_ROOT)/build/$(ARCH)/bin
INITRD_BIN := $(USERLAND_ROOT)/../initrd/bin
ROOTFS_DIR := $(USERLAND_ROOT)/build/$(ARCH)/rootfs
INITRD_ROOT := $(USERLAND_ROOT)/../initrd

# Verbosity
ifeq ($(V),1)
Expand Down Expand Up @@ -59,23 +61,35 @@ endif
install-summary: build
@mkdir -p $(INITRD_BIN)
ifeq ($(V),1)
@echo "Installing userland binaries to initrd..."
@echo "Installing userland binaries/rootfs to initrd..."
@if [ -d "$(BIN_DIR)" ] && [ -n "$$(ls -A $(BIN_DIR) 2>/dev/null)" ]; then \
cp $(BIN_DIR)/* $(INITRD_BIN)/; \
echo "Installed: $$(ls $(BIN_DIR)/)"; \
echo "Installed binaries: $$(ls $(BIN_DIR)/)"; \
else \
echo "No binaries to install"; \
fi
@if [ -d "$(ROOTFS_DIR)" ] && [ -n "$$(ls -A $(ROOTFS_DIR) 2>/dev/null)" ]; then \
cp -a $(ROOTFS_DIR)/. $(INITRD_ROOT)/; \
echo "Installed rootfs overlay from $(ROOTFS_DIR)"; \
else \
echo "No rootfs overlay to install"; \
fi
else
@if [ -d "$(BIN_DIR)" ] && [ -n "$$(ls -A $(BIN_DIR) 2>/dev/null)" ]; then \
cp $(BIN_DIR)/* $(INITRD_BIN)/; \
bincount=$$(ls -1 $(BIN_DIR)/ | wc -l); \
libcount=$$(ls -1 $(SYSROOT)/lib/libstlx.a 2>/dev/null | wc -l); \
if [ $$libcount -eq 1 ]; then libword="library"; else libword="libraries"; fi; \
printf " $$libcount $$libword, $$bincount binaries installed to initrd/bin/\n"; \
else \
echo " No binaries to install"; \
fi
bincount=0; \
fi; \
if [ -d "$(ROOTFS_DIR)" ] && [ -n "$$(ls -A $(ROOTFS_DIR) 2>/dev/null)" ]; then \
cp -a $(ROOTFS_DIR)/. $(INITRD_ROOT)/; \
rootfsword=", rootfs overlay installed"; \
else \
rootfsword=""; \
fi; \
libcount=$$(ls -1 $(SYSROOT)/lib/libstlx.a 2>/dev/null | wc -l); \
if [ $$libcount -eq 1 ]; then libword="library"; else libword="libraries"; fi; \
printf " $$libcount $$libword, $$bincount binaries installed to initrd/bin/$$rootfsword\n"
endif

clean:
Expand Down
2 changes: 1 addition & 1 deletion userland/apps/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
APP_DIRS := init hello shell ls cat rm stat touch sleep true false clear ptytest date \
clockbench stlxdm stlxterm doom ping ifconfig nslookup arp udpecho tcpecho \
fetch polltest dropbear blackjack wordle hangman snake tetris \
grep wc head threadtest uname kill cxxtest synctest
grep wc head threadtest uname kill cxxtest synctest python
APP_COUNT := $(words $(APP_DIRS))

all:
Expand Down
2 changes: 1 addition & 1 deletion userland/apps/ptytest/src/ptytest.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <string.h>
#include <sys/ioctl.h>

#define STLX_TCSETS_RAW 0x5401
#define STLX_TCSETS_RAW 0x7301

int main(void) {
setvbuf(stdout, NULL, _IONBF, 0);
Expand Down
4 changes: 4 additions & 0 deletions userland/apps/python/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
src/
build/
dl/
install/
Loading
Loading