From 903f33f40bc668843c8e8aaf6b61b28366e9e8c3 Mon Sep 17 00:00:00 2001 From: Nicolas Berr Date: Fri, 23 Sep 2011 15:31:44 +0200 Subject: [PATCH] - added support for changing current working directory - added cd, pwd command --- newlib/examples/mshell.c | 83 ++++++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 11 deletions(-) diff --git a/newlib/examples/mshell.c b/newlib/examples/mshell.c index 74323f3b..1f43a821 100644 --- a/newlib/examples/mshell.c +++ b/newlib/examples/mshell.c @@ -24,7 +24,9 @@ #include #include #include +#include #undef errno + extern int errno; void showlogo() { @@ -35,14 +37,22 @@ void showlogo() { } void help() { - printf("possible commands: \n"); - printf("exit > exit shell \n"); + printf("shell builtin commands: \n"); + printf("cd :\t change current working directory to path\n"); + printf("pwd :\t show current working directory\n"); + printf("help :\t this short help\n"); + printf("exit :\t exit the shell \n"); } -#define MAXARGS 16 +#define MAXARGS 16 +#define MAXPATH 128 +#define MAXCMDLINE 1024 #define ST_WHITE 0 -#define ST_ARG 1 +#define ST_ARG 1 +#define ST_QUOTE 2 + +#define USE_STAT 0 char** splitargs(char* args) { static char* ret[MAXARGS+1]; @@ -51,14 +61,22 @@ char** splitargs(char* args) { while (*args != '\0') { if (state == ST_WHITE) { if (!isspace(*args)) { + if(*args == '"') { + args++; + state = ST_QUOTE; + if (*args == '\0') + break; + } + else { + state = ST_ARG; + } ret[i++] = args; if (i == MAXARGS) break; - state = ST_ARG; } } else { - if (isspace(*args)) { + if ((state == ST_QUOTE && *args == '"') || isspace(*args)) { *args = '\0'; state = ST_WHITE; } @@ -70,18 +88,57 @@ char** splitargs(char* args) { return ret; } +char* ms_getcwd() { + return getenv("PWD"); +} + +void ms_setcwd(char* path) { + static char newpath[MAXPATH]; + static struct stat stats; + + if (path == NULL) + return; + + if (*path == NULL) + return; + + if (*path == '/') { + strcpy(newpath, path); + } + else { + char* oldpath = ms_getcwd(); + + if(oldpath[strlen(oldpath)-1] == '/') + sprintf(newpath,"%s%s", oldpath, path); + else + sprintf(newpath,"%s/%s", oldpath, path); + } + +#if USE_STAT + if (stat(newpath, &stats)) { + printf("mshell: %s is not a valid path\n", newpath); + return; + } + if (!S_ISDIR(stats.st_mode)) { + printf("mshell: %s is not a directory\n", newpath); + return; + } +#endif + + setenv("PWD", newpath, 1); +} + int main(int argc, char** argv) { - char commandline[1024]; + char commandline[MAXCMDLINE]; char* command; - int size = 0, status = 0; + int status = 0; pid_t pid; system("clear"); showlogo(); while(1) { char** newargv; - char* newenv[] = {"USER=root", "PATH=/bin:/sbin:/usr/bin", "PWD=/", "TEMP=/tmp", NULL}; printf("mshell> "); gets(commandline); @@ -97,12 +154,16 @@ int main(int argc, char** argv) } if(!strcmp(command, "help")) { help(); + } else if (!strcmp(command, "pwd")) { + printf("%s\n", ms_getcwd()); + } else if (!strcmp(command, "cd")) { + ms_setcwd(newargv[1]); } else { - char path[128]; + char path[MAXPATH]; sprintf(path, "/bin/%s", command); pid = fork(); if (pid == 0) { //child - status = execve(path, newargv, newenv); + status = execve(path, newargv, environ); if (status) printf("mshell: %s: command not found\n", path); return errno;