command line fix

This commit is contained in:
Julian Barathieu 2019-05-18 19:40:24 +02:00
parent df479e6336
commit 247d8feeec
4 changed files with 36 additions and 30 deletions

View File

@ -240,7 +240,7 @@ size_t KalComputeArgVecSize(const char **argv);
// //
error_t KalCmdLineToArgVecEx(const char *cmdLine, error_t KalCmdLineToArgVecEx(const char *cmdLine,
int *argcPtr, int *argcPtr,
char **argv, char *bufptr,
bool doEscaping); bool doEscaping);
// //
@ -248,7 +248,7 @@ error_t KalCmdLineToArgVecEx(const char *cmdLine,
// //
error_t KalCmdLineToArgVec(const char *cmdLine, error_t KalCmdLineToArgVec(const char *cmdLine,
int *argcPtr, int *argcPtr,
char **argv); char *bufptr);
// //
// Argument vector to command line // Argument vector to command line

View File

@ -56,25 +56,17 @@ size_t KalComputeArgVecSize(const char *argv[])
// //
// Converts command line to an argument vector // Converts command line to an argument vector
// //
// This function assumes that argv[0] is a pointer // This function assumes that *argv is a (ARG_MAX * 2)-wide buffer,
// to a ARG_MAX-wide buffer, which will be filled // whose second half will be filled with strings in succession;
// with strings in succession; the address of the nth // with the address of the nth string stored in the first half,
// string will be stored in argv[n-1] // specifically at argv[n-1]
//
// Technically ARG_MAX is the maximum number of bytes
// in both the buffer *and* argv, i.e. (argc + 1) * sizeof(char *)
// bytes are reserved for the argv[i] pointers, so in fact less than
// ARG_MAX bytes are available
//
// That available space, however, remains strictly higher than 4KB,
// which is the POSIX minimum; the current ARG_MAX guarantees 16KB available
// //
// TODO long escape sequences // TODO long escape sequences
// get program command line if cmdLine == NULL // get program command line if cmdLine == NULL
// //
error_t KalCmdLineToArgVecEx(const char *cmdLine, error_t KalCmdLineToArgVecEx(const char *cmdLine,
int *argcPtr, int *argcPtr,
char **argv, char *bufptr,
bool doEscaping) bool doEscaping)
{ {
int argc = 0; int argc = 0;
@ -83,11 +75,17 @@ error_t KalCmdLineToArgVecEx(const char *cmdLine,
bool escaping = false; bool escaping = false;
size_t written = 0; size_t written = 0;
error_t retcode = EOK; error_t retcode = EOK;
bool maxreached = false;
assert_always(argv && *argv && cmdLine);
// An ARG_MAX-wide buffer // An ARG_MAX-wide buffer
char *buffer = *argv; char **argv = (char **)bufptr;
assert(argv && cmdLine);
// Another ARG_MAX-wide buffer
char *buffer = *argv + ARG_MAX;
argv[0] = buffer;
// Null-terminate current argv slot // Null-terminate current argv slot
// and save the start of next string // and save the start of next string
@ -111,12 +109,15 @@ error_t KalCmdLineToArgVecEx(const char *cmdLine,
for (; *cmdLine; cmdLine++) { for (; *cmdLine; cmdLine++) {
// Make sure we don't go beyond ARG_MAX bytes // Make sure we don't go beyond ARG_MAX bytes
if (written >= ARG_MAX - (1 + sizeof(char *))) { maxreached = written >= ARG_MAX - 1;
// Sanity check maxreached = maxreached || argc >= (int)(ARG_MAX/sizeof(char *) - 1);
assert(written == ARG_MAX - (1 + sizeof(char *)));
// All we have left is one byte for the null-terminator of the current slot if (maxreached) {
// and sizeof(char *) bytes for the NULL at the end of argv // Sanity check
assert(written == ARG_MAX - 1);
// All we have left is one byte for the null-terminator
// (or argv maxed out)
*buffer = 0; *buffer = 0;
// Did we write anything in this slot? // Did we write anything in this slot?
@ -193,6 +194,9 @@ error_t KalCmdLineToArgVecEx(const char *cmdLine,
*buffer++ = *cmdLine; *buffer++ = *cmdLine;
} }
// Ensures that the last string is null-terminated
*buffer = 0;
// Ensures that argv[argc] == NULL // Ensures that argv[argc] == NULL
argv[++argc] = NULL; argv[++argc] = NULL;
@ -211,7 +215,7 @@ error_t KalCmdLineToArgVecEx(const char *cmdLine,
error_t KalCmdLineToArgVec(const char *cmdLine, error_t KalCmdLineToArgVec(const char *cmdLine,
int *argcPtr, int *argcPtr,
char **argv) char *bufptr)
{ {
return KalCmdLineToArgVecEx(cmdLine, argcPtr, argv, false); return KalCmdLineToArgVecEx(cmdLine, argcPtr, bufptr, false);
} }

View File

@ -41,7 +41,7 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg)
IoEnableCursor(); IoEnableCursor();
IoUpdateCursor(0, 0); IoUpdateCursor(0, 0);
KernLog("%c%c%c OS/K\n\n", 219, 219, 219); //grrr KernLog("%c%c%c OS/K\n\n", 219, 219, 219);
// Sanity checks // Sanity checks
BtDoSanityChecks(mbMagic); BtDoSanityChecks(mbMagic);
@ -55,6 +55,8 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg)
KeSetupIDT(); KeSetupIDT();
KeEnableIRQs(); KeEnableIRQs();
//KalCmdLineToArgVec("test 1 2 3 4 5\n", &buf, );
// Start drivers // Start drivers
KeEnableRTC(); KeEnableRTC();
IoEnableKeyb(); IoEnableKeyb();

View File

@ -38,7 +38,7 @@ void ExecuteCommand(char *cmdbuf)
return; return;
memzero(*shargv, ARG_MAX); memzero(*shargv, ARG_MAX);
rc = KalCmdLineToArgVec(cmdbuf, &shargc, shargv); rc = KalCmdLineToArgVec(cmdbuf, &shargc, argv0);
if (rc) KeStartPanic("Shell: Couldn't parse command line: %d", rc); if (rc) KeStartPanic("Shell: Couldn't parse command line: %d", rc);
for (cmd = cmdtable; cmd->name != NULL; cmd++) { for (cmd = cmdtable; cmd->name != NULL; cmd++) {
@ -63,9 +63,9 @@ void KeStartShell(void)
char *cmdbuf = malloc(CMDBUFSIZE); char *cmdbuf = malloc(CMDBUFSIZE);
char *bufptr = cmdbuf; char *bufptr = cmdbuf;
argv0 = malloc(ARG_MAX); argv0 = malloc(ARG_MAX * 2);
memzero(argv0, ARG_MAX); memzero(argv0, ARG_MAX * 2);
shargv = &argv0; shargv = (char **)argv0;
KernLog("\nshell> "); KernLog("\nshell> ");
BFlushBuf(BStdOut); BFlushBuf(BStdOut);