Kernel - Add a quick and dirty (and useless) emergency console
authorJohn Hodge <[email protected]>
Sun, 15 Feb 2015 07:23:20 +0000 (15:23 +0800)
committerJohn Hodge <[email protected]>
Sun, 15 Feb 2015 07:23:20 +0000 (15:23 +0800)
KernelLand/Kernel/Makefile
KernelLand/Kernel/emergency_console.c [new file with mode: 0644]
KernelLand/Kernel/system.c

index 93536b8..34e6bcf 100644 (file)
@@ -57,7 +57,7 @@ OBJ := $(addprefix arch/$(ARCHDIR)/,$(A_OBJ))
 OBJ += pmemmap.o
 OBJ += heap.o logging.o debug.o lib.o libc.o adt.o time.o utf16.o debug_hooks.o
 OBJ += drvutil_video.o drvutil_disk.o memfs_helpers.o
-OBJ += messages.o modules.o syscalls.o system.o
+OBJ += messages.o modules.o syscalls.o system.o emergency_console.o
 OBJ += threads.o mutex.o semaphore.o workqueue.o events.o rwlock.o
 OBJ += drv/zero-one.o drv/proc.o drv/fifo.o drv/dgram_pipe.o drv/iocache.o drv/pci.o drv/vpci.o
 OBJ += drv/vterm.o drv/vterm_font.o drv/vterm_vt100.o drv/vterm_output.o drv/vterm_input.o drv/vterm_termbuf.o
