* maybe change map[] to use 2-bit entries
* (eventually) remove all the printf's
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
*/
#include <ctype.h> /* isalpha, isdigit */
#include <unistd.h> /* getpid */
#include "cmdedit.h"
#else
#define bb_applet_name "hush"
-#include "standalone.h"
+//#include "standalone.h"
#define hush_main main
#undef CONFIG_FEATURE_SH_FANCY_PROMPT
-#define BB_BANNER
+#define BB_BANNER ""
#endif
#define SPECIAL_VAR_SYMBOL 03
#define FLAG_EXIT_FROM_LOOP 1
/* The descrip member of this structure is only used to make debugging
* output pretty */
-struct {int mode; int default_fd; char *descrip;} redir_table[] = {
+static const struct {int mode; int default_fd; const char *descrip;} redir_table[] = {
{ 0, 0, "()" },
{ O_RDONLY, 0, "<" },
{ O_CREAT|O_TRUNC|O_WRONLY, 1, ">" },
/* globals, connect us to the outside world
* the first three support $?, $#, and $1 */
-char **global_argv;
-unsigned int global_argc;
-unsigned int last_return_code;
+static char **global_argv;
+static int global_argc;
+static int last_return_code;
extern char **environ; /* This is in <unistd.h>, but protected with __USE_GNU */
/* "globals" within this file */
static char *ifs;
-static char map[256];
+static unsigned char map[256];
static int fake_mode;
static int interactive;
static struct close_me *close_me_head;
static const char *cwd;
static struct pipe *job_list;
static unsigned int last_bg_pid;
-static unsigned int last_jobid;
+static int last_jobid;
static unsigned int shell_terminal;
static char *PS1;
static char *PS2;
-struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 };
-struct variables *top_vars = &shell_ver;
+static struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 };
+static struct variables *top_vars = &shell_ver;
#define B_CHUNK (100)
#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
struct built_in_command {
- char *cmd; /* name */
- char *descr; /* description */
+ const char *cmd; /* name */
+ const char *descr; /* description */
int (*function) (struct child_prog *); /* function ptr */
};
va_end(args);
}
#else
-static inline void debug_printf(const char *format, ...) { }
+static inline void debug_printf(const char *format ATTRIBUTE_UNUSED, ...) { }
#endif
#define final_printf debug_printf
/* really run the final data structures: */
static int setup_redirects(struct child_prog *prog, int squirrel[]);
static int run_list_real(struct pipe *pi);
-static void pseudo_exec(struct child_prog *child) __attribute__ ((noreturn));
+static void pseudo_exec(struct child_prog *child) ATTRIBUTE_NORETURN;
static int run_pipe_real(struct pipe *pi);
/* extended glob support: */
static int globhack(const char *src, int flags, glob_t *pglob);
* in the parent shell process. If forked, of course they can not.
* For example, 'unset foo | whatever' will parse and run, but foo will
* still be set at the end. */
-static struct built_in_command bltins[] = {
+static const struct built_in_command bltins[] = {
{"bg", "Resume a job in the background", builtin_fg_bg},
{"break", "Exit for, while or until loop", builtin_not_written},
{"cd", "Change working directory", builtin_cd},
}
/* built-in 'env' handler */
-static int builtin_env(struct child_prog *dummy)
+static int builtin_env(struct child_prog *dummy ATTRIBUTE_UNUSED)
{
char **e = environ;
if (e == NULL) return EXIT_FAILURE;
}
/* built-in 'help' handler */
-static int builtin_help(struct child_prog *dummy)
+static int builtin_help(struct child_prog *dummy ATTRIBUTE_UNUSED)
{
- struct built_in_command *x;
+ const struct built_in_command *x;
printf("\nBuilt-in commands:\n");
printf("-------------------\n");
}
/* built-in 'jobs' handler */
-static int builtin_jobs(struct child_prog *child)
+static int builtin_jobs(struct child_prog *child ATTRIBUTE_UNUSED)
{
struct pipe *job;
char *status_string;
/* built-in 'pwd' handler */
-static int builtin_pwd(struct child_prog *dummy)
+static int builtin_pwd(struct child_prog *dummy ATTRIBUTE_UNUSED)
{
puts(set_cwd());
return EXIT_SUCCESS;
}
/* belongs in utility.c */
-char *simple_itoa(unsigned int i)
+static char *simple_itoa(unsigned int i)
{
/* 21 digits plus null terminator, good for 64-bit or smaller ints */
static char local[22];
{
int i, rcode;
char *p;
- struct built_in_command *x;
+ const struct built_in_command *x;
if (child->argv) {
for (i=0; is_assignment(child->argv[i]); i++) {
debug_printf("pid %d environment modification: %s\n",getpid(),child->argv[i]);
* we belong to the foreground process group associated with
* that tty. The value of shell_terminal is needed in order to call
* tcsetpgrp(shell_terminal, ...); */
-void controlling_tty(int check_pgrp)
+#if 0
+static void controlling_tty(int check_pgrp)
{
pid_t curpgrp;
shell_terminal = -1;
return;
}
+#endif
/* run_pipe_real() starts all the jobs, but doesn't wait for anything
* to finish. See checkjobs().
int nextin, nextout;
int pipefds[2]; /* pipefds[0] is for reading */
struct child_prog *child;
- struct built_in_command *x;
+ const struct built_in_command *x;
char *p;
nextin = 0;
if (rmode == RES_IN) continue;
if (rmode == RES_DO) {
if (!flag_rep) continue;
- }
+ }
if ((rmode == RES_DONE)) {
if (flag_rep) {
flag_restore = 1;
{
int gr;
- /* short-circuit for null word */
+ /* short-circuit for null word */
/* we can code this better when the debug_printf's are gone */
- if (dest->length == 0) {
- if (dest->nonnull) {
- /* bash man page calls this an "explicit" null */
- gr = globhack(dest->data, flags, pglob);
- debug_printf("globhack returned %d\n",gr);
- } else {
+ if (dest->length == 0) {
+ if (dest->nonnull) {
+ /* bash man page calls this an "explicit" null */
+ gr = globhack(dest->data, flags, pglob);
+ debug_printf("globhack returned %d\n",gr);
+ } else {
return 0;
}
- } else if (glob_needed(dest->data)) {
+ } else if (glob_needed(dest->data)) {
gr = glob(dest->data, flags, NULL, pglob);
debug_printf("glob returned %d\n",gr);
if (gr == GLOB_NOMATCH) {
return 0;
}
-struct pipe *new_pipe(void) {
+static struct pipe *new_pipe(void) {
struct pipe *pi;
pi = xmalloc(sizeof(struct pipe));
pi->num_progs = 0;
pi->progs = NULL;
pi->next = NULL;
pi->followup = 0; /* invalid */
+ pi->r_mode = RES_NONE;
return pi;
}
* should handle if, then, elif, else, fi, for, while, until, do, done.
* case, function, and select are obnoxious, save those for later.
*/
-int reserved_word(o_string *dest, struct p_context *ctx)
+static int reserved_word(o_string *dest, struct p_context *ctx)
{
struct reserved_combo {
char *literal;
if (reserved_word(dest,ctx)) return ctx->w==RES_SNTX;
}
glob_target = &child->glob_result;
- if (child->argv) flags |= GLOB_APPEND;
+ if (child->argv) flags |= GLOB_APPEND;
}
gr = xglob(dest, flags, glob_target);
if (gr != 0) return 1;
return num;
}
-FILE *generate_stream_from_list(struct pipe *head)
+static FILE *generate_stream_from_list(struct pipe *head)
{
FILE *pf;
#if 1
int parse_stream(o_string *dest, struct p_context *ctx,
struct in_str *input, int end_trigger)
{
- unsigned int ch, m;
+ int ch, m;
int redir_fd;
redir_type redir_style;
int next;
return 0;
}
-void mapset(const unsigned char *set, int code)
+static void mapset(const char *set, int code)
{
const unsigned char *s;
- for (s=set; *s; s++) map[*s] = code;
+ for (s = (const unsigned char *)set; *s; s++) map[(int)*s] = code;
}
-void update_ifs_map(void)
+static void update_ifs_map(void)
{
/* char *ifs and char map[256] are both globals. */
ifs = getenv("IFS");
if (interactive) {
/* Looks like they want an interactive shell */
#ifndef CONFIG_FEATURE_SH_EXTRA_QUIET
- printf( "\n\n" BB_BANNER " hush - the humble shell v0.01 (testing)\n");
+ printf( "\n\n%s hush - the humble shell v0.01 (testing)\n",
+ BB_BANNER);
printf( "Enter 'help' for a list of built-in commands.\n\n");
#endif
setup_job_control();