diff --git a/ChangeLog b/ChangeLog
index 1c828cf7ecef3f73c9a93604bbdd635660e464d4..9ba531c355945c804515700261bd4bc5314ca43e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -412,4 +412,6 @@
 	* Correct an error in the FAT that caused files opened for writing with
 	  O_APPEND to fail.  The file was not being properly positioned to the
 	  end of the file in that case.
+	* NSH now supports last exit status $?
+	* NSH now supports if-then[-else]-fi construct
 
diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html
index c4bbf8b42029cb6247a627d1c48385750d67f1f4..f84038533cfb8bff1934a4966429074dcbb9c1cc 100644
--- a/Documentation/NuttX.html
+++ b/Documentation/NuttX.html
@@ -1046,6 +1046,8 @@ nuttx-0.3.13 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
 	* Correct an error in the FAT that caused files opened for writing with
 	  O_APPEND to fail.  The file was not being properly positioned to the
 	  end of the file in that case.
+	* NSH now supports last exit status $?
+	* NSH now supports if-then[-else]-fi construct
 
 pascal-0.1.3 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
 
diff --git a/examples/nsh/nsh.h b/examples/nsh/nsh.h
index 4855ea3669c50eb21cbe08713159367f06d17650..574e032212a835abc09c015926dbfee19a5ee069 100644
--- a/examples/nsh/nsh.h
+++ b/examples/nsh/nsh.h
@@ -112,8 +112,32 @@
  * Public Types
  ****************************************************************************/
 
+enum nsh_parser_e
+{
+   NSH_PARSER_NORMAL = 0,
+   NSH_PARSER_IF,
+   NSH_PARSER_THEN,
+   NSH_PARSER_ELSE
+};
+
+struct nsh_parser_s
+{
+  boolean   np_bg;       /* TRUE: The last command executed in background */
+  boolean   np_redirect; /* TRUE: Output from the last command was re-directed */
+  boolean   np_fail;     /* TRUE: The last command failed */
+  boolean   np_ifcond;   /* Value of command in 'if' statement */
+  ubyte     np_state;    /* Parser state (see enum nsh_parser_e) */
+  int       np_nice;     /* "nice" value applied to last background cmd */
+};
+
 struct nsh_vtbl_s
 {
+  /* This function pointers are "hooks" into the front end logic to
+   * handle things like output of command results, redirection, etc.
+   * -- all of which must be done in a way that is unique to the nature
+   * of the front end.
+   */
+   
   FAR struct nsh_vtbl_s *(*clone)(FAR struct nsh_vtbl_s *vtbl);
   void (*addref)(FAR struct nsh_vtbl_s *vtbl);
   void (*release)(FAR struct nsh_vtbl_s *vtbl);
@@ -122,9 +146,13 @@ struct nsh_vtbl_s
   void (*redirect)(FAR struct nsh_vtbl_s *vtbl, int fd, FAR ubyte *save);
   void (*undirect)(FAR struct nsh_vtbl_s *vtbl, FAR ubyte *save);
   void (*exit)(FAR struct nsh_vtbl_s *vtbl);
+
+  /* Parser state data */
+
+  struct nsh_parser_s np;
 };
 