diff --git a/KernelLand/Kernel/emergency_console.c b/KernelLand/Kernel/emergency_console.c
new file mode 100644 (file)
index 0000000..dd6d708
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * Acess 2 Kernel
+ * - By John Hodge (thePowersGang)
+ * 
+ * emergency_console.c
+ * - Kernel-land emergency console/shell
+ */
+#include <acess.h>
+#include <stdarg.h>
+
+#define STDIN  0
+#define STDOUT 1
+#define STDERR 2
+
+// === PROTOTYPES ===
+void EmergencyConsole(void);
+// -- Commands
+void Command_ls(const char* path);
+void Command_hd(const char* path);
+void Command_mount(const char *fs, const char *dev, const char *point);
+// --
+static char **split_args(char *line);
+static char *read_line(int fd);
+static int dprintf(int fd, const char *fmt, ...);// __attribute__((printf(2,3)));
+
+// === CODE ===
+void EmergencyConsole(void)
+{
+       for(;;)
+       {
+               dprintf(STDOUT, "(kernel)$ ");
+               char *line = read_line(STDIN);
+               
+               // Explode line into args
+               char **args = split_args(line);
+               // Get command from first arg
+               ASSERT(args);
+               ASSERT(args[0]);
+               if( strcmp(args[0], "help") == 0 ) {
+                       dprintf(STDOUT,
+                               "Commands:\n"
+                               "ls <path> - List the contents of a directory\n"
+                               "hd <path> - Dump a file in a 16 bytes/line hex format\n"
+                               "mount <fs> <device> <point> - Mount a filesystem\n"
+                               );
+               }
+               else if( strcmp(args[0], "ls") == 0 ) {
+                       Command_ls(args[1]); 
+               }
+               else if( strcmp(args[0], "hd") == 0 ) {
+                       Command_hd(args[1]);
+               }
+               else if( strcmp(args[0], "mount") == 0 ) {
+                       Command_mount(args[1], args[2], args[3]);
+               }
+               else
+               {
+                       dprintf(STDERR, "Unknown command '%s'\n", args[0]);
+               }
+               // Free args
+               free(args);
+               free(line);
+       }
+}
+
+void Command_ls(const char* path)
+{
+       dprintf(STDERR, "ls: TODO - Implement\n");
+}
+void Command_hd(const char* path)
+{
+       dprintf(STDERR, "hd: TODO - Implement\n");
+}
+void Command_mount(const char *fs, const char *dev, const char *point)
+{
+       dprintf(STDERR, "mount: TODO - Implement\n");
+}
+
+// Allocates return array (NUL terminated), but mangles input string
+static int split_args_imp(char *line, char **buf)
+{
+        int    argc = 0;
+        int    pos = 0;
+       enum {
+               MODE_SPACE,
+               MODE_NORM,
+               MODE_SQUOTE,
+               MODE_DQUOTE,
+       } mode = MODE_SPACE;
+       for( char *chp = line; *chp; chp ++ )
+       {
+               if( *chp == ' ' ) {
+                       if( mode != MODE_SPACE ) {
+                               if(buf) buf[argc][pos] = '\0';
+                               argc ++;
+                       }
+                       mode = MODE_SPACE;
+                       continue ;
+               }
+               
+               switch( mode )
+               {
+               case MODE_SPACE:
+                       if( buf )
+                               buf[argc] = chp;
+                       pos = 0;
+               case MODE_NORM:
+                       switch( *chp )
+                       {
+                       case '"':
+                               mode = MODE_DQUOTE;
+                               break;
+                       case '\'':
+                               mode = MODE_SQUOTE;
+                               break;
+                       case '\\':
+                               chp ++;
+                               switch( *chp )
+                               {
+                               case '\0':
+                                       dprintf(STDERR, "err: Trailing '\\'\n");
+                                       break;
+                               case '\\':
+                               case '\'':
+                               case '"':
+                                       if(buf) buf[argc][pos++] = *chp;
+                                       break;
+                               default:
+                                       dprintf(STDERR, "err: Unkown escape '%c'\n", *chp);
+                                       break;
+                               }
+                               break;
+                       default:
+                               if(buf) buf[argc][pos++] = *chp;
+                               break;
+                       }
+                       break;
+               case MODE_SQUOTE:
+                       switch( *chp )
+                       {
+                       case '\'':
+                               mode = MODE_NORM;
+                               break;
+                       case '\0':
+                               dprintf(STDERR, "err: Unterminated \' string\n");
+                               break;
+                       default:
+                               if(buf) buf[argc][pos++] = *chp;
+                               break;
+                       }
+                       break;
+               case MODE_DQUOTE:
+                       switch( *chp )
+                       {
+                       case '\"':
+                               mode = MODE_NORM;
+                               break;
+                       case '\\':
+                               chp ++;
+                               switch(*chp)
+                               {
+                               case '\0':
+                                       dprintf(STDERR, "err: Trailing '\\' in \" string\n");
+                                       break;
+                               case '\\':
+                               case '"':
+                                       if(buf) buf[argc][pos++] = *chp;
+                                       break;
+                               default:
+                                       dprintf(STDERR, "err: Unkown escape '%c'\n", *chp);
+                                       break;
+                               }
+                               break;
+                       case '\0':
+                               dprintf(STDERR, "err: Unterminated \" string\n");
+                               break;
+                       default:
+                               if(buf) buf[argc][pos++] = *chp;
+                               break;
+                       }
+                       break;
+               }
+       }
+
+       if(buf) buf[argc][pos++] = '\0';
+       argc ++;
+       return argc;
+}
+static char **split_args(char *line)
+{
+       // 1. Count
+       int count = split_args_imp(line, NULL);
+       char **ret = malloc( (count + 1) * sizeof(char*) );
+       
+       split_args_imp(line, ret);
+       ret[count] = NULL;
+       return ret;
+}
+
+static char *read_line(int fd)
+{
+       // Read line (or up to ~128 bytes)
+       // - This assumes a default PTY state (i.e. line buffered, echo on)
+       char *ret = malloc(128);
+       size_t len = VFS_Read(STDIN, 128, ret);
+       ret[len] = 0;
+       return ret;
+}
+
+static int dprintf(int fd, const char *fmt, ...)
+{
+       va_list args;
+       va_start(args, fmt);
+       size_t len = vsnprintf(NULL, 0, fmt, args);
+       va_end(args);
+       
+       char buf[len+1];
+       va_start(args, fmt);
+       vsnprintf(buf, len+1, fmt, args);
+       va_end(args);
+       
+       VFS_Write(fd, len, buf);
+       
+       return len;
+}
+
index 9eac825..9892af3 100644 (file)
@@ -14,6 +14,7 @@ extern int    Modules_LoadBuiltins(void);
 extern void    Modules_SetBuiltinParams(char *Name, char *ArgString);
 extern void    Debug_SetKTerminal(const char *File);
 extern void    Timer_CallbackThread(void *);
+extern void    EmergencyConsole(void);
 
 // === PROTOTYPES ===
 void   System_Init(char *Commandline);
@@ -282,4 +283,5 @@ void System_ParseSetting(char *Arg)
 void System_EmergencyConsole(void)
 {
        // TODO: Support an emergency kernel-land console (with FS viewing support)
+       EmergencyConsole();
 }

UCC git Repository :: git.ucc.asn.au