Index: trunk/user/ksh/ksh.c
===================================================================
--- trunk/user/ksh/ksh.c	(revision 230)
+++ trunk/user/ksh/ksh.c	(revision 407)
@@ -1,26 +1,41 @@
-/*
- * Authors: Clément Guérin and Alain Greiner (2015)
- */
-
+///////////////////////////////////////////////////////////////////////////////
+// File   :  ksh.c
+// Date   :  October 2017
+// Author :  Alain Greiner
+///////////////////////////////////////////////////////////////////////////////
+// This single thread application implement a simple shell for ALMOS-MKH.
+///////////////////////////////////////////////////////////////////////////////
+
+#include <nostdio.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <string.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include <errno.h>
-
-#define MAX_SIZE	(128)  // max number of characters in one command
-#define LOG_DEPTH   (128)  // max number of commands in log
-#define MAX_ARGS	(32)   // max number of arguments in a command
-#define FIFO_SIZE   (1024) // FIFO depth for recursive ls
-
-#define __unused(a)	(void)a
-
-extern char **environ;
+
+#define CMD_MAX_SIZE   (256)    // max number of characters in one command
+#define LOG_DEPTH      (256)    // max number of registered commands 
+#define MAX_ARGS	   (32)     // max number of arguments in a command
+#define FIFO_SIZE      (1024)   // FIFO depth for recursive ls
+
+////////////////////////////////////////////////////////////////////////////////
+//	   Structures
+////////////////////////////////////////////////////////////////////////////////
+
+// one entry in the registered commands array
+typedef struct log_entry_s 
+{
+	char          buf[CMD_MAX_SIZE];
+	unsigned int  count;
+}
+log_entry_t;
+
+// one entry in the supported command types array
+typedef struct ksh_cmd_s 
+{
+	char * name;
+	char * desc;
+	void   (*fn)( int , char ** );
+}
+ksh_cmd_t;
+
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -28,19 +43,10 @@
 ////////////////////////////////////////////////////////////////////////////////
 
-struct {
-	char buf[MAX_SIZE];
-	size_t count;
-} log_entries[LOG_DEPTH];
-
-size_t ptw; // write pointer in log
-size_t ptr; // read pointer in log
-
-struct command_t {
-	char *name;
-	char *desc;
-	void (*fn)(int, char **);
-};
-
-struct command_t cmd[];
+ksh_cmd_t       cmd[];                    // array of supported commands
+
+log_entry_t     log_entries[LOG_DEPTH];   // array of registered commands
+
+unsigned int    ptw;                      // write pointer in log_entries[]
+unsigned int    ptr;                      // read pointer in log_entries[]
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -48,26 +54,31 @@
 ////////////////////////////////////////////////////////////////////////////////
 
