diff --git a/ce/Makefile b/ce/Makefile index 6cc8099..bef00fc 100644 --- a/ce/Makefile +++ b/ce/Makefile @@ -5,7 +5,7 @@ $(eval $(call add_lib,libprocess)) $(eval $(call add_lib,libaux)) $(eval $(call add_lib,libarena)) $(eval $(call add_lib,libioutil)) -$(eval $(call add_include,libterminal)) +$(eval $(call add_lib,libterminal)) $(eval $(call add_include,libkb)) cflags += -DPRINTF_INCLUDE_CONFIG_H=1 diff --git a/ce/interp.c b/ce/interp.c index 64ffb6d..710870a 100644 --- a/ce/interp.c +++ b/ce/interp.c @@ -15,6 +15,7 @@ #include #include #include +#include static bool run = true; @@ -51,6 +52,12 @@ static void mkfile (struct context* context, char** file_paths, size_t files_cou } } +static void terminfo (struct context* context) { + size_t cols = 0, rows = 0; + terminal_dimensions (&cols, &rows); + cprintf (context, "%zu x %zu\n", cols, rows); +} + static void mkdir (struct context* context, char** dir_paths, size_t dirs_count) { char volume[VOLUME_MAX]; const char* path; @@ -248,6 +255,7 @@ static void help (struct context* context) { cprintf (context, "mkdir \n"); cprintf (context, "rm \n"); cprintf (context, "edit \n"); + cprintf (context, "terminfo\n"); cprintf (context, "quit\n"); } @@ -286,6 +294,8 @@ static void execute_cmd (struct ast_cmd* cmd, struct context* context) { rm (context, cmd->args, cmd->arg_count); } else if (strcmp (cmd->name, "edit") == 0) { edit (context, cmd->args[0]); + } else if (strcmp (cmd->name, "terminfo") == 0) { + terminfo (context); } else { char volume[VOLUME_MAX]; const char* path; diff --git a/include/devices.h b/include/devices.h index 0f66920..70525f4 100644 --- a/include/devices.h +++ b/include/devices.h @@ -2,7 +2,8 @@ #define _DEVICES_H /* terminal device */ -#define TERMINAL_PUTSTR 0 +#define TERMINAL_PUTSTR 0 +#define TERMINAL_DIMENSIONS 1 /* keyboard device */ #define KB_READ_KEY 0 diff --git a/kernel/device/device.c b/kernel/device/device.c index 04bd6fb..e0f0804 100644 --- a/kernel/device/device.c +++ b/kernel/device/device.c @@ -86,6 +86,7 @@ struct device* device_create (const char* key, device_op_func_t* ops, size_t ops void terminal_device_init (void) { device_op_func_t ops[] = { [TERMINAL_PUTSTR] = &terminal_putstr, + [TERMINAL_DIMENSIONS] = &terminal_dimensions, }; device_create ("TERMINAL", ops, lengthof (ops), &terminal_init, &terminal_fini, NULL); } diff --git a/kernel/device/terminal.c b/kernel/device/terminal.c index 985a38b..6d19ced 100644 --- a/kernel/device/terminal.c +++ b/kernel/device/terminal.c @@ -37,7 +37,7 @@ void terminal_fini (struct device* device) { (void)device; } int terminal_putstr (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4) { - (void)a2, (void)a3, (void)a4, (void)device; + (void)a2, (void)a3, (void)a4, (void)device, (void)rctx; if (!(proc->procgroup->capabilities & PROC_CAP_TERMINAL)) return -ST_PERMISSION_ERROR; @@ -52,3 +52,15 @@ int terminal_putstr (struct device* device, struct proc* proc, struct reschedule return ST_OK; } + +int terminal_dimensions (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, + void* a1, void* a2, void* a3, void* a4) { + (void)proc, (void)rctx, (void)a3, (void)a4, (void)device; + + if (a1 == NULL || a2 == NULL) + return -ST_BAD_ADDRESS_SPACE; + + flanterm_get_dimensions (ft_ctx, (size_t*)a1, (size_t*)a2); + + return ST_OK; +} diff --git a/kernel/device/terminal.h b/kernel/device/terminal.h index 571435e..cbd21a1 100644 --- a/kernel/device/terminal.h +++ b/kernel/device/terminal.h @@ -16,4 +16,7 @@ void terminal_fini (struct device* device); int terminal_putstr (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4); +int terminal_dimensions (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, + void* a1, void* a2, void* a3, void* a4); + #endif // _KERNEL_DEVICE_TERMINAL_H diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index 0fb7743..800dd17 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -273,6 +273,11 @@ DEFINE_SYSCALL (sys_device_do) { spin_lock (&device->lock); + if (device->ops[cmd] == NULL) { + spin_unlock (&device->lock); + return SYSRESULT (-ST_NOT_FOUND); + } + int ret = device_op (device, cmd, proc, rctx, ka1, ka2, ka3, ka4); spin_unlock (&device->lock); diff --git a/libterminal/terminal.c b/libterminal/terminal.c index 4153371..3556865 100644 --- a/libterminal/terminal.c +++ b/libterminal/terminal.c @@ -5,3 +5,7 @@ void terminal_print (const char* string, size_t len) { device_do ("TERMINAL", TERMINAL_PUTSTR, (void*)string, &len, NULL, NULL); } + +void terminal_dimensions (size_t* cols, size_t* rows) { + device_do ("TERMINAL", TERMINAL_DIMENSIONS, (void*)cols, (void*)rows, NULL, NULL); +} diff --git a/libterminal/terminal.h b/libterminal/terminal.h index df85659..9f9558f 100644 --- a/libterminal/terminal.h +++ b/libterminal/terminal.h @@ -7,4 +7,7 @@ /* Print a string onto a graphical terminal. Prints len chars */ void terminal_print (const char* string, size_t len); +/* Get terminal dimensions */ +void terminal_dimensions (size_t* cols, size_t* rows); + #endif // _LIBTERMINAL_TERMINAL_TERMINAL_H