Usermode/libaxwin4 - Handle demarshal failure
[tpg/acess2.git] / Usermode / Applications / CLIShell_src / main.c
index 89bfe0d..6de92df 100644 (file)
@@ -7,18 +7,16 @@
 #include <stdio.h>\r
 #include <string.h>\r
 #include "header.h"\r
-\r
-#if USE_READLINE\r
-# include "readline.h"\r
-#endif\r
+#include <readline.h>\r
+#include <errno.h>\r
+#include <acess/devices/pty.h>\r
 \r
 #define _stdin 0\r
 #define _stdout        1\r
 #define _stderr        2\r
 \r
 // ==== PROTOTYPES ====\r
-char   *ReadCommandLine(int *Length);\r
-void   Parse_Args(char *str, char **dest);\r
+ int   Parse_Args(const char *str, char **dest);\r
 void   CallCommand(char **Args);\r
 void   Command_Logout(int argc, char **argv);\r
 void   Command_Clear(int argc, char **argv);\r
@@ -35,11 +33,11 @@ struct      {
        {"help", Command_Help}, {"clear", Command_Clear},\r
        {"cd", Command_Cd}, {"dir", Command_Dir}\r
 };\r
-static char    *cDEFAULT_PATH[] = {"/Acess/Bin"};\r
+static char    *cDEFAULT_PATH[] = {"/Acess/Bin","/Acess/SBin"};\r
 #define        BUILTIN_COUNT   (sizeof(cBUILTINS)/sizeof(cBUILTINS[0]))\r
 \r
 // ==== LOCAL VARIABLES ====\r
- int   giNumPathDirs = 1;\r
+ int   giNumPathDirs = 2;\r
 char   **gasPathDirs = cDEFAULT_PATH;\r
 char   **gasEnvironment;\r
 char   gsCommandBuffer[1024];\r
