//----------------------------------------------------------------------------// // GNU GPL OS/K // // // // Desc: Kernel shell // // // // // // Copyright © 2018-2019 The OS/K Team // // // // This file is part of OS/K. // // // // OS/K is free software: you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation, either version 3 of the License, or // // any later version. // // // // OS/K is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY//without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License for more details. // // // // You should have received a copy of the GNU General Public License // // along with OS/K. If not, see . // //----------------------------------------------------------------------------// #include "shell.h" int shargc = 0; char *argv0 = 0; char **shargv = 0; void ExecuteCommand(char *cmdbuf) { error_t rc; Command_t *cmd; bool found = false; if (!cmdbuf || !*cmdbuf) return; memzero(*shargv, ARG_MAX); rc = KalCmdLineToArgVec(cmdbuf, &shargc, shargv); if (rc) KeStartPanic("Shell: Couldn't parse command line: %d", rc); for (cmd = cmdtable; cmd->name != NULL; cmd++) { if (!strcmp(cmd->name, shargv[0])) { cmd->func(shargc, shargv, cmdbuf); found = true; break; } } if (found == false) { KernLog("err: command not found: '%s' (%ld)\n", shargv[0], strlen(shargv[0])); } } void KeStartShell(void) { uchar ch; error_t rc; char *cmdbuf = malloc(CMDBUFSIZE); char *bufptr = cmdbuf; argv0 = malloc(ARG_MAX); memzero(argv0, ARG_MAX); shargv = &argv0; KernLog("\nshell> "); BFlushBuf(BStdOut); while ((rc = BGetFromBuf(BStdIn, &ch)) == EOK || rc == EENDF) { // Reset BStdIn's content if (rc == EENDF) { if (!(BStdIn->flags & BF_ERR)) { *bufptr = 0; bufptr = cmdbuf; ExecuteCommand(cmdbuf); memzero(cmdbuf, CMDBUFSIZE); BFlushBuf(BStdIn); KernLog("shell> "); BFlushBuf(BStdOut); } else break; } switch (ch) { case KEY_BS: *bufptr = 0; if (bufptr > cmdbuf) { bufptr--; } break; case KEY_BEL: if (rand() % 16 == 0) { IoDoStarWars(); } else IoDoBeep(); break; case KEY_DC1: IoScrollUp(); break; case KEY_DC2: IoScrollDown(); break; case KEY_ESC: PoShutdown(); break; default: *bufptr++ = (char)ch; // End of buffer? if (bufptr != cmdbuf+CMDBUFSIZE-1) { break; // No } KernLog("\n"); // Else, fallthrough to case '\n' case '\n': *bufptr = 0; bufptr = cmdbuf; ExecuteCommand(cmdbuf); memzero(cmdbuf, CMDBUFSIZE); KernLog("shell> "); BFlushBuf(BStdIn); BFlushBuf(BStdOut); break; } KePauseCPU(); } KernLog("[EOI]\n"); }