summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2008-03-05 02:49:35 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2008-03-05 02:49:35 +0000
commita3ddb08bec11871f6e83bb7aaa53a17a4ea5309c (patch)
tree7a77642c272052b03260156dc5062d23f16e3a35 /cpukit
parentNew. (diff)
downloadrtems-a3ddb08bec11871f6e83bb7aaa53a17a4ea5309c.tar.bz2
2008-03-04 Joel Sherrill <joel.sherrill@oarcorp.com>
* libmisc/Makefile.am, libmisc/shell/main_cp.c, libmisc/shell/main_cpuuse.c, libmisc/shell/main_date.c, libmisc/shell/main_mallocinfo.c, libmisc/shell/main_netstats.c, libmisc/shell/main_perioduse.c, libmisc/shell/main_stackuse.c, libmisc/shell/main_wkspaceinfo.c, libmisc/shell/print_heapinfo.c, libmisc/shell/shell.c, libmisc/shell/shell.h, libmisc/shell/shell_makeargs.c, libmisc/shell/shellconfig.c, libmisc/shell/shellconfig.h, libmisc/shell/write_file.c: Add initial capability to automatically execute a script from the filesystem. Add echo command from NetBSD and sleep command. * libmisc/shell/main_echo.c, libmisc/shell/main_sleep.c, libmisc/shell/shell_script.c: New files.
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/ChangeLog15
-rw-r--r--cpukit/libmisc/Makefile.am13
-rw-r--r--cpukit/libmisc/shell/main_cp.c12
-rw-r--r--cpukit/libmisc/shell/main_cpuuse.c2
-rw-r--r--cpukit/libmisc/shell/main_date.c4
-rw-r--r--cpukit/libmisc/shell/main_echo.c142
-rw-r--r--cpukit/libmisc/shell/main_mallocinfo.c2
-rw-r--r--cpukit/libmisc/shell/main_netstats.c76
-rw-r--r--cpukit/libmisc/shell/main_perioduse.c2
-rw-r--r--cpukit/libmisc/shell/main_sleep.c57
-rw-r--r--cpukit/libmisc/shell/main_stackuse.c2
-rw-r--r--cpukit/libmisc/shell/main_wkspaceinfo.c2
-rw-r--r--cpukit/libmisc/shell/print_heapinfo.c2
-rw-r--r--cpukit/libmisc/shell/shell.c18
-rw-r--r--cpukit/libmisc/shell/shell.h24
-rw-r--r--cpukit/libmisc/shell/shell_makeargs.c2
-rw-r--r--cpukit/libmisc/shell/shell_script.c327
-rw-r--r--cpukit/libmisc/shell/shellconfig.c3
-rw-r--r--cpukit/libmisc/shell/shellconfig.h18
-rw-r--r--cpukit/libmisc/shell/write_file.c8
20 files changed, 683 insertions, 48 deletions
diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog
index fc2f77746b..4f10e55932 100644
--- a/cpukit/ChangeLog
+++ b/cpukit/ChangeLog
@@ -1,3 +1,18 @@
+2008-03-04 Joel Sherrill <joel.sherrill@oarcorp.com>
+
+ * libmisc/Makefile.am, libmisc/shell/main_cp.c,
+ libmisc/shell/main_cpuuse.c, libmisc/shell/main_date.c,
+ libmisc/shell/main_mallocinfo.c, libmisc/shell/main_netstats.c,
+ libmisc/shell/main_perioduse.c, libmisc/shell/main_stackuse.c,
+ libmisc/shell/main_wkspaceinfo.c, libmisc/shell/print_heapinfo.c,
+ libmisc/shell/shell.c, libmisc/shell/shell.h,
+ libmisc/shell/shell_makeargs.c, libmisc/shell/shellconfig.c,
+ libmisc/shell/shellconfig.h, libmisc/shell/write_file.c: Add initial
+ capability to automatically execute a script from the filesystem. Add
+ echo command from NetBSD and sleep command.
+ * libmisc/shell/main_echo.c, libmisc/shell/main_sleep.c,
+ libmisc/shell/shell_script.c: New files.
+
2008-02-28 Joel Sherrill <joel.sherrill@oarcorp.com>
* itron/include/rtems/itron/task.h, itron/src/cre_tsk.c,
diff --git a/cpukit/libmisc/Makefile.am b/cpukit/libmisc/Makefile.am
index 9428bc4f7a..6103e3c56d 100644
--- a/cpukit/libmisc/Makefile.am
+++ b/cpukit/libmisc/Makefile.am
@@ -68,20 +68,21 @@ libshell_a_SOURCES = shell/cat_file.c shell/cmds.c shell/internal.h \
shell/main_alias.c shell/main_cat.c shell/main_cd.c \
shell/main_chdir.c shell/main_chmod.c shell/main_chroot.c \
shell/main_cp.c shell/main_cpuuse.c shell/main_date.c shell/main_dir.c \
- shell/main_exit.c shell/main_help.c shell/main_id.c \
+ shell/main_echo.c shell/main_exit.c shell/main_help.c shell/main_id.c \
shell/main_logoff.c shell/main_ls.c shell/main_mallocinfo.c \
shell/main_mdump.c shell/main_medit.c shell/main_mfill.c \
shell/main_mkdir.c shell/main_mount.c $(shell_mount_fs) \
shell/main_mount_msdos.c shell/main_mmove.c shell/main_msdosfmt.c \
shell/main_mwdump.c shell/main_perioduse.c shell/main_pwd.c \
- shell/main_rm.c shell/main_rmdir.c shell/main_stackuse.c \
- shell/main_tty.c shell/main_umask.c shell/main_unmount.c \
- shell/main_blksync.c shell/main_whoami.c shell/shell.c \
- shell/shell_cmdset.c shell/shellconfig.c shell/shellconfig.h \
+ shell/main_rm.c shell/main_rmdir.c shell/main_sleep.c \
+ shell/main_stackuse.c shell/main_tty.c shell/main_umask.c \
+ shell/main_unmount.c shell/main_blksync.c shell/main_whoami.c \
+ shell/shell.c shell/shell_cmdset.c shell/shellconfig.c shell/shellconfig.h \
shell/shell.h shell/shell_makeargs.c shell/str2int.c shell/write_file.c \
shell/utils-cp.c shell/err.c shell/errx.c shell/verr.c shell/verrx.c \
shell/vwarn.c shell/vwarnx.c shell/warn.c shell/warnx.c \
- shell/fts.c shell/print_heapinfo.c shell/main_wkspaceinfo.c
+ shell/fts.c shell/print_heapinfo.c shell/main_wkspaceinfo.c \
+ shell/shell_script.c
if LIBNETWORKING
libshell_a_SOURCES += shell/main_mount_ftp.c shell/main_mount_tftp.c \
shell/main_ifconfig.c shell/main_route.c shell/main_netstats.c \
diff --git a/cpukit/libmisc/shell/main_cp.c b/cpukit/libmisc/shell/main_cp.c
index f7e7347b66..3812c3caac 100644
--- a/cpukit/libmisc/shell/main_cp.c
+++ b/cpukit/libmisc/shell/main_cp.c
@@ -522,10 +522,10 @@ mastercmp(const FTSENT **a, const FTSENT **b)
}
rtems_shell_cmd_t rtems_shell_CP_Command = {
- "cp", /* name */
- "cp [-R [-H | -L | -P]] [-f | -i] [-pv] src target # copy", /* usage */
- "files", /* topic */
- rtems_shell_main_cp, /* command */
- NULL, /* alias */
- NULL /* next */
+ "cp", /* name */
+ "cp [-R [-H | -L | -P]] [-f | -i] [-pv] src target", /* usage */
+ "files", /* topic */
+ rtems_shell_main_cp, /* command */
+ NULL, /* alias */
+ NULL /* next */
};
diff --git a/cpukit/libmisc/shell/main_cpuuse.c b/cpukit/libmisc/shell/main_cpuuse.c
index 492997cd8f..b2329934bd 100644
--- a/cpukit/libmisc/shell/main_cpuuse.c
+++ b/cpukit/libmisc/shell/main_cpuuse.c
@@ -1,7 +1,7 @@
/*
* CPUUSE Command Implementation
*
- * COPYRIGHT (c) 1989-2007.
+ * COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
diff --git a/cpukit/libmisc/shell/main_date.c b/cpukit/libmisc/shell/main_date.c
index 4d3f4fa94f..4ddbc118b8 100644
--- a/cpukit/libmisc/shell/main_date.c
+++ b/cpukit/libmisc/shell/main_date.c
@@ -1,10 +1,12 @@
/*
* DATE Shell Command Implmentation
*
- * Author: Fernando RUIZ CASAS
+ * OAuthor: Fernando RUIZ CASAS
* Work: fernando.ruiz@ctv.es
* Home: correo@fernando-ruiz.com
*
+ * Significantly rewritten by Joel Sherrill <joel.sherrill@oarcorp.com>.
+ *
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
diff --git a/cpukit/libmisc/shell/main_echo.c b/cpukit/libmisc/shell/main_echo.c
new file mode 100644
index 0000000000..8f868a2f29
--- /dev/null
+++ b/cpukit/libmisc/shell/main_echo.c
@@ -0,0 +1,142 @@
+/* $NetBSD: echo.c,v 1.12 2005/02/06 04:43:43 perry Exp $ */
+
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Kenneth Almquist.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)echo.c 8.1 (Berkeley) 5/31/93
+ */
+
+/*
+ * Echo command.
+ *
+ * echo is steeped in tradition - several of them!
+ * netbsd has supported 'echo [-n | -e] args' in spite of -e not being
+ * documented anywhere.
+ * Posix requires that -n be supported, output from strings containing
+ * \ is implementation defined
+ * The Single Unix Spec requires that \ escapes be treated as if -e
+ * were set, but that -n not be treated as an option.
+ * (ksh supports 'echo [-eEn] args', but not -- so that it is actually
+ * impossible to actually output '-n')
+ *
+ * It is suggested that 'printf "%b" "string"' be used to get \ sequences
+ * expanded. printf is now a builtin of netbsd's sh and csh.
+ */
+
+/*
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rtems.h>
+#include <rtems/shell.h>
+#include "internal.h"
+
+
+
+int rtems_shell_main_echo(
+ int argc,
+ char *argv[]
+)
+{
+ char **ap;
+ char *p;
+ char c;
+ int count;
+ int nflag = 0;
+ int eflag = 0;
+
+ ap = argv;
+ if (argc)
+ ap++;
+
+ if ((p = *ap) != NULL) {
+ if (!strcmp(p, "-n")) {
+ nflag = 1;
+ ap++;
+ } else if (!strcmp(p, "-e")) {
+ eflag = 1;
+ ap++;
+ }
+ }
+
+ while ((p = *ap++) != NULL) {
+ while ((c = *p++) != '\0') {
+ if (c == '\\' && eflag) {
+ switch (*p++) {
+ case 'a': c = '\a'; break; /* bell */
+ case 'b': c = '\b'; break;
+ case 'c': return 0; /* exit */
+ case 'e': c = 033; break; /* escape */
+ case 'f': c = '\f'; break;
+ case 'n': c = '\n'; break;
+ case 'r': c = '\r'; break;
+ case 't': c = '\t'; break;
+ case 'v': c = '\v'; break;
+ case '\\': break; /* c = '\\' */
+ case '0':
+ c = 0;
+ count = 3;
+ while (--count >= 0 && (unsigned)(*p - '0') < 8)
+ c = (c << 3) + (*p++ - '0');
+ break;
+ default:
+ /* Output the '/' and char following */
+ p--;
+ break;
+ }
+ }
+ putchar(c);
+ }
+ if (*ap)
+ putchar(' ');
+ }
+ if (! nflag)
+ putchar('\n');
+ return 0;
+}
+
+rtems_shell_cmd_t rtems_shell_ECHO_Command = {
+ "echo", /* name */
+ "echo [args]", /* usage */
+ "misc", /* topic */
+ rtems_shell_main_echo, /* command */
+ NULL, /* alias */
+ NULL /* next */
+};
diff --git a/cpukit/libmisc/shell/main_mallocinfo.c b/cpukit/libmisc/shell/main_mallocinfo.c
index 1f459270ee..109dbc3dd3 100644
--- a/cpukit/libmisc/shell/main_mallocinfo.c
+++ b/cpukit/libmisc/shell/main_mallocinfo.c
@@ -1,7 +1,7 @@
/*
* MALLOC_INFO Shell Command Implmentation
*
- * COPYRIGHT (c) 1989-2007.
+ * COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
diff --git a/cpukit/libmisc/shell/main_netstats.c b/cpukit/libmisc/shell/main_netstats.c
index 09dea65694..a86b7afa35 100644
--- a/cpukit/libmisc/shell/main_netstats.c
+++ b/cpukit/libmisc/shell/main_netstats.c
@@ -1,7 +1,7 @@
/*
* Network Statistics Shell Command Implmentation
*
- * COPYRIGHT (c) 1989-2007.
+ * COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -52,17 +52,21 @@ int rtems_shell_main_netstats( /* command */
int doICMPStats = 0;
int doUDPStats = 0;
int doTCPStats = 0;
+ int verbose = 0;
+ struct getopt_data getopt_reent;
- while ( (option = getopt( argc, argv, "Aimfpcutv")) != -1 ) {
- switch (option) {
- case 'A': doAll = 1; break;
- case 'i': doInetRoutes = 1; break;
- case 'm': doMBUFStats = 1; break;
- case 'f': doIFStats = 1; break;
- case 'p': doIPStats = 1; break;
- case 'c': doICMPStats = 1; break;
- case 'u': doUDPStats = 1; break;
- case 't': doTCPStats = 1; break;
+ while ( (option = getopt_r( argc, argv, "Aimfpcutv", &getopt_reent)) != -1 ) {
+
+ switch ((char)option) {
+ case 'A': doAll = 1; break;
+ case 'i': doInetRoutes = 1; break;
+ case 'm': doMBUFStats = 1; break;
+ case 'f': doIFStats = 1; break;
+ case 'p': doIPStats = 1; break;
+ case 'c': doICMPStats = 1; break;
+ case 'u': doUDPStats = 1; break;
+ case 't': doTCPStats = 1; break;
+ case 'v': verbose = 1; break;
case '?':
default:
netstats_usage();
@@ -70,21 +74,57 @@ int rtems_shell_main_netstats( /* command */
}
}
- if ( doInetRoutes == 1 || doAll == 1 )
+ if ( verbose ) {
+ printf(
+ "doAll=%d\n"
+ "doInetRoutes=%d\n"
+ "doMBUFStats=%d\n"
+ "doIFStats=%d\n"
+ "doIPStats=%d\n"
+ "doICMPStats=%d\n"
+ "doUDPStats=%d\n"
+ "doTCPStats=%d\n",
+ doAll,
+ doInetRoutes,
+ doMBUFStats,
+ doIFStats,
+ doIPStats,
+ doICMPStats,
+ doUDPStats,
+ doTCPStats
+ );
+ }
+
+#if 0
+ if ( doInetRoutes == 1 || doAll == 1 ) {
rtems_bsdnet_show_inet_routes();
- if ( doMBUFStats == 1 || doAll == 1 )
+ }
+
+ if ( doMBUFStats == 1 || doAll == 1 ) {
rtems_bsdnet_show_mbuf_stats();
- if ( doIFStats == 1 || doAll == 1 )
+ }
+
+ if ( doIFStats == 1 || doAll == 1 ) {
rtems_bsdnet_show_if_stats();
- if ( doIPStats == 1 || doAll == 1 )
+ }
+
+ if ( doIPStats == 1 || doAll == 1 ) {
rtems_bsdnet_show_ip_stats();
- if ( doICMPStats == 1 || doAll == 1 )
+ }
+
+ if ( doICMPStats == 1 || doAll == 1 ) {
rtems_bsdnet_show_icmp_stats();
- if ( doUDPStats == 1 || doAll == 1 )
+ }
+
+ if ( doUDPStats == 1 || doAll == 1 ) {
rtems_bsdnet_show_udp_stats();
- if ( doTCPStats == 1 || doAll == 1 )
+ }
+
+ if ( doTCPStats == 1 || doAll == 1 ) {
rtems_bsdnet_show_tcp_stats();
+ }
+#endif
return 0;
}
diff --git a/cpukit/libmisc/shell/main_perioduse.c b/cpukit/libmisc/shell/main_perioduse.c
index 9ad18d76de..d0f123af1c 100644
--- a/cpukit/libmisc/shell/main_perioduse.c
+++ b/cpukit/libmisc/shell/main_perioduse.c
@@ -1,7 +1,7 @@
/*
* perioduse Command Implementation
*
- * COPYRIGHT (c) 1989-2007.
+ * COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
diff --git a/cpukit/libmisc/shell/main_sleep.c b/cpukit/libmisc/shell/main_sleep.c
new file mode 100644
index 0000000000..6ee4cef614
--- /dev/null
+++ b/cpukit/libmisc/shell/main_sleep.c
@@ -0,0 +1,57 @@
+/*
+ * Sleep Shell Command Implmentation
+ *
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <time.h>
+
+#include <rtems.h>
+#include <rtems/shell.h>
+#include "internal.h"
+
+int rtems_shell_main_sleep(
+ int argc,
+ char *argv[]
+)
+{
+ struct timespec delay;
+
+ if (argc == 2) {
+ delay.tv_sec = rtems_shell_str2int(argv[1]);
+ delay.tv_nsec = 0;
+ nanosleep( &delay, NULL );
+ return 0;
+ }
+
+ if (argc == 3) {
+ delay.tv_sec = rtems_shell_str2int(argv[1]);
+ delay.tv_nsec = rtems_shell_str2int(argv[2]);
+ nanosleep( &delay, NULL );
+ return 0;
+ }
+
+ fprintf( stderr, "%s: Usage seconds [nanoseconds]\n", argv[0] );
+ return -1;
+}
+
+rtems_shell_cmd_t rtems_shell_SLEEP_Command = {
+ "sleep", /* name */
+ "sleep seconds [nanoseconds]", /* usage */
+ "misc", /* topic */
+ rtems_shell_main_sleep, /* command */
+ NULL, /* alias */
+ NULL /* next */
+};
diff --git a/cpukit/libmisc/shell/main_stackuse.c b/cpukit/libmisc/shell/main_stackuse.c
index 6c6c9251ae..3179f3670b 100644
--- a/cpukit/libmisc/shell/main_stackuse.c
+++ b/cpukit/libmisc/shell/main_stackuse.c
@@ -1,7 +1,7 @@
/*
* stackuse Command Implementation
*
- * COPYRIGHT (c) 1989-2007.
+ * COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
diff --git a/cpukit/libmisc/shell/main_wkspaceinfo.c b/cpukit/libmisc/shell/main_wkspaceinfo.c
index b5df7a4b42..41a3664330 100644
--- a/cpukit/libmisc/shell/main_wkspaceinfo.c
+++ b/cpukit/libmisc/shell/main_wkspaceinfo.c
@@ -1,7 +1,7 @@
/*
* MALLOC_INFO Shell Command Implmentation
*
- * COPYRIGHT (c) 1989-2007.
+ * COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
diff --git a/cpukit/libmisc/shell/print_heapinfo.c b/cpukit/libmisc/shell/print_heapinfo.c
index 9110c97a76..ad6db121d2 100644
--- a/cpukit/libmisc/shell/print_heapinfo.c
+++ b/cpukit/libmisc/shell/print_heapinfo.c
@@ -1,7 +1,7 @@
/*
* Print Heap Information Structure
*
- * COPYRIGHT (c) 1989-2007.
+ * COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
diff --git a/cpukit/libmisc/shell/shell.c b/cpukit/libmisc/shell/shell.c
index eca05f19e8..264742a246 100644
--- a/cpukit/libmisc/shell/shell.c
+++ b/cpukit/libmisc/shell/shell.c
@@ -208,7 +208,7 @@ int rtems_shell_login(FILE * in,FILE * out) {
fprintf(out,"RTEMS");
break;
case 'V':
- fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice);
+ fprintf(out,"%s\n%s",_RTEMS_version, _Copyright_Notice);
break;
case '@':
fprintf(out,"@");
@@ -371,6 +371,8 @@ rtems_boolean rtems_shell_main_loop(
rtems_boolean result = TRUE;
rtems_boolean input_file = FALSE;
int line = 0;
+ FILE *stdinToClose = NULL;
+ FILE *stdoutToClose = NULL;
rtems_shell_initialize_command_set();
@@ -397,8 +399,9 @@ rtems_boolean rtems_shell_main_loop(
fileno(stdout);
-fprintf( stderr,
- "-%s-%s-\n", shell_env->input, shell_env->output );
+ /* fprintf( stderr,
+ "-%s-%s-\n", shell_env->input, shell_env->output );
+ */
if (shell_env->output && strcmp(shell_env->output, "stdout") != 0) {
if (strcmp(shell_env->output, "stderr") == 0) {
@@ -414,6 +417,7 @@ fprintf( stderr,
return FALSE;
}
stdout = output;
+ stdoutToClose = output;
}
}
@@ -425,6 +429,7 @@ fprintf( stderr,
return FALSE;
}
stdin = input;
+ stdinToClose = input;
shell_env->forever = FALSE;
input_file = TRUE;
}
@@ -534,8 +539,7 @@ fprintf( stderr,
if ( argv[0] == NULL ) {
shell_env->errorlevel = -1;
} else if ( shell_cmd == NULL ) {
- fprintf(stdout, "shell:%s command not found\n", argv[0]);
- shell_env->errorlevel = -1;
+ shell_env->errorlevel = rtems_shell_script_file( argc, argv );
} else {
shell_env->errorlevel = shell_cmd->command(argc, argv);
}
@@ -551,6 +555,10 @@ fprintf( stderr,
fflush( stderr );
}
} while (result && shell_env->forever);
+ if ( stdinToClose )
+ fclose( stdinToClose );
+ if ( stdoutToClose )
+ fclose( stdoutToClose );
return result;
}
diff --git a/cpukit/libmisc/shell/shell.h b/cpukit/libmisc/shell/shell.h
index 9415c5940f..2aca183138 100644
--- a/cpukit/libmisc/shell/shell.h
+++ b/cpukit/libmisc/shell/shell.h
@@ -73,9 +73,27 @@ int rtems_shell_make_args(
int max_args
);
-int rtems_shell_scanline(char * line,int size,FILE * in,FILE * out) ;
-int rtems_shell_cat_file(FILE * out,char *name);
-void rtems_shell_write_file(char *name,char * content);
+int rtems_shell_scanline(
+ char *line,
+ int size,
+ FILE *in,
+ FILE *out
+);
+
+int rtems_shell_cat_file(
+ FILE *out,
+ char *name
+);
+
+void rtems_shell_write_file(
+ const char *name,
+ const char *content
+);
+
+int rtems_shell_script_file(
+ int argc,
+ char *argv[]
+);
/**
* Initialise the shell creating tasks to login and run the shell
diff --git a/cpukit/libmisc/shell/shell_makeargs.c b/cpukit/libmisc/shell/shell_makeargs.c
index 9359a634d3..35d1cf475d 100644
--- a/cpukit/libmisc/shell/shell_makeargs.c
+++ b/cpukit/libmisc/shell/shell_makeargs.c
@@ -1,7 +1,7 @@
/*
* Split string into argc/argv style argument list
*
- * COPYRIGHT (c) 1989-2007.
+ * COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
diff --git a/cpukit/libmisc/shell/shell_script.c b/cpukit/libmisc/shell/shell_script.c
new file mode 100644
index 0000000000..a38d2aa72d
--- /dev/null
+++ b/cpukit/libmisc/shell/shell_script.c
@@ -0,0 +1,327 @@
+/*
+ * Shell Script Invocation
+ *
+ * Pseudo-code from Chris Johns, implemented and debugged
+ * by Joel Sherrill.
+ *
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include <rtems.h>
+#include <rtems/shell.h>
+#include "internal.h"
+
+static void rtems_shell_joel_usage()
+{
+ printf(
+ "joel [args] where args may be:\n"
+ " -o FILE output file (default=stdout)\n"
+ " -p PRIORITY task priority\n"
+ " -s SIZE task stack size\n"
+ " -t NAME task name\n"
+ );
+}
+
+int rtems_shell_main_decho(
+ int argc,
+ char **argv
+)
+{
+ int i;
+
+ for (i=0 ; i<argc ; i++ )
+ printf( "argv[%d] = -%s-\n", i, argv[i] );
+ return 0;
+}
+
+static int findOnPATH(
+ const char *userScriptName,
+ char *scriptFile
+)
+{
+ /*
+ * If the user script name starts with a / assume it is a fully
+ * qualified path name and just use it.
+ */
+ if ( userScriptName[0] == '/' ) {
+ strcpy( scriptFile, userScriptName );
+ return 0;
+ }
+
+ /*
+ * For now, the provided name is just turned into a fully
+ * qualified path name and used. There is no attempt to
+ * search along a path for it.
+ */
+
+ getcwd( scriptFile, PATH_MAX );
+ /* XXX should use strncat but what is the limit? */
+ strcat( scriptFile, "/" );
+ strcat( scriptFile, userScriptName );
+ return 0;
+
+#if 0
+ /*
+ * Does the command (argv[0]) contain a path ?, i.e. starts with
+ * '.' or contains a '/'?
+ */
+ /* TODO: Add concept of PATH */
+ if (!contains_path) {
+ /* check PATH environment variable */
+ for (path_part = PATH; path_part; skip to ':')
+ {
+ }
+ if (not found)
+ return -1;
+ }
+#endif
+}
+
+int rtems_shell_main_joel(
+ int argc,
+ char **argv
+)
+{
+ int option;
+ int sc;
+ int verbose = 0;
+ char *taskName = "JOEL";
+ uint32_t stackSize = RTEMS_MINIMUM_STACK_SIZE * 10;
+ rtems_task_priority taskPriority = 20;
+ char *outputFile = "stdout";
+ rtems_status_code result;
+ char scriptFile[PATH_MAX];
+ struct getopt_data getopt_reent;
+
+ while ( (option = getopt_r( argc, argv, "o:p:s:t:v", &getopt_reent)) != -1 ) {
+ switch ((char)option) {
+ case 'o':
+ outputFile = getopt_reent.optarg;
+ break;
+ case 'p':
+ taskPriority = rtems_shell_str2int(getopt_reent.optarg);
+ break;
+ case 's':
+ stackSize = rtems_shell_str2int(getopt_reent.optarg);
+ break;
+ case 't':
+ taskName = getopt_reent.optarg;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case '?':
+ default:
+ rtems_shell_joel_usage();
+ return -1;
+ }
+ }
+
+ if ( verbose ) {
+ fprintf( stderr,
+ "outputFile: %s\n"
+ "taskPriority: %" PRId32 "\n"
+ "stackSize: %" PRId32 "\n"
+ "taskName: %s\n",
+ outputFile,
+ taskPriority,
+ stackSize,
+ taskName
+ );
+ }
+
+ /*
+ * Verify there is a script name past the end of the arguments.
+ * Preincrement to skip program name.
+ */
+ if ( getopt_reent.optind >= argc ) {
+ fprintf( stderr, "Shell: No script to execute\n" );
+ return -1;
+ }
+
+ /*
+ * Find script on the path.
+ *
+ * NOTE: It is terrible that this is done twice but it
+ * seems to be the most expedient thing.
+ */
+ sc = findOnPATH( argv[getopt_reent.optind], scriptFile );
+ if ( sc ) {
+ fprintf( stderr, "%s not found on PATH\n", argv[0] );
+ return -1;
+ }
+
+ /* fprintf( stderr, "SCRIPT: -%s-\n", scriptFile ); */
+
+ /*
+ * I assume that argv[optind...] will have the arguments to
+ * the shell script. But that remains to be implemented.
+ */
+
+ /*
+ * Run the script
+ */
+ result = rtems_shell_script(
+ taskName, /* the name of the task */
+ stackSize, /* stack size */
+ taskPriority, /* task priority */
+ scriptFile, /* the script file */
+ outputFile, /* where to redirect the script */
+ 0, /* run once and exit */
+ 1 /* we will wait */
+ );
+ if (result)
+ return -1;
+ return 0;
+}
+
+rtems_shell_cmd_t rtems_shell_JOEL_Command = {
+ "joel", /* name */
+ "joel [args] SCRIPT", /* usage */
+ "misc", /* topic */
+ rtems_shell_main_joel, /* command */
+ NULL, /* alias */
+ NULL /* next */
+};
+
+/*
+ * This is a helper function which takes a command as arguments
+ * which has not been located as a built-in command and attempts
+ * to find something in the filesystem with the same name that
+ * appears to be a shell script.
+ */
+int rtems_shell_script_file(
+ int argc,
+ char *argv[]
+)
+{
+ #define FIRST_LINE_LENGTH 128
+ #define SCRIPT_ARGV_LIMIT 32
+ char scriptFile[PATH_MAX];
+ char *scriptHead;
+ char scriptHeadBuffer[FIRST_LINE_LENGTH];
+ int sc;
+ FILE *script;
+ size_t length;
+ int scriptArgc;
+ char *scriptArgv[SCRIPT_ARGV_LIMIT];
+
+ /*
+ * Clear argv pointer array
+ */
+ for ( scriptArgc=0 ; scriptArgc<SCRIPT_ARGV_LIMIT ; scriptArgc++ )
+ scriptArgv[scriptArgc] = NULL;
+
+ /*
+ * Find argv[0] on the path
+ */
+ sc = findOnPATH( argv[0], scriptFile );
+ if ( sc ) {
+ fprintf( stderr, "%s not found on PATH\n", argv[0] );
+ return -1;
+ }
+
+ /*
+ * Open the file so we can see if it looks like a script.
+ */
+ script = fopen( scriptFile, "r" );
+ if ( !script ) {
+ fprintf( stderr, "%s: Unable to open %s\n", argv[0], scriptFile );
+ return -1;
+ }
+
+ /*
+ * Is the script OK to run?
+ * Verify the current user has permission to execute it.
+ *
+ * NOTE: May not work on all file systems
+ */
+ sc = access( scriptFile, X_OK );
+ if ( sc ) {
+ fprintf( stderr, "Unable to execute %s\n", scriptFile );
+ fclose( script );
+ return -1;
+ }
+
+ /*
+ * Try to read the first line from the potential script file
+ */
+ scriptHead = fgets(scriptHeadBuffer, FIRST_LINE_LENGTH, script);
+ if ( !scriptHead ) {
+ fprintf(
+ stderr, "%s: Unable to read first line of %s\n", argv[0], scriptFile );
+ fclose( script );
+ return -1;
+ }
+
+ fclose(script);
+
+ length = strnlen(scriptHead, FIRST_LINE_LENGTH);
+ scriptHead[length - 1] = '\0';
+
+ /* fprintf( stderr, "FIRST LINE: -%s-\n", scriptHead ); */
+
+ /*
+ * Verify the name of the "shell" is joel. This means
+ * the line starts with "#! joel".
+ */
+ if (strncmp("#! joel", scriptHead, 7) != 0) {
+ fprintf( stderr, "%s: Not a joel script %s\n", argv[0], scriptFile );
+ return -1;
+ }
+
+ /*
+ * Do not worry about search path further. We have found the
+ * script, it is executable, and we have successfully read the
+ * first line and found out it is a script.
+ */
+
+ /*
+ * Check for arguments in fist line of the script. This changes
+ * how the shell task is run.
+ */
+
+ sc = rtems_shell_make_args(
+ &scriptHead[3],
+ &scriptArgc,
+ scriptArgv,
+ SCRIPT_ARGV_LIMIT - 1
+ );
+ if ( sc ) {
+ fprintf(
+ stderr, "%s: Error parsing joel arguments %s\n", argv[0], scriptFile );
+ return -1;
+ }
+
+ scriptArgv[ scriptArgc++ ] = scriptFile;
+
+ /*
+ * TODO: How do we pass arguments from here to the script?
+ * At this point, it doesn't matter because we don't
+ * have any way for a shell script to access them.
+ */
+ return rtems_shell_main_joel( scriptArgc, scriptArgv );
+
+ return 0;
+}
+
diff --git a/cpukit/libmisc/shell/shellconfig.c b/cpukit/libmisc/shell/shellconfig.c
index f3448ee693..1272ae8380 100644
--- a/cpukit/libmisc/shell/shellconfig.c
+++ b/cpukit/libmisc/shell/shellconfig.c
@@ -1,6 +1,9 @@
/*
* RTEMS Shell Command Set -- DEFAULT Configuration
*
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
diff --git a/cpukit/libmisc/shell/shellconfig.h b/cpukit/libmisc/shell/shellconfig.h
index 33d60f7e28..3cde53ffc4 100644
--- a/cpukit/libmisc/shell/shellconfig.h
+++ b/cpukit/libmisc/shell/shellconfig.h
@@ -29,7 +29,10 @@ extern rtems_shell_cmd_t rtems_shell_MEDIT_Command;
extern rtems_shell_cmd_t rtems_shell_MFILL_Command;
extern rtems_shell_cmd_t rtems_shell_MMOVE_Command;
+extern rtems_shell_cmd_t rtems_shell_JOEL_Command;
extern rtems_shell_cmd_t rtems_shell_DATE_Command;
+extern rtems_shell_cmd_t rtems_shell_ECHO_Command;
+extern rtems_shell_cmd_t rtems_shell_SLEEP_Command;
extern rtems_shell_cmd_t rtems_shell_ID_Command;
extern rtems_shell_cmd_t rtems_shell_TTY_Command;
extern rtems_shell_cmd_t rtems_shell_WHOAMI_Command;
@@ -144,11 +147,26 @@ extern rtems_shell_filesystems_t *rtems_shell_Mount_filesystems[];
* Common commands that can be optional
*/
#if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_JOEL)) || \
+ defined(CONFIGURE_SHELL_COMMAND_JOEL)
+ &rtems_shell_JOEL_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
!defined(CONFIGURE_SHELL_NO_COMMAND_DATE)) || \
defined(CONFIGURE_SHELL_COMMAND_DATE)
&rtems_shell_DATE_Command,
#endif
#if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_ECHO)) || \
+ defined(CONFIGURE_SHELL_COMMAND_ECHO)
+ &rtems_shell_ECHO_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_SLEEP)) || \
+ defined(CONFIGURE_SHELL_COMMAND_SLEEP)
+ &rtems_shell_SLEEP_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
!defined(CONFIGURE_SHELL_NO_COMMAND_ID)) || \
defined(CONFIGURE_SHELL_COMMAND_ID)
&rtems_shell_ID_Command,
diff --git a/cpukit/libmisc/shell/write_file.c b/cpukit/libmisc/shell/write_file.c
index e294ad99b6..f9e72f4645 100644
--- a/cpukit/libmisc/shell/write_file.c
+++ b/cpukit/libmisc/shell/write_file.c
@@ -23,13 +23,17 @@
#include <string.h>
void rtems_shell_write_file(
- char *name,
- char * content
+ const char *name,
+ const char *content
)
{
FILE * fd;
fd = fopen(name,"w");
+ if ( !fd ) {
+ fprintf( stderr, "Unable to write %s\n", name );
+ }
+
if (fd) {
fwrite(content,1,strlen(content),fd);
fclose(fd);