-static void cmd_cat(int argc, char **argv)
-{
-	char *path, *buf = NULL;
-	struct stat st;
-	size_t size;
-	int fd;
-
-	if (argc != 2) {
+/////////////////////////////////////////////
+static void cmd_cat( int argc , char **argv )
+{
+	char         * path;
+
+	if (argc != 2) 
+    {
 		printf("usage: cat pathname\n");
 		return;
 	}
+
 	path = argv[1];
 
-	/* open the file */
-	fd = open(path, O_RDONLY, 0);
-	if (fd < 0) {
+    printf("error: not implemented yet\n");
+
+/*
+	// open the file
+	fd = open( path , O_RDONLY , 0 );
+	if (fd < 0) 
+    {
 		printf("error: cannot open %s\n", path);
 		goto exit;
 	}
 
-	/* get file size */
-	if (stat(path, &st) == -1) {
+	// get file size 
+	if (stat(path, &st) == -1)
+    {
 		printf("error: cannot stat %s\n", path);
 		goto exit;
@@ -79,5 +90,5 @@
 	size = st.st_size;
 
-	/* mmap the file */
+	// mmap the file 
 	buf = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
 	if (buf == NULL || buf == (char *)-1) {
@@ -86,34 +97,64 @@
 	}
 
-	/* set terminating '0' XXX */
+	// set terminating '0' XXX
 	buf[size-1] = 0;
 
-	/* display the file content */
+	// display the file content
 	printf("%s", buf);
 
 exit:
-	if (buf != NULL)
-		munmap(buf, size);
-	if (fd >= 0)
-		close(fd);
-}
-
+	if (buf != NULL) munmap(buf, size);
+	if (fd >= 0) close(fd);
+*/
+
+}   // end cmd_cat()
+
+////////////////////////////////////////////
+static void cmd_cd( int argc , char **argv )
+{
+	char * path;
+
+	if (argc != 2)
+    {
+		printf("usage: cd pathname\n");
+		return;
+	}
+
+	path = argv[1];
+
+    printf("error: not implemented yet\n");
+/*
+	path = argv[1];
+
+	if (chdir(path) == -1) 
+    {
+		printf("error: cannot cd to %s\n", path);
+	}
+*/
+
+}   // end cmd_cd()
+
+/////////////////////////////////////////
 static void cmd_cp(int argc, char **argv)
 {
-	int src_fd = -1, dst_fd = -1;
-	char *srcpath, *dstpath;
-	struct stat st;
-	size_t size, i;
-	char buf[1024];
-
-	if (argc != 3) {
+//	int src_fd = -1, dst_fd = -1;
+//	char *srcpath, *dstpath;
+//	struct stat st;
+//	size_t size, i;
+//	char buf[1024];
+
+	if (argc != 3) 
+    {
 		printf("usage: cp src_pathname dst_pathname\n");
 		return;
 	}
 
+    printf("error: not implemented yet\n");
+
+/*
 	srcpath = argv[1];
 	dstpath = argv[2];
 
-	/* open the src file */
+	// open the src file 
 	src_fd = open(srcpath, O_RDONLY, 0);
 	if (src_fd < 0) {
@@ -122,5 +163,5 @@
 	}
 
-	/* get file size */
+	// get file size 
 	if (stat(srcpath, &st) == -1) {
 		printf("error: cannot stat %s\n", srcpath);
@@ -133,5 +174,5 @@
 	size = st.st_size;
 
-	/* open the dst file */
+	// open the dst file 
 	dst_fd = open(dstpath, O_CREAT|O_TRUNC|O_RDWR, 0);
 	if (dst_fd < 0) {
@@ -155,5 +196,5 @@
 		ssize_t ret;
 
-		/* read the source */
+		// read the source 
 		ret = read(src_fd, buf, rlen);
 		if (ret == -1) {
@@ -163,5 +204,5 @@
 		rlen = (size_t)ret;
 
-		/* write to the destination */
+		// write to the destination 
 		ret = write(dst_fd, buf, rlen);
 		if (ret == -1) {
@@ -171,5 +212,5 @@
 		wlen = (size_t)ret;
 
-		/* check */
+		// check 
 		if (wlen != rlen) {
 			printf("error: cannot write on device\n");
@@ -181,96 +222,131 @@
 
 exit:
-	if (src_fd >= 0)
-		close(src_fd);
-	if (dst_fd >= 0)
-		close(dst_fd);
-}
-
-static void cmd_exec(int argc, char **argv)
-{
-	pid_t pid, wpid;
-	int status;
-	char *path;
-
-	if (argc != 2) {
-		printf("usage: %s prog\n", argv[0]);
-		return;
-	}
-
-	path = argv[1];
-	argv++;
-
+	if (src_fd >= 0) close(src_fd);
+	if (dst_fd >= 0) close(dst_fd);
+*/
+
+}   // end cmd_cp()
+
+//////////////////////////////////////////////
+static void cmd_help( int argc , char **argv )
+{
+	unsigned int i;
+
+	if (argc != 1) 
+    {
+		printf("usage: %s\n", argv[0]);
+		return;
+	}
+
+	printf("available commands:\n");
+	for (i = 0 ; cmd[i].name ; i++) 
+    {
+		printf("\t%s\t : %s\n", cmd[i].name , cmd[i].desc);
+	}
+}   // end cmd_help()
+
+//////////////////////////////////////////////
+static void cmd_kill( int argc , char **argv )
+{
+	unsigned int pid;
+
+	if (argc != 2) 
+    {
+		printf("usage: %s pid\n", argv[0]);
+		return;
+	}
+
+	pid = atoi(argv[1]);
+
+	if( kill( pid , 9 ) )   // TODO replace 9 by SIGKILL
+    {
+		printf("error: unable to kill process %x\n", pid );
+	}
+}   // end cmd_kill()
+
+//////////////////////////////////////////////
+static void cmd_load( int argc , char **argv )
+{
+	unsigned int   pid;
+    unsigned int   error;
+	char         * pathname;
+
+	if (argc != 2) 
+    {
+		printf("usage: %s pathname \n", argv[0] );
+		return;
+	}
+
+	pathname = argv[1];
+
+    // fork system call
 	pid = fork();
-	if (pid == 0) {
-		/* child process */
-		if (execve(path, argv, environ) == -1) {
-			printf("error: unable to execve %s\n", path);
-		}
-		exit(EXIT_FAILURE);
-	} else if (pid < 0) {
-		/* error forking */
-		printf("error: unable to fork\n");
-	} else {
-		/* parent process */
-		do {
-			wpid = waitpid(pid, &status, WUNTRACED);
-		} while (!WIFEXITED(status) && !WIFSIGNALED(status));
-	}
-}
-
-static void cmd_help(int argc, char **argv)
-{
-	size_t i;
-	__unused(argc);
-	__unused(argv);
-	printf("available commands:\n");
-	for (i = 0; cmd[i].name; i++) {
-		printf("\t%s\t : %s\n", cmd[i].name , cmd[i].desc);
-	}
-}
-
-static void cmd_kill(int argc, char **argv)
-{
-	pid_t pid;
-
-	if (argc != 2) {
-		printf("usage: %s pid\n", argv[0]);
-		return;
-	}
-
-	pid = (pid_t)atoi(argv[1]);
-
-	if (kill(pid, SIGKILL) == -1) {
-		printf("error: unable to kill %d\n", (int)pid);
-	}
-}
-
-static void cmd_log(int argc, char **argv)
-{
-	size_t i;
-	__unused(argc);
-	__unused(argv);
+
+    if (pid == 0)  // it is the child process 
+    {
+
+printf("\n[KSH_DBG] process %x before exec\n", getpid() );
+
+        // exec system call
+        error = exec( pathname , NULL , NULL );
+
+printf("\n[KSH_DBG] process %x after exec / error = %d\n", getpid() , error );
+
+        if( error )
+        {
+            printf("error: new process unable to exec <%s>\n", pathname );
+            // TODO exit();
+        }
+	} 
+    else if ( pid < 0 )  // it is a failure reported to parent
+    {
+        printf("error: unable to fork\n");
+    }
+    else                 // it is a success reported to parent
+    {
+
+printf("\n[KSH_DBG] process %x created for <%s>\n", pid, pathname );
+
+    }
+
+}   // end cmd_load
+
+/////////////////////////////////////////////
+static void cmd_log( int argc , char **argv )
+{
+	unsigned int i;
+
 	printf("--- registered commands ---\n");
-	for (i = 0; i < LOG_DEPTH; i++) {
+	for (i = 0; i < LOG_DEPTH; i++) 
+    {
 		printf(" - %zu\t: %s\n", i, &log_entries[i].buf);
 	}
 }
 
-static void cmd_ls(int argc, char **argv)
-{
-    struct dirent *file;
-	char *path;
-    DIR *dir;
-
-	if (argc == 1) {
+////////////////////////////////////////////
+static void cmd_ls( int argc , char **argv )
+{
+	char  * path;
+
+//  struct dirent * file;
+//  DIR *dir;
+
+	if (argc == 1)
+    {
 		path = ".";
-	} else if (argc == 2) {
+	}
+    else if (argc == 2) 
+    {
 		path = argv[1];
-	} else {
+	} 
+    else 
+    {
 		printf("usage: ls [path]\n");
 		return;
 	}
 
-	dir = opendir(path);
+    printf("error: not implemented yet\n");
+/*
+	dir = opendir( path );
 	while ((file = readdir(dir)) != NULL)
 	{
@@ -278,25 +354,33 @@
 	}
 	closedir(dir);
-}
-
-static void cmd_mkdir(int argc, char **argv)
-{
-	char *path;
-
-	if (argc != 2) {
+*/
+}
+
+///////////////////////////////////////////////
+static void cmd_mkdir( int argc , char **argv )
+{
+	char * pathname;
+
+	if (argc != 2)
+    {
 		printf("usage: mkdir pathname\n");
 		return;
 	}
 
-	path = argv[1];
-
-	if (mkdir(path, 0700) == -1) {
+    pathname = argv[1];
+
+    printf("error: not implemented yet\n");
+/*
+	if ( mkdir( path, 0x700) == -1 )
+    {
 		printf("error: cannot create directory %s\n", path);
 	}
-}
-
-static void cmd_mv(int argc, char **argv)
-{
-#if 0
+*/
+}
+
+////////////////////////////////////////////
+static void cmd_mv( int argc , char **argv )
+{
+
 	if (argc < 3)
 	{
@@ -305,4 +389,7 @@
 	}
 
+    printf("error: not implemented yet\n");
+    
+/*
 	int ret = giet_fat_rename(argv[1], argv[2]);
 	if (ret < 0)
@@ -310,81 +397,105 @@
 		printf("error : cannot move %s to %s / err = %d\n", argv[1], argv[2], ret );
 	}
-#endif
-}
-
-static void cmd_rm(int argc, char **argv)
-{
-	char *path;
-
-	if (argc != 2) {
+*/
+
+}
+
+/////////////////////////////////////////////
+static void cmd_pwd( int argc , char **argv )
+{
+	char buf[1024];
+
+	if (argc != 1)
+    {
+		printf("usage: pwd\n");
+		return;
+	}
+
+	if ( getcwd( buf , 1024 ) ) 
+    {
+		printf("error: unable to get current directory\n");
+	}
+    else 
+    {
+		printf("%s\n", buf);
+	}
+}
+
+////////////////////////////////////////////
+static void cmd_rm( int argc , char **argv )
+{
+	char * pathname;
+
+	if (argc != 2)
+    {
 		printf("usage: rm pathname\n");
 		return;
 	}
 
-	path = argv[1];
-
-	if (remove(path) == -1) {
+	pathname = argv[1];
+
+    printf("error: not implemented yet\n");
+/*
+	if (remove(path) == -1)
+    {
 		printf("error: cannot remove %s\n", path);
 	}
-}
-
-static void cmd_rmdir(int argc, char **argv)
+*/
+
+}
+
+///////////////////////////////////////////////
+static void cmd_rmdir( int argc , char **argv )
 {
 	cmd_rm(argc, argv);
 }
 
-static void cmd_cd(int argc, char **argv)
-{
-	char *path;
-
-	if (argc != 2) {
-		printf("usage: cd pathname\n");
-		return;
-	}
-
-	path = argv[1];
-
-	if (chdir(path) == -1) {
-		printf("error: cannot cd to %s\n", path);
-	}
-}
-
-static void cmd_pwd(int argc, char **argv)
-{
-	char buf[1024];
-
-	if (argc != 1) {
-		printf("usage: pwd\n");
-		return;
-	}
-
-	if (getcwd(buf, 1024) == NULL) {
-		printf("error: unable to get current directory\n");
-	} else {
-		printf("%s\n", buf);
-	}
-}
-
-struct command_t cmd[] =
-{
-	{ "cat",    "display file content",                cmd_cat },
-	{ "cd",     "change current directory",            cmd_cd },
-	{ "cp",     "replicate a file in file system",     cmd_cp },
-	{ "exec",   "start an application",                cmd_exec },
-	{ "help",   "list available commands",             cmd_help },
-	{ "kill",   "kill an application (all threads)",   cmd_kill },
-	{ "log",    "list registered commands",            cmd_log },
-	{ "ls",     "list directory entries",              cmd_ls },
+///////////////////////////////////////////////
+static void cmd_sched( int argc , char **argv )
+{
+    unsigned int cxy;
+    unsigned int lid;
+
+	if (argc != 3)
+    {
+		printf("usage: sched cxy lid\n");
+		return;
+	}
+
+	cxy = atoi(argv[1]);
+	lid = atoi(argv[2]);
+
+    if( get_sched( cxy , lid ) )
+    {
+        printf("error: illegal arguments\n");
+    }
+}
+
+//////////////////////////////////////////////////////////////////
+// Array of commands
+//////////////////////////////////////////////////////////////////
+
+ksh_cmd_t cmd[] =
+{
+	{ "cat",    "display file content",                cmd_cat   },
+	{ "cd",     "change current directory",            cmd_cd    },
+	{ "cp",     "replicate a file in file system",     cmd_cp    },
+	{ "load",   "load an user application",            cmd_load  },
+	{ "help",   "list available commands",             cmd_help  },
+	{ "kill",   "kill an application (all threads)",   cmd_kill  },
+	{ "log",    "list registered commands",            cmd_log   },
+	{ "ls",     "list directory entries",              cmd_ls    },
 	{ "mkdir",  "create a new directory",              cmd_mkdir },
-	{ "mv",     "move a file in file system",          cmd_mv },
-	{ "pwd",    "print current working directory",     cmd_pwd },
-	{ "rm",     "remove a file from file system",      cmd_rm },
+	{ "mv",     "move a file in file system",          cmd_mv    },
+	{ "pwd",    "print current working directory",     cmd_pwd   },
+	{ "rm",     "remove a file from file system",      cmd_rm    },
 	{ "rmdir",  "remove a directory from file system", cmd_rmdir },
-	{ NULL,     NULL,								   NULL }
+    { "sched",  "display scheduler state",             cmd_sched },
+	{ NULL,     NULL,								   NULL      }
 };
 
-///////////////////////////////////////////////////////////////////
-// This function analyses one command (with arguments)
-///////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+// This function analyses one command (with arguments), execute it, and return.
+////////////////////////////////////////////////////////////////////////////////////
 static void parse(char *buf)
 {
@@ -395,9 +506,14 @@
 
 	// build argc/argv
-	for (i = 0; i < len; i++) {
-		if (buf[i] == ' ') {
+	for (i = 0; i < len; i++) 
+    {
+		if (buf[i] == ' ') 
+        {
 			buf[i] = '\0';
-		} else if (i == 0 || buf[i - 1] == '\0') {
-			if (argc < MAX_ARGS) {
+		}
+        else if (i == 0 || buf[i - 1] == '\0') 
+        {
+			if (argc < MAX_ARGS) 
+            {
 				argv[argc] = &buf[i];
 				argc++;
@@ -406,12 +522,15 @@
 	}
 
-	if (argc > 0) {
+	if (argc > 0)
+    {
 		int found = 0;
 
 		argv[argc] = NULL;
 
-		// try to match typed command with built-ins
-		for (i = 0; cmd[i].name; i++) {
-			if (strcmp(argv[0], cmd[i].name) == 0) {
+		// try to match typed command 
+		for (i = 0; cmd[i].name; i++)
+        {
+			if (strcmp(argv[0], cmd[i].name) == 0)
+            {
 				cmd[i].fn(argc, argv);
 				found = 1;
@@ -420,5 +539,6 @@
 		}
 
-		if (!found) {
+		if (!found)
+        {
 			printf("\n  undefined command %s\n", argv[0]);
 		}
@@ -426,14 +546,14 @@
 }
 
-int main(int argc, char *argv[])
-{
-	char c;							  // read character
-	char buf[MAX_SIZE];				  // buffer for one command
-	size_t count = 0;					  // pointer in buf
-	size_t i, j;						  // indexes for loops
-	__unused(argc);
-	__unused(argv);
-
-	enum fsm_states {
+///////////////////////////////////
+int main( int argc , char *argv[] )
+{
+	char         c;						  // read character
+	char         buf[CMD_MAX_SIZE];		  // buffer for one command
+	unsigned int count = 0;				  // pointer in buf
+	unsigned int i;						  // index for loops
+
+	enum fsm_states 
+    {
 		NORMAL,
 		ESCAPE,
@@ -441,12 +561,13 @@
 	};
 
-	memset(&log_entries, 0, sizeof(log_entries));
-	ptw = 0;
-	ptr = 0;
+    // log buffer initialisation
+	memset( &log_entries , 0, sizeof(log_entries));
+	ptw   = 0;
+	ptr   = 0;
 
 	printf( "~~~ shell ~~~\n\n" );
 
 	// command buffer initialisation
-	memset(buf, 0x20, sizeof(buf));
+	memset( buf, 0x20 , sizeof(buf) );
 	count = 0;
 
@@ -460,5 +581,5 @@
 	// - ESC [ C : right arrow
 	// - ESC [ D : left arrow
-	// The thee states have the following semantic:
+	// The three states have the following semantic:
 	// - NORMAL : no (ESC) character has been found
 	// - ESCAPE : the character (ESC) has been found
@@ -466,11 +587,13 @@
 	unsigned int state = NORMAL;
 
+// @@@
+parse("load /bin/user/sort.elf");
+// @@@
+    
 	while (1)
 	{
-		/*
-		 * Certainly not a good idea to use getchar. The escape sequences won't
-		 * be handled correctly.
-		 */
-		c = getchar();
+		c = (char)getchar();
+
+        if( c == 0 ) continue;
 
 		switch (state)
