Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 3 additions & 0 deletions kernel/include/kernel/con/con.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <kernel/fs/ioctl.h>
#include <stddef.h>
#include <stdint.h>
#include <utils/varray.h>
Expand All @@ -14,6 +15,8 @@ int con_update (void);
void con_scrollup (size_t howmuch);
void con_scrolldown (size_t howmuch);

int con_tiocgwinsz (winsize_t* ptr);

int add_char (unsigned char c);
void init_con (size_t screen_width, size_t screen_height, size_t x_padding, size_t y_padding,
size_t char_spacing, size_t line_padding, size_t font_multiplier);
17 changes: 17 additions & 0 deletions kernel/include/kernel/fs/ioctl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#define TIOCGWINSZ 0x5413
#define TIOCSWINSZ 0x5414
#define TCGETS 0x5401
#define TCSETS 0x5402
#define TCSETSW 0x5403
#define TCSETSF 0x5404
#define TIOCGPGRP 0x540F
#define TIOCSPGRP 0x5410

typedef struct {
unsigned short ws_row;
unsigned short ws_col;
unsigned short ws_xpixel;
unsigned short ws_ypixel;
} winsize_t;
3 changes: 3 additions & 0 deletions kernel/include/kernel/fs/vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ typedef struct {
int (*seek) (inode*, file*, size_t, int);
int (*getdents) (inode*, file*, void*, size_t);
int (*fstat) (inode*, file*, stat*);
int (*ioctl) (inode*, file*, uint64_t, uint64_t);
} file_operations;