-typedef void (*cmd_t)(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+typedef int (*cmd_t)(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
 
 /****************************************************************************
  * Public Data
@@ -137,6 +165,7 @@ extern const char g_fmtcmdnotfound[];
 extern const char g_fmtcmdnotimpl[];
 extern const char g_fmtnosuch[];
 extern const char g_fmttoomanyargs[];
+extern const char g_fmtcontext[];
 extern const char g_fmtcmdfailed[];
 extern const char g_fmtcmdoutofmemory[];
 
@@ -160,42 +189,42 @@ extern int nsh_telnetmain(int argc, char *argv[]);
 
 /* Shell command handlers */
 
-extern void cmd_echo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
-extern void cmd_exec(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
-extern void cmd_ps(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+extern int cmd_echo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+extern int cmd_exec(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+extern int cmd_ps(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
 
 #if CONFIG_NFILE_DESCRIPTORS > 0
-  extern void cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
-  extern void cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
-  extern void cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+  extern int cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+  extern int cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+  extern int cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
 # if CONFIG_NFILE_STREAMS > 0
-  extern void cmd_sh(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+  extern int cmd_sh(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
 # endif  /* CONFIG_NFILE_STREAMS */
 # ifndef CONFIG_DISABLE_MOUNTPOINT
-    extern void cmd_mkdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
-    extern void cmd_mkfifo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
-    extern void cmd_rm(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
-    extern void cmd_rmdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+    extern int cmd_mkdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+    extern int cmd_mkfifo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+    extern int cmd_rm(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+    extern int cmd_rmdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
 #   ifdef CONFIG_FS_FAT
-      extern void cmd_mkfatfs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
-      extern void cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
-      extern void cmd_umount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+      extern int cmd_mkfatfs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+      extern int cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+      extern int cmd_umount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
 #   endif /* CONFIG_FS_FAT */
 # endif /* !CONFIG_DISABLE_MOUNTPOINT */
 #endif /* CONFIG_NFILE_DESCRIPTORS */
 
 #if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
-  extern void cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+  extern int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
 #endif
 
 #ifndef CONFIG_DISABLE_ENVIRON
-  extern void cmd_set(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
-  extern void cmd_unset(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+  extern int cmd_set(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+  extern int cmd_unset(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
 #endif /* CONFIG_DISABLE_ENVIRON */
 
 #ifndef CONFIG_DISABLE_SIGNALS
-  extern void cmd_sleep(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
-  extern void cmd_usleep(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+  extern int cmd_sleep(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+  extern int cmd_usleep(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
 #endif /* CONFIG_DISABLE_SIGNALS */
 
 #endif /* __NSH_H */
diff --git a/examples/nsh/nsh_envcmds.c b/examples/nsh/nsh_envcmds.c
index 86b7651e88728debc94142d6c46dc3c14415ecd5..7c8ece414b4654517a119d772dadddbbd7d98d6e 100644
--- a/examples/nsh/nsh_envcmds.c
+++ b/examples/nsh/nsh_envcmds.c
@@ -79,7 +79,7 @@
  * Name: cmd_echo
  ****************************************************************************/
 
-void cmd_echo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_echo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
   int i;
 
@@ -92,6 +92,7 @@ void cmd_echo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
       nsh_output(vtbl, "%s ", argv[i]);
     }
   nsh_output(vtbl, "\n");
+  return OK;
 }
 
 /****************************************************************************
@@ -99,12 +100,14 @@ void cmd_echo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
  ****************************************************************************/
 
 #ifndef CONFIG_DISABLE_ENVIRON
-void cmd_set(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_set(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
-  if (setenv(argv[1], argv[2], TRUE) < 0)
+  int ret = setenv(argv[1], argv[2], TRUE);
+  if (ret < 0)
     {
       nsh_output(vtbl, g_fmtcmdfailed, argv[0], "setenv", NSH_ERRNO);
     }
+  return ret;
 }
 #endif
 
@@ -113,11 +116,13 @@ void cmd_set(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
  ****************************************************************************/
 
 #ifndef CONFIG_DISABLE_ENVIRON
-void cmd_unset(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_unset(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
-  if (unsetenv(argv[1]) < 0)
+  int ret = unsetenv(argv[1]);
+  if (ret < 0)
     {
       nsh_output(vtbl, g_fmtcmdfailed, argv[0], "unsetenv", NSH_ERRNO);
     }
+  return ret;
 }
 #endif
diff --git a/examples/nsh/nsh_fscmds.c b/examples/nsh/nsh_fscmds.c
index 721a30cfe3a9c8d89c0e3707bafa4a623d207bcc..8ec2d7c252c7a1c3ae972f1dbcf214201c9e1c4d 100644
--- a/examples/nsh/nsh_fscmds.c
+++ b/examples/nsh/nsh_fscmds.c
@@ -237,7 +237,7 @@ static int ls_handler(FAR struct nsh_vtbl_s *vtbl, const char *dirpath, struct d
       if (ret != 0)
         {
           nsh_output(vtbl, g_fmtcmdfailed, "ls", "stat", NSH_ERRNO);
-          return OK;
+          return ERROR;
         }
 
       if ((lsflags & LSFLAGS_LONG) != 0)
@@ -337,6 +337,7 @@ static int ls_handler(FAR struct nsh_vtbl_s *vtbl, const char *dirpath, struct d
 #if CONFIG_NFILE_DESCRIPTORS > 0
 static int ls_recursive(FAR struct nsh_vtbl_s *vtbl, const char *dirpath, struct dirent *entryp, void *pvarg)
 {
+  int ret = OK;
   /* Is this entry a directory? */
 
   if (DIRENT_ISDIRECTORY(entryp->d_type))
@@ -349,14 +350,16 @@ static int ls_recursive(FAR struct nsh_vtbl_s *vtbl, const char *dirpath, struct
       /* List the directory contents */
 
       nsh_output(vtbl, "%s:\n", newpath);
-      foreach_direntry(vtbl, "ls", newpath, ls_handler, pvarg);
-
-      /* Then recurse to list each directory within the directory */
+      ret = foreach_direntry(vtbl, "ls", newpath, ls_handler, pvarg);
+      if (ret == 0)
+        {
+          /* Then recurse to list each directory within the directory */
 
-      foreach_direntry(vtbl, "ls", newpath, ls_recursive, pvarg);
-      free(newpath);
+          ret = foreach_direntry(vtbl, "ls", newpath, ls_recursive, pvarg);
+          free(newpath);
+        }
     }
-  return OK;
+  return ret;
 }
 #endif
 
@@ -369,9 +372,10 @@ static int ls_recursive(FAR struct nsh_vtbl_s *vtbl, const char *dirpath, struct
  ****************************************************************************/
 
 #if CONFIG_NFILE_DESCRIPTORS > 0
-void cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
   char buffer[IOBUFFERSIZE];
+  int ret = ERROR;
 
   /* Open the file for reading */
 
@@ -379,7 +383,7 @@ void cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
   if (fd < 0)
     {
       nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
-      return;
+      return ERROR;
     }
 
   /* And just dump it byte for byte into stdout */
@@ -431,11 +435,13 @@ void cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 
       else
         {
+          ret = OK;
           break;
         }
     }
 
   (void)close(fd);
+  return ret;
 }
 #endif
 
@@ -444,7 +450,7 @@ void cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
  ****************************************************************************/
 
 #if CONFIG_NFILE_DESCRIPTORS > 0
-void cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
   struct stat buf;
   char *fullpath = NULL;
@@ -452,7 +458,7 @@ void cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
   int oflags = O_WRONLY|O_CREAT|O_TRUNC;
   int rdfd;
   int wrfd;
-  int ret;
+  int ret = ERROR;
 
   /* Open the source file for reading */
 
@@ -460,7 +466,7 @@ void cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
   if (rdfd < 0)
     {
       nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
-      return;
+      return ERROR;
     }
 
   /* Check if the destination is a directory */
@@ -519,6 +525,7 @@ void cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
             {
               /* End of file */
 
+              ret = OK;
               goto out_with_wrfd;
             }
           else if (nbytesread < 0 && errno != EINTR)
@@ -560,6 +567,7 @@ out_with_fullpath:
 
 out_with_rdfd:
   close(rdfd);
+  return ret;
 }
 #endif
 
@@ -568,7 +576,7 @@ out_with_rdfd:
  ****************************************************************************/
 
 #if CONFIG_NFILE_DESCRIPTORS > 0
-void cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
   unsigned int lsflags = 0;
   int ret;
@@ -595,7 +603,7 @@ void cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
           case '?':
           default:
             nsh_output(vtbl, g_fmtarginvalid, argv[0]);
-            return;
+            return ERROR;
         }
     }
 
@@ -604,12 +612,12 @@ void cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
   if (optind + 1 <  argc)
     {
       nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
-      return;
+      return ERROR;
     }
   else if (optind + 1 >  argc)
     {
       nsh_output(vtbl, g_fmtargrequired, argv[0]);
-      return;
+      return ERROR;
     }
 
   /* List the directory contents */
@@ -622,6 +630,7 @@ void cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 
       ret = foreach_direntry(vtbl, "ls", argv[optind], ls_recursive, (void*)lsflags);
     }
+  return ret;
 }
 #endif
 
@@ -630,13 +639,14 @@ void cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
  ****************************************************************************/
 
 #if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
-void cmd_mkdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_mkdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
-  int result = mkdir(argv[1], 0777);
-  if ( result < 0)
+  int ret = mkdir(argv[1], 0777);
+  if (ret < 0)
     {
       nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mkdir", NSH_ERRNO);
     }
+  return ret;
 }
 #endif
 
@@ -645,14 +655,15 @@ void cmd_mkdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
  ****************************************************************************/
 
 #if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_FAT)
-void cmd_mkfatfs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_mkfatfs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
   struct fat_format_s fmt = FAT_FORMAT_INITIALIZER;
-  int result = mkfatfs(argv[1], &fmt);
-  if ( result < 0)
+  int ret = mkfatfs(argv[1], &fmt);
+  if (ret < 0)
     {
       nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mkfatfs", NSH_ERRNO);
     }
+  return ret;
 }
 #endif
 
@@ -661,13 +672,14 @@ void cmd_mkfatfs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
  ****************************************************************************/
 
 #if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
-void cmd_mkfifo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_mkfifo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
-  int result = mkfifo(argv[1], 0777);
-  if ( result < 0)
+  int ret = mkfifo(argv[1], 0777);
+  if (ret < 0)
     {
       nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mkfifo", NSH_ERRNO);
     }
+  return ret;
 }
 #endif
 
@@ -677,7 +689,7 @@ void cmd_mkfifo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 
 #if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
 #ifdef CONFIG_FS_FAT /* Need at least one filesytem in configuration */
-void cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
   char *filesystem = 0;
   int result;
@@ -695,12 +707,12 @@ void cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 
           case ':':
             nsh_output(vtbl, g_fmtargrequired, argv[0]);
-            return;
+            return ERROR;
 
           case '?':
           default:
             nsh_output(vtbl, g_fmtarginvalid, argv[0]);
-            return;
+            return ERROR;
         }
     }
 
@@ -709,12 +721,12 @@ void cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
   if (optind + 2 <  argc)
     {
       nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
-      return;
+      return ERROR;
     }
   else if (optind + 2 >  argc)
     {
       nsh_output(vtbl, g_fmtargrequired, argv[0]);
-      return;
+      return ERROR;
     }
 
   /* Perform the mount */
@@ -723,6 +735,7 @@ void cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
     {
       nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mount", NSH_ERRNO);
     }
+  return result;
 }
 #endif
 #endif
@@ -732,12 +745,14 @@ void cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
  ****************************************************************************/
 
 #if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
-void cmd_rm(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_rm(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
-  if (unlink(argv[1]) < 0)
+  int ret = unlink(argv[1]);
+  if (ret < 0)
     {
       nsh_output(vtbl, g_fmtcmdfailed, argv[0], "unlink", NSH_ERRNO);
     }
+  return ret;
 }
 #endif
 
@@ -746,12 +761,14 @@ void cmd_rm(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
  ****************************************************************************/
 
 #if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
-void cmd_rmdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_rmdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
-  if (rmdir(argv[1]) < 0)
+  int ret = rmdir(argv[1]);
+  if (ret < 0)
     {
       nsh_output(vtbl, g_fmtcmdfailed, argv[0], "rmdir", NSH_ERRNO);
     }
+  return ret;
 }
 #endif
 
@@ -760,7 +777,7 @@ void cmd_rmdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
  ****************************************************************************/
 
 #if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0
-void cmd_sh(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_sh(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
   FILE *stream;
   char *buffer;
@@ -775,7 +792,7 @@ void cmd_sh(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
       if (!stream)
         {
           nsh_output(vtbl, g_fmtcmdfailed, argv[0], "fopen", NSH_ERRNO);
-          return;
+          return ERROR;
         }
 
       do
@@ -797,6 +814,7 @@ void cmd_sh(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
       while(pret);
       fclose(stream);
     }
+  return OK;
 }
 #endif
 
@@ -806,14 +824,15 @@ void cmd_sh(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 
 #if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
 #ifdef CONFIG_FS_FAT /* Need at least one filesytem in configuration */
-void cmd_umount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_umount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
   /* Perform the umount */
   int result = umount(argv[1]);
-  if ( result < 0)
+  if (result < 0)
     {
       nsh_output(vtbl, g_fmtcmdfailed, argv[0], "umount", NSH_ERRNO);
     }
+  return result;
 }
 #endif
 #endif
diff --git a/examples/nsh/nsh_main.c b/examples/nsh/nsh_main.c
index 32c4a94a66fa8952f037da73a24b0b205075cf8b..c9622a90b4cb2d2cd59c4d3e4b8cebf1188e977d 100644
--- a/examples/nsh/nsh_main.c
+++ b/examples/nsh/nsh_main.c
@@ -72,9 +72,9 @@ struct cmdmap_s
  * Private Function Prototypes
  ****************************************************************************/
 
-static void cmd_help(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
-static void cmd_exit(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
-static void cmd_unrecognized(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+static int cmd_help(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+static int cmd_exit(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+static int cmd_unrecognized(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
 
 /****************************************************************************
  * Private Data
@@ -83,6 +83,9 @@ static void cmd_unrecognized(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 static const char g_delim[]      = " \t\n";
 static const char g_redirect1[]  = ">";
 static const char g_redirect2[]  = ">>";
+static const char g_exitstatus[] = "$?";
+static const char g_success[]    = "0";
+static const char g_failure[]    = "1";
 
 static const struct cmdmap_s g_cmdmap[] =
 {
@@ -153,6 +156,7 @@ const char g_fmtcmdnotfound[]    = "nsh: %s: command not found\n";
 const char g_fmtcmdnotimpl[]     = "nsh: %s: command not implemented\n";
 const char g_fmtnosuch[]         = "nsh: %s: no such %s: %s\n";
 const char g_fmttoomanyargs[]    = "nsh: %s: too many arguments\n";
+const char g_fmtcontext[]        = "nsh: %s: not valid in this context\n";
 #ifdef CONFIG_EXAMPLES_NSH_STRERROR
 const char g_fmtcmdfailed[]      = "nsh: %s: %s failed: %s\n";
 #else
@@ -168,12 +172,19 @@ const char g_fmtcmdoutofmemory[] = "nsh: %s: out of memory\n";
  * Name: cmd_help
  ****************************************************************************/
 
-static void cmd_help(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+static int cmd_help(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
   const struct cmdmap_s *ptr;
 
-  nsh_output(vtbl, "NSH command form:\n");
+  nsh_output(vtbl, "NSH command forms:\n");
   nsh_output(vtbl, "  [nice [-d <niceness>>]] <cmd> [[> <file>|>> <file>] &]\n");
+  nsh_output(vtbl, "OR\n");
+  nsh_output(vtbl, "  if <cmd>\n");
+  nsh_output(vtbl, "  then\n");
+  nsh_output(vtbl, "    [sequence of <cmd>]\n");
+  nsh_output(vtbl, "  else\n");
+  nsh_output(vtbl, "    [sequence of <cmd>]\n");
+  nsh_output(vtbl, "  fi\n");
   nsh_output(vtbl, "Where <cmd> is one of:\n");
   for (ptr = g_cmdmap; ptr->cmd; ptr++)
     {
@@ -186,24 +197,27 @@ static void cmd_help(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
           nsh_output(vtbl, "  %s\n", ptr->cmd);
         }
     }
+  return OK;
 }
 
 /****************************************************************************
  * Name: cmd_unrecognized
  ****************************************************************************/
 
-static void cmd_unrecognized(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+static int cmd_unrecognized(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
   nsh_output(vtbl, g_fmtcmdnotfound, argv[0]);
+  return ERROR;
 }
 
 /****************************************************************************
  * Name: cmd_exit
  ****************************************************************************/
 
-static void cmd_exit(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+static int cmd_exit(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
   nsh_exit(vtbl);
+  return OK;
 }
 
 /****************************************************************************
@@ -216,6 +230,7 @@ static int nsh_execute(int argc, char *argv[])
    const char            *cmd;
    struct nsh_vtbl_s     *vtbl;
    cmd_t                  handler = cmd_unrecognized;
+   int                    ret;
 
    /* Parse all of the arguments following the command name.  The form
     * of argv is:
@@ -273,16 +288,16 @@ static int nsh_execute(int argc, char *argv[])
          }
      }
 
-   handler(vtbl, argc, &argv[2]);
+   ret = handler(vtbl, argc, &argv[2]);
    nsh_release(vtbl);
-   return OK;
+   return ret;
 }
 
 /****************************************************************************
  * Name: nsh_argument
  ****************************************************************************/
 
-char *nsh_argument(char **saveptr)
+char *nsh_argument(FAR struct nsh_vtbl_s *vtbl, char **saveptr)
 {
   char *pbegin = *saveptr;
   char *pend   = NULL;
@@ -315,12 +330,12 @@ char *nsh_argument(char **saveptr)
       if (*(pbegin + 1) == '>')
         {
           *saveptr = pbegin + 2;
-	  pbegin = g_redirect2;
+	  pbegin = (char*)g_redirect2;
         }
       else
         {
           *saveptr = pbegin + 1;
-	  pbegin = g_redirect1;
+	  pbegin = (char*)g_redirect1;
         }
     }
   else
@@ -368,28 +383,227 @@ char *nsh_argument(char **saveptr)
 
   /* Check for references to environment variables */
 
-#ifndef CONFIG_DISABLE_ENVIRON
   if (pbegin[0] == '$' && !quoted)
     {
-      /* Yes.. return the value of the environment variable with this name */
+      /* Check for built-in variables */
 
-      char *value = getenv(pbegin+1);
-      if (value)
+      if (strcmp(pbegin, g_exitstatus) == 0)
         {
-          return value;
+          if (vtbl->np.np_fail)
+            {
+              return (char*)g_failure;
+            }
+          else
+            {
+              return (char*)g_success;
+            }
         }
+
+      /* Not a built-in? Return the value of the environment variable with this name */
+#ifndef CONFIG_DISABLE_ENVIRON
       else
         {
-          return "";
+          char *value = getenv(pbegin+1);
+          if (value)
+            {
+              return value;
+            }
+          else
+            {
+              return (char*)"";
+            }
         }
-    }
 #endif
+    }
 
   /* Return the beginning of the token. */
 
   return pbegin;
 }
 
+/****************************************************************************
+ * Name: nsh_ifthenelse
+ ****************************************************************************/
+
+static inline int nsh_ifthenelse(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd, FAR char **saveptr)
+{
+  FAR char *cmd = *ppcmd;
+  if (cmd)
+    {
+      /* Check if the command is preceeded by "if" */
+
+      if (strcmp(cmd, "if") == 0)
+        {
+          /* Get the cmd following the if */
+
+          *ppcmd = nsh_argument(vtbl, saveptr);
+          if (!*ppcmd)
+            {
+              nsh_output(vtbl, g_fmtarginvalid, "if");
+              return ERROR;
+            }
+
+          /* Verify that "if" is valid in this context */
+
+          if (vtbl->np.np_state != NSH_PARSER_NORMAL)
+            {
+              nsh_output(vtbl, g_fmtcontext, "if");
+              return ERROR;
+            }
+          vtbl->np.np_state = NSH_PARSER_IF;
+        }
+      else if (strcmp(cmd, "then") == 0)
+        {
+          /* Get the cmd following the then -- there shouldn't be one */
+
+          *ppcmd = nsh_argument(vtbl, saveptr);
+          if (*ppcmd)
+            {
+              nsh_output(vtbl, g_fmtarginvalid, "then");
+              return ERROR;
+            }
+
+          /* Verify that "then" is valid in this context */
+
+          if (vtbl->np.np_state != NSH_PARSER_IF)
+            {
+              nsh_output(vtbl, g_fmtcontext, "then");
+              return ERROR;
+            }
+          vtbl->np.np_state = NSH_PARSER_THEN;
+        }
+      else if (strcmp(cmd, "else") == 0)
+        {
+          /* Get the cmd following the else -- there shouldn't be one */
+
+          *ppcmd = nsh_argument(vtbl, saveptr);
+          if (*ppcmd)
+            {
+              nsh_output(vtbl, g_fmtarginvalid, "else");
+              return ERROR;
+            }
+
+          /* Verify that "then" is valid in this context */
+
+          if (vtbl->np.np_state != NSH_PARSER_THEN)
+            {
+              nsh_output(vtbl, g_fmtcontext, "else");
+              return ERROR;
+            }
+          vtbl->np.np_state = NSH_PARSER_ELSE;
+        }
+      else if (strcmp(cmd, "fi") == 0)
+        {
+          /* Get the cmd following the fi -- there should be one */
+
+          *ppcmd = nsh_argument(vtbl, saveptr);
+          if (*ppcmd)
+            {
+              nsh_output(vtbl, g_fmtarginvalid, "fi");
+              return ERROR;
+            }
+
+          /* Verify that "fi" is valid in this context */
+
+          if (vtbl->np.np_state != NSH_PARSER_THEN && vtbl->np.np_state != NSH_PARSER_ELSE)
+            {
+              nsh_output(vtbl, g_fmtcontext, "fi");
+              return ERROR;
+            }
+          vtbl->np.np_state = NSH_PARSER_NORMAL;
+        }
+      else if (vtbl->np.np_state == NSH_PARSER_IF)
+        {
+          nsh_output(vtbl, g_fmtcontext, cmd);
+          return ERROR;
+        }
+    }
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nsh_cmdenabled
+ ****************************************************************************/
+
+static inline boolean nsh_cmdenabled(FAR struct nsh_vtbl_s *vtbl)
+{
+  switch (vtbl->np.np_state)
+    {
+      case NSH_PARSER_NORMAL :
+      case NSH_PARSER_IF:
+      default:
+        break;
+
+      case NSH_PARSER_THEN:
+        return !vtbl->np.np_ifcond;
+
+      case NSH_PARSER_ELSE:
+        return vtbl->np.np_ifcond;
+    }
+  return TRUE;
+}
+
+/****************************************************************************
+ * Name: nsh_saveresult
+ ****************************************************************************/
+
+static inline void nsh_saveresult(FAR struct nsh_vtbl_s *vtbl, boolean result)
+{
+  vtbl->np.np_fail = result;
+  if (vtbl->np.np_state == NSH_PARSER_IF)
+    {
+      vtbl->np.np_ifcond = result;
+    }
+}
+
+/****************************************************************************
+ * Name: nsh_nice
+ ****************************************************************************/
+
+static inline int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd, FAR char **saveptr)
+{
+  FAR char *cmd = *ppcmd;
+ 
+  vtbl->np.np_nice = 0;
+  if (cmd)
+    {
+      /* Check if the command is preceded by "nice" */
+
+      if (strcmp(cmd, "nice") == 0)
+        {
+          /* Nicenesses range from -20 (most favorable scheduling) to 19
+           * (least  favorable).  Default is 10.
+           */
+
+          vtbl->np.np_nice = 10;
+
+          /* Get the cmd (or -d option of nice command) */
+
+          cmd = nsh_argument(vtbl, saveptr);
+          if (cmd && strcmp(cmd, "-d") == 0)
+            {
+              FAR char *val = nsh_argument(vtbl, saveptr);
+              if (val)
+                {
+                  char *endptr;
+                  vtbl->np.np_nice = (int)strtol(val, &endptr, 0);
+                  if (vtbl->np.np_nice > 19 || vtbl->np.np_nice < -20 || endptr == val || *endptr != '\0')
+                    {
+                      nsh_output(vtbl, g_fmtarginvalid, "nice");
+                      return ERROR;
+                    }
+                  cmd = nsh_argument(vtbl, saveptr);
+                }
+            }
+
+          /* Return the real command name */
+
+          *ppcmd = cmd;
+        }
+    }
+  return OK;
+}
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -464,58 +678,48 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
   FAR char *saveptr;
   FAR char *cmd;
   FAR char *redirfile;
-  boolean   bg = FALSE;
-  boolean   redirect = FALSE;
   int       fd = -1;
-  int       nice = 0;
   int       oflags;
   int       argc;
   int       ret;
 
+  /* Initialize parser state */
+
   memset(argv, 0, (NSH_MAX_ARGUMENTS+4)*sizeof(char*));
+  vtbl->np.np_bg       = FALSE;
+  vtbl->np.np_redirect = FALSE;
 
   /* Parse out the command at the beginning of the line */
 
   saveptr = cmdline;
-  cmd = nsh_argument(&saveptr);
-  if (cmd)
-    {
-      /* Check if the command is preceded by "nice" */
+  cmd = nsh_argument(vtbl, &saveptr);
 
-      if (strcmp(cmd, "nice") == 0)
-        {
-          /* Nicenesses range from -20 (most favorable scheduling) to 19
-           * (least  favorable).  Default is 10.
-           */
+  /* Handler if-then-else-fi */
 
-          nice = 10;
+  if (nsh_ifthenelse(vtbl, &cmd, &saveptr) != 0)
+    {
+      goto errout;
+    }
 
-          /* Get the cmd (or -d option of nice command) */
+  /* Handle nice */
 
-          cmd = nsh_argument(&saveptr);
-          if (cmd && strcmp(cmd, "-d") == 0)
-            {
-              FAR char *val = nsh_argument(&saveptr);
-              if (val)
-                {
-                  char *endptr;
-                  nice = (int)strtol(val, &endptr, 0);
-                  if (nice > 19 || nice < -20 || endptr == val || *endptr != '\0')
-                    {
-                      nsh_output(vtbl, g_fmtarginvalid, "nice");
-                      return ERROR;
-                    }
-                  cmd = nsh_argument(&saveptr);
-                }
-            }
-        }
+  if (nsh_nice(vtbl, &cmd, &saveptr) != 0)
+    {
+      goto errout;
     }
 
-  /* Check if any command was provided */
+  /* Check if any command was provided -OR- if command processing is
+   * currently disabled.
+   */
 
-  if (!cmd)
+  if (!cmd || !nsh_cmdenabled(vtbl))
     {
-      return OK; /* Newline only is not an error */
+      /* An empty line is not an error and an unprocessed command cannot
+       * generate an error, but neither should they change the last
+       * command status.
+       */
+
+      return OK;
     }
 
   /* Parse all of the arguments following the command name.  The form
@@ -543,7 +747,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
   argv[2] = cmd;
   for (argc = 3; argc < NSH_MAX_ARGUMENTS+6; argc++)
     {
-      argv[argc] = nsh_argument(&saveptr);
+      argv[argc] = nsh_argument(vtbl, &saveptr);
       if (!argv[argc])
         {
           break;
@@ -555,7 +759,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
 
   if (argc > 3 && strcmp(argv[argc-1], "&") == 0)
     {
-      bg = TRUE;
+      vtbl->np.np_bg = TRUE;
       argv[argc-1] = NULL;
       argc--;
     }
@@ -568,26 +772,26 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
 
       if (strcmp(argv[argc-2], g_redirect1) == 0)
         {
-          redirect  = TRUE;
-          oflags    = O_WRONLY|O_CREAT|O_TRUNC;
-          redirfile = argv[argc-1];
-          argc     -= 2;
+          vtbl->np.np_redirect = TRUE;
+          oflags               = O_WRONLY|O_CREAT|O_TRUNC;
+          redirfile            = argv[argc-1];
+          argc                -= 2;
         }
 
       /* Check for redirection by appending to an existing file */
 
       else if (strcmp(argv[argc-2], g_redirect2) == 0)
         {
-          redirect  = TRUE;
-          oflags    = O_WRONLY|O_CREAT|O_APPEND;
-          redirfile = argv[argc-1];
-          argc     -= 2;
+          vtbl->np.np_redirect = TRUE;
+          oflags               = O_WRONLY|O_CREAT|O_APPEND;
+          redirfile            = argv[argc-1];
+          argc                -= 2;
         }
     }
 
   /* Redirected output? */
 
-  if (redirect)
+  if (vtbl->np.np_redirect)
     {
       /* Open the redirection file.  This file will eventually
        * be closed by a call to either nsh_release (if the command
@@ -599,7 +803,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
       if (fd < 0)
         {
           nsh_output(vtbl, g_fmtcmdfailed, cmd, "open", NSH_ERRNO);
-          return ERROR;
+          goto errout;
         }
     }
 
@@ -612,7 +816,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
 
   /* Handle the case where the command is executed in background */
 
-  if (bg)
+  if (vtbl->np.np_bg)
     {
       struct sched_param param;
       int priority;
@@ -632,7 +836,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
 
       /* Handle redirection of output via a file descriptor */
 
-      if (redirect)
+      if (vtbl->np.np_redirect)
         {
           (void)nsh_redirect(bkgvtbl, fd, NULL);
         }
@@ -643,16 +847,16 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
       if (ret != 0)
         {
           nsh_output(vtbl, g_fmtcmdfailed, cmd, "sched_getparm", NSH_ERRNO);
-          goto errout;
+          goto errout_with_redirect;
         }
 
       /* Determine the priority to execute the command */
 
       priority = param.sched_priority;
-      if (nice != 0)
+      if (vtbl->np.np_nice != 0)
         {
-          priority -= nice;
-          if (nice < 0)
+          priority -= vtbl->np.np_nice;
+          if (vtbl->np.np_nice < 0)
             {
               int max_priority = sched_get_priority_max(SCHED_RR);
               if (priority > max_priority)
@@ -674,14 +878,14 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
 
 #ifndef CONFIG_CUSTOM_STACK
       ret = task_create("nsh_execute", priority, CONFIG_EXAMPLES_NSH_STACKSIZE,
-                        nsh_execute, &argv[1]);
+                        (main_t)nsh_execute, &argv[1]);
 #else
-      ret = task_create("nsh_execute", priority, nsh_execute, &argv[1]);
+      ret = task_create("nsh_execute", priority, (main_t)nsh_execute, &argv[1]);
 #endif
       if (ret < 0)
         {
           nsh_output(vtbl, g_fmtcmdfailed, cmd, "task_create", NSH_ERRNO);
-          goto errout;
+          goto errout_with_redirect;
         }
       nsh_output(vtbl, "%s [%d:%d:%d]\n", cmd, ret, priority, param.sched_priority);
 
@@ -690,7 +894,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
        * the file descriptor
        */
 
-      if (redirect)
+      if (vtbl->np.np_redirect)
         {
           (void)close(fd);
         }
@@ -713,7 +917,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
 
       /* Handle redirection of output via a file descriptor */
 
-      if (redirect)
+      if (vtbl->np.np_redirect)
         {
           nsh_redirect(vtbl, fd, save);
         }
@@ -728,14 +932,14 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
        * file descriptor.
        */
 
-      if (redirect)
+      if (vtbl->np.np_redirect)
         {
           nsh_undirect(vtbl, save);
         }
 
       if (ret < 0)
         {
-          return ERROR;
+          goto errout;
         }
     }
 
@@ -743,12 +947,15 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
    * command task succeeded).
    */
 
+  nsh_saveresult(vtbl, FALSE);
   return OK;
 
-errout:
-  if (redirect)
+errout_with_redirect:
+  if (vtbl->np.np_redirect)
     {
       close(fd);
     }
+errout:
+  nsh_saveresult(vtbl, TRUE);
   return ERROR;
 }
diff --git a/examples/nsh/nsh_netcmds.c b/examples/nsh/nsh_netcmds.c
index ee21ae154d735ea4cf4a39c9cdf5d80006b83067..df4197c874ed683796b28ce8d2b5bd3c1e16dfac 100644
--- a/examples/nsh/nsh_netcmds.c
+++ b/examples/nsh/nsh_netcmds.c
@@ -221,10 +221,11 @@ int ifconfig_callback(FAR struct uip_driver_s *dev, void *arg)
  * Name: cmd_ifconfig
  ****************************************************************************/
 
-void cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
   netdev_foreach(ifconfig_callback, vtbl);
   uip_statistics(vtbl);
+  return OK;
 }
 
 #endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS */
diff --git a/examples/nsh/nsh_proccmds.c b/examples/nsh/nsh_proccmds.c
index 3df84c62b93bdab2efa5e7f7907d580ab8840d7f..643e420fbea5725cf89c58a3001ce554ef054231 100644
--- a/examples/nsh/nsh_proccmds.c
+++ b/examples/nsh/nsh_proccmds.c
@@ -139,7 +139,7 @@ static void ps_task(FAR _TCB *tcb, FAR void *arg)
  * Name: cmd_exec
  ****************************************************************************/
 
-void cmd_exec(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_exec(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
   char *endptr;
   long addr;
@@ -148,21 +148,23 @@ void cmd_exec(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
   if (!addr || endptr == argv[1] || *endptr != '\0')
     {
        nsh_output(vtbl, g_fmtarginvalid, argv[0]);
-       return;
+       return ERROR;
     }
 
   nsh_output(vtbl, "Calling %p\n", (exec_t)addr);
   ((exec_t)addr)();
+  return OK;
 }
 
 /****************************************************************************
  * Name: cmd_ps
  ****************************************************************************/
 
-void cmd_ps(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_ps(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
   nsh_output(vtbl, "PID   PRI SCHD TYPE   NP STATE    NAME\n");
   sched_foreach(ps_task, vtbl);
+  return OK;
 }
 
 /****************************************************************************
@@ -170,7 +172,7 @@ void cmd_ps(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
  ****************************************************************************/
 
 #ifndef CONFIG_DISABLE_SIGNALS
-void cmd_sleep(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_sleep(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
   char *endptr;
   long secs;
@@ -179,9 +181,10 @@ void cmd_sleep(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
   if (!secs || endptr == argv[1] || *endptr != '\0')
     {
        nsh_output(vtbl, g_fmtarginvalid, argv[0]);
-       return;
+       return ERROR;
     }
   sleep(secs);
+  return OK;
 }
 #endif
 
@@ -190,7 +193,7 @@ void cmd_sleep(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
  ****************************************************************************/
 
 #ifndef CONFIG_DISABLE_SIGNALS
-void cmd_usleep(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+int cmd_usleep(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
   char *endptr;
   long usecs;
@@ -199,8 +202,9 @@ void cmd_usleep(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
   if (!usecs || endptr == argv[1] || *endptr != '\0')
     {
        nsh_output(vtbl, g_fmtarginvalid, argv[0]);
-       return;
+       return ERROR;
     }
   usleep(usecs);
+  return OK;
 }
 #endif
diff --git a/examples/nsh/nsh_serial.c b/examples/nsh/nsh_serial.c
index 95953171c9e3dc7fc8f34ab4f74ddc90e136108f..e138cf6c1e92bc68f7030b0c8084934a1aa3e481 100644
--- a/examples/nsh/nsh_serial.c
+++ b/examples/nsh/nsh_serial.c
@@ -114,6 +114,8 @@ static inline FAR struct serial_s *nsh_allocstruct(void)
       pstate->ss_vtbl.undirect   = nsh_consoleundirect;
       pstate->ss_vtbl.exit       = nsh_consoleexit;
 
+      memset(&pstate->ss_vtbl.np, 0, sizeof(struct nsh_parser_s));
+
       pstate->ss_refs            = 1;
       pstate->ss_fd              = 1;
       pstate->ss_stream          = stdout;
diff --git a/examples/nsh/nsh_telnetd.c b/examples/nsh/nsh_telnetd.c
index 0e99dd36a04f2c579e45b45eb2062828dfaefee9..a2729347279695fc41c7c1a5500b8163b508da37 100644
--- a/examples/nsh/nsh_telnetd.c
+++ b/examples/nsh/nsh_telnetd.c
@@ -209,6 +209,8 @@ static FAR struct telnetd_s *nsh_allocstruct(void)
       pstate->tn_vtbl.undirect   = nsh_telnetundirect;
       pstate->tn_vtbl.exit       = nsh_telnetexit;
 
+      memset(&pstate->tn_vtbl.np, 0, sizeof(struct nsh_parser_s));
+
       pstate->tn_refs            = 1;
     }
   return pstate;