@@ -53,18 +51,13 @@ int main(int argc, char *argv[], char **envp)
 {\r
        char    *sCommandStr;\r
        char    *saArgs[32] = {0};\r
-        int    length = 0;\r
         int    i;\r
         int    iArgCount = 0;\r
-       #if !USE_READLINE\r
-        int    bCached = 1;\r
-       #else\r
        tReadline       *readline_state = Readline_Init(1);\r
-       #endif\r
        \r
        gasEnvironment = envp;\r
        \r
-       Command_Clear(0, NULL);\r
+//     Command_Clear(0, NULL);\r
        \r
        {\r
                char    *tmp = getenv("CWD");\r
@@ -81,46 +74,21 @@ int main(int argc, char *argv[], char **envp)
        for(;;)\r
        {\r
                // Free last command & arguments\r
-               if(saArgs[0])   free(saArgs);\r
-               #if !USE_READLINE\r
-               if(!bCached)    free(sCommandStr);\r
-               bCached = 0;\r
-               #endif\r
+               if(saArgs[0])   free(saArgs[0]);\r
                \r
                printf("%s$ ", gsCurrentDirectory);\r
+               fflush(stdout);\r
                \r
                // Read Command line\r
-               #if USE_READLINE\r
                sCommandStr = Readline( readline_state );\r
                printf("\n");\r
-               length = strlen(sCommandStr);\r
-               #else\r
-               sCommandStr = ReadCommandLine( &length );\r
-               \r
-               if(!sCommandStr) {\r
-                       printf("PANIC: Out of heap space\n");\r
-                       return -1;\r
+               if( !sCommandStr ) {\r
+                       perror("Readline");\r
+                       return 1;\r
                }\r
                \r
-               // Check if the command should be cached\r
-               if(gasCommandHistory == NULL || strcmp(sCommandStr, gasCommandHistory[giLastCommand]) != 0)\r
-               {\r
-                       if(giLastCommand >= giCommandSpace) {\r
-                               giCommandSpace += 12;\r
-                               gasCommandHistory = realloc(gasCommandHistory, giCommandSpace*sizeof(char*));\r
-                       }\r
-                       giLastCommand ++;\r
-                       gasCommandHistory[ giLastCommand ] = sCommandStr;\r
-                       bCached = 1;\r
-               }\r
-               #endif\r
-               \r
                // Parse Command Line into arguments\r
-               Parse_Args(sCommandStr, saArgs);\r
-               \r
-               // Count Arguments\r
-               iArgCount = 0;\r
-               while(saArgs[iArgCount])        iArgCount++;\r
+               iArgCount = Parse_Args(sCommandStr, saArgs);\r
                \r
                // Silently Ignore all empty commands\r
                if(saArgs[1][0] == '\0')        continue;\r
@@ -139,157 +107,15 @@ int main(int argc, char *argv[], char **envp)
                // Shall we?\r
                CallCommand( &saArgs[1] );\r
                \r
-               #if USE_READLINE\r
                free( sCommandStr );\r
-               #endif\r
        }\r
 }\r
 \r
-#if !USE_READLINE\r
-/**\r
- * \fn char *ReadCommandLine(int *Length)\r
- * \brief Read from the command line\r
- */\r
-char *ReadCommandLine(int *Length)\r
-{\r
-       char    *ret;\r
-        int    len, pos, space = 1023;\r
-       char    ch;\r
-       #if 0\r
-        int    scrollbackPos = giLastCommand;\r
-       #endif\r
-        \r
-       // Preset Variables\r
-       ret = malloc( space+1 );\r
-       if(!ret)        return NULL;\r
-       len = 0;        pos = 0;\r
-               \r
-       // Read In Command Line\r
-       do {\r
-               ch = getchar(); // Read Character from stdin (read is a blocking call)\r
-               if(ch == '\n')  break;\r
-               \r
-               switch(ch)\r
-               {\r
-               // Control characters\r
-               case '\x1B':\r
-                       ch = getchar(); // Read control character\r
-                       switch(ch)\r
-                       {\r
-                       //case 'D':     if(pos) pos--;  break;\r
-                       //case 'C':     if(pos<len)     pos++;  break;\r
-                       case '[':\r
-                               ch = getchar(); // Read control character\r
-                               switch(ch)\r
-                               {\r
-                               #if 0\r
-                               case 'A':       // Up\r
-                                       {\r
-                                                int    oldLen = len;\r
-                                               if( scrollbackPos > 0 ) break;\r
-                                               \r
-                                               free(ret);\r
-                                               ret = strdup( gasCommandHistory[--scrollbackPos] );\r
-                                               \r
-                                               len = strlen(ret);\r
-                                               while(pos--)    printf("\x1B[D");\r
-                                               write(_stdout, len, ret);       pos = len;\r
-                                               while(pos++ < oldLen)   write(_stdout, 1, " ");\r
-                                       }\r
-                                       break;\r
-                               case 'B':       // Down\r
-                                       {\r
-                                                int    oldLen = len;\r
-                                               if( scrollbackPos < giLastCommand-1 )   break;\r
-                                               \r
-                                               free(ret);\r
-                                               ret = strdup( gasCommandHistory[++scrollbackPos] );\r
-                                               \r
-                                               len = strlen(ret);\r
-                                               while(pos--)    write(_stdout, 3, "\x1B[D");\r
-                                               write(_stdout, len, ret);       pos = len;\r
-                                               while(pos++ < oldLen)   write(_stdout, 1, " ");\r
-                                       }\r
-                                       break;\r
-                               #endif\r
-                               case 'D':       // Left\r
-                                       if(pos == 0)    break;\r
-                                       pos --;\r
-                                       printf("\x1B[D");\r
-                                       break;\r
-                               case 'C':       // Right\r
-                                       if(pos == len)  break;\r
-                                       pos++;\r
-                                       printf("\x1B[C");\r
-                                       break;\r
-                               }\r
-                       }\r
-                       break;\r
-               \r
-               // Backspace\r
-               case '\b':\r
-                       if(len <= 0)            break;  // Protect against underflows\r
-                       putchar(ch);\r
-                       if(pos == len) {        // Simple case of end of string\r
-                               len --;\r
-                               pos--;\r
-                       }\r
-                       else {\r
-                               printf("%.*s ", len-pos, &ret[pos]);    // Move Text\r
-                               printf("\x1B[%iD", len-pos+1);\r
-                               // Alter Buffer\r
-                               memmove(&ret[pos-1], &ret[pos], len-pos);\r
-                               pos --;\r
-                               len --;\r
-                       }\r
-                       break;\r
-               \r
-               // Tab\r
-               case '\t':\r
-                       //TODO: Implement Tab-Completion\r
-                       //Currently just ignore tabs\r
-                       break;\r
-               \r
-               default:                \r
-                       // Expand Buffer\r
-                       if(len+1 > space) {\r
-                               space += 256;\r
-                               ret = realloc(ret, space+1);\r
-                               if(!ret)        return NULL;\r
-                       }\r
-                       \r
-                       // Editing inside the buffer\r
-                       if(pos != len) {\r
-                               putchar(ch);    // Print new character\r
-                               printf("%.*s", len-pos, &ret[pos]);     // Move Text\r
-                               printf("\x1B[%iD", len-pos);\r
-                               memmove( &ret[pos+1], &ret[pos], len-pos );\r
-                       }\r
-                       else {\r
-                               putchar(ch);\r
-                       }\r
-                       ret[pos++] = ch;\r
-                       len ++;\r
-                       break;\r
-               }\r
-       } while(ch != '\n');\r
-       \r
-       // Cap String\r
-       ret[len] = '\0';\r
-       printf("\n");\r
-       \r
-       // Return length\r
-       if(Length)      *Length = len;\r
-       \r
-       return ret;\r
-}\r
-#endif\r
-\r
 /**\r
- * \fn void Parse_Args(char *str, char **dest)\r
+ * \fn int Parse_Args(const char *str, char **dest)\r
  * \brief Parse a string into an argument array\r
  */\r
-void Parse_Args(char *str, char **dest)\r
+int Parse_Args(const char *str, char **dest)\r
 {\r
         int    i = 1;\r
        char    *buf = malloc( strlen(str) + 1 );\r
@@ -297,7 +123,7 @@ void Parse_Args(char *str, char **dest)
        if(buf == NULL) {\r
                dest[0] = NULL;\r
                printf("Parse_Args: Out of heap space!\n");\r
-               return ;\r
+               return 0;\r
        }\r
        \r
        strcpy(buf, str);\r
@@ -324,10 +150,8 @@ void Parse_Args(char *str, char **dest)
                if(*buf == '\0')        break;\r
        }\r
        dest[i] = NULL;\r
-       if(i == 1) {\r
-               free(buf);\r
-               dest[0] = NULL;\r
-       }\r
+       \r
+       return i;\r
 }\r
 \r
 /**\r
@@ -348,15 +172,15 @@ void CallCommand(char **Args)
        {\r
                GeneratePath(exefile, gsCurrentDirectory, sTmpBuffer);\r
                // Check file existence\r
-               fd = open(sTmpBuffer, OPENFLAG_EXEC);\r
+               fd = _SysOpen(sTmpBuffer, OPENFLAG_EXEC);\r
                if(fd == -1) {\r
                        printf("Unknown Command: `%s'\n", Args[0]);     // Error Message\r
                        return ;\r
                }\r
                \r
                // Get File info and close file\r
-               finfo( fd, &info, 0 );\r
-               close( fd );\r
+               _SysFInfo( fd, &info, 0 );\r
+               _SysClose( fd );\r
                \r
                // Check if the file is a directory\r
                if(info.flags & FILEFLAG_DIRECTORY) {\r
@@ -372,10 +196,10 @@ void CallCommand(char **Args)
                for( i = 0; i < giNumPathDirs; i++ )\r
                {\r
                        GeneratePath(exefile, gasPathDirs[i], sTmpBuffer);\r
-                       fd = open(sTmpBuffer, OPENFLAG_EXEC);\r
+                       fd = _SysOpen(sTmpBuffer, OPENFLAG_EXEC);\r
                        if(fd == -1)    continue;\r
-                       finfo( fd, &info, 0 );\r
-                       close( fd );\r
+                       _SysFInfo( fd, &info, 0 );\r
+                       _SysClose( fd );\r
                        if(info.flags & FILEFLAG_DIRECTORY)     continue;\r
                        // Woohoo! We found a valid command\r
                        break;\r
@@ -389,19 +213,28 @@ void CallCommand(char **Args)
        }\r
        \r
        // Create new process\r
-       pid = clone(CLONE_VM, 0);\r
-       // Start Task\r
-       if(pid == 0) {\r
-               execve(sTmpBuffer, Args, gasEnvironment);\r
-               printf("Execve returned, ... oops\n");\r
-               exit(-1);\r
-       }\r
+       int fds[] = {0, 1, 2};\r
+        int    status;\r
+       pid = _SysSpawn(sTmpBuffer, (const char **)Args, (const char **)gasEnvironment, 3, fds, NULL);\r
        if(pid <= 0) {\r
                printf("Unable to create process: `%s'\n", sTmpBuffer); // Error Message\r
+               status = 0;\r
        }\r
        else {\r
-                int    status;\r
-               waittid(pid, &status);\r
+               _SysIOCtl(0, PTY_IOCTL_SETPGRP, &pid);\r
+               _SysWaitTID(pid, &status);\r
+       }\r
+       \r
+       // Return terminal to a sane state\r
+       {\r
+               int zero = 0;\r
+               _SysIOCtl(0, PTY_IOCTL_SETPGRP, &zero);\r
+               printf("\x1b[0m");\r
+       }\r
+       // Print a status message if termination was non-clean\r
+       if( status )\r
+       {\r
+               printf("[%i] exited %i\n", pid, status);\r
        }\r
 }\r
 \r
@@ -439,7 +272,7 @@ void Command_Help(int argc, char **argv)
  */\r
 void Command_Clear(int argc, char **argv)\r
 {\r
-       write(_stdout, "\x1B[2J", 4);   //Clear Screen\r
+       _SysWrite(_stdout, "\x1B[2J", 4);       //Clear Screen\r
 }\r
 \r
 /**\r
@@ -460,13 +293,13 @@ void Command_Cd(int argc, char **argv)
        \r
        GeneratePath(argv[1], gsCurrentDirectory, tmpPath);\r
        \r
-       fp = open(tmpPath, 0);\r
+       fp = _SysOpen(tmpPath, 0);\r
        if(fp == -1) {\r
                printf("Directory does not exist\n");\r
                return;\r
        }\r
-       finfo(fp, &stats, 0);\r
-       close(fp);\r
+       _SysFInfo(fp, &stats, 0);\r
+       _SysClose(fp);\r
        \r
        if( !(stats.flags & FILEFLAG_DIRECTORY) ) {\r
                printf("Not a Directory\n");\r
@@ -478,7 +311,7 @@ void Command_Cd(int argc, char **argv)
        strcpy(gsCurrentDirectory, tmpPath);\r
        \r
        // Register change with kernel\r
-       chdir( gsCurrentDirectory );\r
+       _SysChdir( gsCurrentDirectory );\r
 }\r
 \r
 /**\r
@@ -487,55 +320,43 @@ void Command_Cd(int argc, char **argv)
  */\r
 void Command_Dir(int argc, char **argv)\r
 {\r
-        int    dp, fp, dirLen;\r
+        int    dp, fp;\r
        char    modeStr[11] = "RWXrwxRWX ";\r
-       char    tmpPath[1024];\r
-       char    *fileName;\r
+       char    fileName[256];\r
        t_sysFInfo      info;\r
        t_sysACL        acl;\r
        \r
+\r
+       // -- Generate and open directory --\r
        // Generate Directory Path\r
+       char    tmpPath[1024];\r
        if(argc > 1)\r
-               dirLen = GeneratePath(argv[1], gsCurrentDirectory, tmpPath);\r
+               GeneratePath(argv[1], gsCurrentDirectory, tmpPath);\r
        else\r
-       {\r
                strcpy(tmpPath, gsCurrentDirectory);\r
-       }\r
-       dirLen = strlen(tmpPath);\r
-       \r
        // Open Directory\r
-       dp = open(tmpPath, OPENFLAG_READ);\r
-       // Check if file opened\r
-       if(dp == -1)\r
-       {\r
+       dp = _SysOpen(tmpPath, OPENFLAG_READ);\r
+       if(dp == -1) {\r
                printf("Unable to open directory `%s', File cannot be found\n", tmpPath);\r
                return;\r
        }\r
        // Get File Stats\r
-       if( finfo(dp, &info, 0) == -1 )\r
+       if( _SysFInfo(dp, &info, 0) == -1 )\r
        {\r
-               close(dp);\r
+               _SysClose(dp);\r
                printf("stat Failed, Bad File Descriptor\n");\r
                return;\r
        }\r
        // Check if it's a directory\r
        if(!(info.flags & FILEFLAG_DIRECTORY))\r
        {\r
-               close(dp);\r
+               _SysClose(dp);\r
                printf("Unable to open directory `%s', Not a directory\n", tmpPath);\r
                return;\r
        }\r
        \r
-       // Append Shash for file paths\r
-       if(tmpPath[dirLen-1] != '/')\r
-       {\r
-               tmpPath[dirLen++] = '/';\r
-               tmpPath[dirLen] = '\0';\r
-       }\r
-       \r
-       fileName = (char*)(tmpPath+dirLen);\r
-       // Read Directory Content\r
-       while( (fp = readdir(dp, fileName)) )\r
+       // -- Read Directory Contents --\r
+       while( (fp = _SysReadDir(dp, fileName)) )\r
        {\r
                if(fp < 0)\r
                {\r
@@ -544,10 +365,10 @@ void Command_Dir(int argc, char **argv)
                        break;\r
                }\r
                // Open File\r
-               fp = open(tmpPath, 0);\r
+               fp = _SysOpenChild(dp, fileName, 0);\r
                if(fp == -1)    continue;\r
                // Get File Stats\r
-               finfo(fp, &info, 0);\r
+               _SysFInfo(fp, &info, 0);\r
                \r
                if(info.flags & FILEFLAG_DIRECTORY)\r
                        printf("d");\r
@@ -574,7 +395,7 @@ void Command_Dir(int argc, char **argv)
                if(acl.perms & 2)       modeStr[7] = 'w';       else    modeStr[7] = '-';\r
                if(acl.perms & 8)       modeStr[8] = 'x';       else    modeStr[8] = '-';\r
                printf(modeStr);\r
-               close(fp);\r
+               _SysClose(fp);\r
                \r
                // Colour Code\r
                if(info.flags & FILEFLAG_DIRECTORY)     // Directory: Green\r
@@ -595,5 +416,5 @@ void Command_Dir(int argc, char **argv)
                printf("\n");\r
        }\r
        // Close Directory\r
-       close(dp);\r
+       _SysClose(dp);\r
 }\r

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