struct inode {
Expand Down Expand Up @@ -85,6 +86,7 @@ int do_close (struct file* fd);
int do_getdents (struct file* f, void* buf, size_t count);
int do_fstat (struct file* fd, stat* buf);
int do_stat (const char* restrict path, stat* restrict buf);
int do_ioctl (struct file* fd, uint64_t req, uint64_t arg);

uint64_t sys_read (uint64_t fd, uint64_t buf, uint64_t size);
uint64_t sys_write (uint64_t fd, uint64_t buf, uint64_t size);
Expand All @@ -97,6 +99,7 @@ uint64_t sys_getdents (uint64_t fd, uint64_t buf, uint64_t count);
uint64_t sys_getcwd (uint64_t buf, uint64_t size, uint64_t arg3);
uint64_t sys_fstat (uint64_t fd, uint64_t buf, uint64_t arg3);
uint64_t sys_stat (uint64_t path, uint64_t buf, uint64_t arg3);
uint64_t sys_ioctl (uint64_t fd, uint64_t req, uint64_t arg);

inode* get_absolute_root (void);
void init_vfs (inode* absolute_root);
Expand Down
1 change: 1 addition & 0 deletions kernel/include/kernel/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

// The following will have numbers changed

#define SYSCALL_SYS_IOCTL 241
#define SYSCALL_SYS_GETCWD 242
#define SYSCALL_SYS_CHDIR 243
#define SYSCALL_SYS_FCNTL 244
Expand Down
15 changes: 15 additions & 0 deletions kernel/src/kernel/con/con.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <kernel/con/ansi.h>
#include <kernel/con/con.h>
#include <kernel/con/con_ds.h>
#include <kernel/error.h>

static console_t* console = nullptr;
static bool update_flag = true;
Expand Down Expand Up @@ -33,6 +34,20 @@ void con_scrolldown (size_t howmuch) {
write_to_gfx (&console);
}

int con_tiocgwinsz (winsize_t* ptr) {
if (!ptr) return -EINVAL;

console_parameters_t params = console_getparams (&console);
ptr->ws_col = params.width;
ptr->ws_row = params.height;
ptr->ws_xpixel = (unsigned short)(params.width * (params.glyph_width + params.char_spacing) *
params.font_size);
ptr->ws_ypixel = (unsigned short)(params.height * (params.glyph_height + params.line_spacing) *
params.font_size);

return 0;
}

int add_char (unsigned char c) {
int error = 0;
console_parameters_t params = console_getparams (&console);
Expand Down
10 changes: 10 additions & 0 deletions kernel/src/kernel/fs/chardev/chardev.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#include "kernel/fs/vfs.h"
#include <kclib/ctype.h>
#include <kclib/stdio.h>
#include <kclib/string.h>
#include <kernel/con/con.h>
#include <kernel/error.h>
#include <kernel/fs/chardev.h>
#include <kernel/fs/ioctl.h>
#include <kernel/fs/stat.h>
#include <kernel/hw/keyboard.h>
#include <kernel/process.h>
Expand Down Expand Up @@ -73,6 +75,13 @@ static int chardev_fstat (inode* node, file* f, stat* buf) {
return 0;
}

static int chardev_ioctl (inode* node, file* f, uint64_t request, uint64_t argument) {
(void)node, (void)f;
if (request == TIOCGWINSZ) return con_tiocgwinsz ((winsize_t*)argument);

return -ENOSYS;
}

void init_tty1 (inode* absolute_root) {
inode* dev_dir = nullptr;
int error = do_mkdir ("dev", &dev_dir, absolute_root);
Expand All @@ -89,6 +98,7 @@ void init_tty1 (inode* absolute_root) {
tty1_fops->write = stdout_write;
tty1_fops->read = stdin_read;
tty1_fops->fstat = chardev_fstat;
tty1_fops->ioctl = chardev_ioctl;

chardev_info_t* tty1_info = kmalloc (sizeof (chardev_info_t));
kmemset (tty1_info, 0, sizeof (chardev_info_t));
Expand Down
16 changes: 16 additions & 0 deletions kernel/src/kernel/fs/vfs/ioctl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <kernel/error.h>
#include <kernel/fs/vfs.h>
#include <kernel/process.h>
#include <stddef.h>

int do_ioctl (struct file* fd, uint64_t req, uint64_t arg) {
if (!fd) return -EINVAL;
if (!fd->f_fops || !fd->f_fops->ioctl) return -ENOSYS;
return fd->f_fops->ioctl (fd->f_inode, fd, req, arg);
}

uint64_t sys_ioctl (uint64_t fd, uint64_t req, uint64_t arg) {
process* current = get_current_process ();
if (fd >= MAX_FDS || !current || !current->p_fds[fd]) return -EINVAL;
return do_ioctl (current->p_fds[fd], req, arg);
}
1 change: 1 addition & 0 deletions kernel/src/kernel/fs/vfs/vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ void init_vfs (inode* absolute_root) {
register_syscall (SYSCALL_SYS_STAT, sys_stat);
register_syscall (SYSCALL_SYS_CHDIR, sys_chdir);
register_syscall (SYSCALL_SYS_GETCWD, sys_getcwd);
register_syscall (SYSCALL_SYS_IOCTL, sys_ioctl);
}
1 change: 1 addition & 0 deletions lib/cos/include/arch/x86_64-cos/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#define SYSCALL_SYS_FORK 57
#define SYSCALL_SCHED_YIELD 158

#define SYSCALL_SYS_IOCTL 241
#define SYSCALL_SYS_GETCWD 242
#define SYSCALL_SYS_CHDIR 243
#define SYSCALL_SYS_FCNTL 244
Expand Down
29 changes: 29 additions & 0 deletions lib/cos/include/sys/ioctl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include <sys/types.h>

#define TIOCGWINSZ 0x5413 /* get window size */
#define TIOCSWINSZ 0x5414 /* set window size */
#define TCGETS 0x5401 /* get termios */
#define TCSETS 0x5402 /* set termios */
#define TCSETSW 0x5403
#define TCSETSF 0x5404
#define TIOCGPGRP 0x540F /* get foreground process group */
#define TIOCSPGRP 0x5410 /* set foreground process group */

struct winsize {
unsigned short ws_row;
unsigned short ws_col;
unsigned short ws_xpixel;
unsigned short ws_ypixel;
};

#ifdef __cplusplus
extern "C" {
#endif

int ioctl (int fd, unsigned long request, ...);

#ifdef __cplusplus
}
#endif
13 changes: 13 additions & 0 deletions lib/cos/src/ioctl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <arch/x86_64-cos/syscalls.h>
#include <stdarg.h>
#include <sys/ioctl.h>

int ioctl (int fd, unsigned long request, ...) {
va_list args;
va_start (args, request);
void* arg = va_arg (args, void*);
va_end (args);

return (int)syscall_ret (
(long)syscall3 (SYSCALL_SYS_IOCTL, (long)fd, (long)request, (long)arg));
}
53 changes: 50 additions & 3 deletions user/cosh/src/builtin/ls.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#include <builtin.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>

int builtin_ls (int argc, char** argv) {
const char* path = (argc >= 2) ? argv[1] : ".";
Expand All @@ -11,10 +15,53 @@ int builtin_ls (int argc, char** argv) {
return -1;
}

struct dirent* entry;
while ((entry = readdir (dir)) != NULL)
printf ("%s\n", entry->d_name);
size_t count = 0, cap = 64;
char** names = malloc (cap * sizeof (char*));
if (!names) {
closedir (dir);
return -1;
}

size_t max_len = 0;
struct dirent* entry;
while ((entry = readdir (dir)) != NULL) {
if (count == cap) {
cap *= 2;
char** tmp = realloc (names, cap * sizeof (char*));
if (!tmp) break;
names = tmp;
}
names[count] = strdup (entry->d_name);
if (!names[count]) break;
size_t len = strlen (entry->d_name);
if (len > max_len) max_len = len;
count++;
}
closedir (dir);

unsigned short term_cols = 80;
struct winsize ws;
if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col > 0) term_cols = ws.ws_col;

size_t col_width = max_len + 2;
size_t ncols = term_cols / col_width;
if (ncols == 0) ncols = 1;
size_t nrows = (count + ncols - 1) / ncols;

for (size_t row = 0; row < nrows; row++) {
for (size_t col = 0; col < ncols; col++) {
size_t idx = col * nrows + row;
if (idx >= count) break;
int last = (col + 1 == ncols) || ((col + 1) * nrows + row >= count);
if (last)
printf ("%s\n", names[idx]);
else
printf ("%-*s", (int)col_width, names[idx]);
}
}

for (size_t i = 0; i < count; i++)
free (names[i]);
free (names);
return 0;
}
Loading