1/* vi: set sw=4 ts=4: */
2/*
3 * lash -- the BusyBox Lame-Ass SHell
4 *
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6 *
7 * Based in part on ladsh.c by Michael K. Johnson and Erik W. Troan, which is
8 * under the following liberal license: "We have placed this source code in the
9 * public domain. Use it in any project, free or commercial."
10 *
11 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
12 */
13
14/* This shell's parsing engine is officially at a dead-end.  Future
15 * work shell work should be done using hush, msh, or ash.  This is
16 * still a very useful, small shell -- it just don't need any more
17 * features beyond what it already has...
18 */
19
20//For debugging/development on the shell only...
21//#define DEBUG_SHELL
22
23#include <getopt.h>
24#include <glob.h>
25
26#include "busybox.h" /* for struct bb_applet */
27
28#define expand_t	glob_t
29
30/* Always enable for the moment... */
31#define CONFIG_LASH_PIPE_N_REDIRECTS
32#define CONFIG_LASH_JOB_CONTROL
33#define ENABLE_LASH_PIPE_N_REDIRECTS 1
34#define ENABLE_LASH_JOB_CONTROL      1
35
36
37enum { MAX_READ = 128 }; /* size of input buffer for 'read' builtin */
38#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
39
40
41#if ENABLE_LASH_PIPE_N_REDIRECTS
42enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
43	REDIRECT_APPEND
44};
45#endif
46
47enum {
48	DEFAULT_CONTEXT = 0x1,
49	IF_TRUE_CONTEXT = 0x2,
50	IF_FALSE_CONTEXT = 0x4,
51	THEN_EXP_CONTEXT = 0x8,
52	ELSE_EXP_CONTEXT = 0x10
53};
54
55#define LASH_OPT_DONE (1)
56#define LASH_OPT_SAW_QUOTE (2)
57
58#if ENABLE_LASH_PIPE_N_REDIRECTS
59struct redir_struct {
60	enum redir_type type;	/* type of redirection */
61	int fd;						/* file descriptor being redirected */
62	char *filename;				/* file to redirect fd to */
63};
64#endif
65
66struct child_prog {
67	pid_t pid;					/* 0 if exited */
68	char **argv;				/* program name and arguments */
69	int num_redirects;			/* elements in redirection array */
70	int is_stopped;				/* is the program currently running? */
71	struct job *family;			/* pointer back to the child's parent job */
72#if ENABLE_LASH_PIPE_N_REDIRECTS
73	struct redir_struct *redirects;	/* I/O redirects */
74#endif
75};
76
77struct jobset {
78	struct job *head;			/* head of list of running jobs */
79	struct job *fg;				/* current foreground job */
80};
81
82struct job {
83	int jobid;					/* job number */
84	int num_progs;				/* total number of programs in job */
85	int running_progs;			/* number of programs running */
86	char *text;					/* name of job */
87	char *cmdbuf;				/* buffer various argv's point into */
88	pid_t pgrp;					/* process group ID for the job */
89	struct child_prog *progs;	/* array of programs in job */
90	struct job *next;			/* to track background commands */
91	int stopped_progs;			/* number of programs alive, but stopped */
92	unsigned int job_context;	/* bitmask defining current context */
93	struct jobset *job_list;
94};
95
96struct built_in_command {
97	const char *cmd;   /* name */
98	const char *descr; /* description */
99	int (*function) (struct child_prog *);	/* function ptr */
100};
101
102/* function prototypes for builtins */
103static int builtin_cd(struct child_prog *cmd);
104static int builtin_exec(struct child_prog *cmd);
105static int builtin_exit(struct child_prog *cmd);
106static int builtin_fg_bg(struct child_prog *cmd);
107static int builtin_help(struct child_prog *cmd);
108static int builtin_jobs(struct child_prog *dummy);
109static int builtin_pwd(struct child_prog *dummy);
110static int builtin_export(struct child_prog *cmd);
111static int builtin_source(struct child_prog *cmd);
112static int builtin_unset(struct child_prog *cmd);
113static int builtin_read(struct child_prog *cmd);
114
115
116/* function prototypes for shell stuff */
117static void checkjobs(struct jobset *job_list);
118static void remove_job(struct jobset *j_list, struct job *job);
119static int get_command_bufsiz(FILE * source, char *command);
120static int parse_command(char **command_ptr, struct job *job, int *inbg);
121static int run_command(struct job *newjob, int inbg, int outpipe[2]);
122static int pseudo_exec(struct child_prog *cmd) ATTRIBUTE_NORETURN;
123static int busy_loop(FILE * input);
124
125
126/* Table of built-in functions (these are non-forking builtins, meaning they
127 * can change global variables in the parent shell process but they will not
128 * work with pipes and redirects; 'unset foo | whatever' will not work) */
129static const struct built_in_command bltins[] = {
130	{"bg"    , "Resume a job in the background", builtin_fg_bg},
131	{"cd"    , "Change working directory", builtin_cd},
132	{"exec"  , "Exec command, replacing this shell with the exec'd process", builtin_exec},
133	{"exit"  , "Exit from shell()", builtin_exit},
134	{"fg"    , "Bring job into the foreground", builtin_fg_bg},
135	{"jobs"  , "Lists the active jobs", builtin_jobs},
136	{"export", "Set environment variable", builtin_export},
137	{"unset" , "Unset environment variable", builtin_unset},
138	{"read"  , "Input environment variable", builtin_read},
139	{"."     , "Source-in and run commands in a file", builtin_source},
140	/* These were "forked applets", but distinction was nuked */
141	/* Original comment retained: */
142	/* Table of forking built-in functions (things that fork cannot change global
143	 * variables in the parent process, such as the current working directory) */
144	{"pwd"   , "Print current directory", builtin_pwd},
145	{"help"  , "List shell built-in commands", builtin_help},
146	/* to do: add ulimit */
147};
148
149
150#define VEC_LAST(v) v[ARRAY_SIZE(v)-1]
151
152
153static int shell_context;  /* Type prompt trigger (PS1 or PS2) */
154
155
156/* Globals that are static to this file */
157static char *cwd;
158static char *local_pending_command;
159static struct jobset job_list = { NULL, NULL };
160static int argc;
161static char **argv;
162static llist_t *close_me_list;
163static int last_return_code;
164static int last_bg_pid;
165static unsigned int last_jobid;
166static int shell_terminal;
167static const char *PS1;
168static const char *PS2 = "> ";
169
170
171#ifdef DEBUG_SHELL
172static inline void debug_printf(const char *format, ...)
173{
174	va_list args;
175	va_start(args, format);
176	vfprintf(stderr, format, args);
177	va_end(args);
178}
179#else
180static inline void debug_printf(const char ATTRIBUTE_UNUSED *format, ...) { }
181#endif
182
183/*
184	Most builtins need access to the struct child_prog that has
185	their arguments, previously coded as cmd->progs[0].  That coding
186	can exhibit a bug, if the builtin is not the first command in
187	a pipeline: "echo foo | exec sort" will attempt to exec foo.
188
189builtin   previous use      notes
190------ -----------------  ---------
191cd      cmd->progs[0]
192exec    cmd->progs[0]  squashed bug: didn't look for applets or forking builtins
193exit    cmd->progs[0]
194fg_bg   cmd->progs[0], job_list->head, job_list->fg
195help    0
196jobs    job_list->head
197pwd     0
198export  cmd->progs[0]
199source  cmd->progs[0]
200unset   cmd->progs[0]
201read    cmd->progs[0]
202
203I added "struct job *family;" to struct child_prog,
204and switched API to builtin_foo(struct child_prog *child);
205So   cmd->text        becomes  child->family->text
206     cmd->job_context  becomes  child->family->job_context
207     cmd->progs[0]    becomes  *child
208     job_list          becomes  child->family->job_list
209 */
210
211
212static void update_cwd(void)
213{
214	cwd = xrealloc_getcwd_or_warn(cwd);
215	if (!cwd)
216		cwd = xstrdup(bb_msg_unknown);
217}
218
219/* built-in 'cd <path>' handler */
220static int builtin_cd(struct child_prog *child)
221{
222	char *newdir;
223
224	if (child->argv[1] == NULL)
225		newdir = getenv("HOME");
226	else
227		newdir = child->argv[1];
228	if (chdir(newdir)) {
229		bb_perror_msg("cd: %s", newdir);
230		return EXIT_FAILURE;
231	}
232	update_cwd();
233	return EXIT_SUCCESS;
234}
235
236/* built-in 'exec' handler */
237static int builtin_exec(struct child_prog *child)
238{
239	if (child->argv[1] == NULL)
240		return EXIT_SUCCESS;   /* Really? */
241	child->argv++;
242	while (close_me_list)
243		close((long)llist_pop(&close_me_list));
244	pseudo_exec(child);
245	/* never returns */
246}
247
248/* built-in 'exit' handler */
249static int builtin_exit(struct child_prog *child)
250{
251	if (child->argv[1] == NULL)
252		exit(EXIT_SUCCESS);
253
254	exit(atoi(child->argv[1]));
255}
256
257/* built-in 'fg' and 'bg' handler */
258static int builtin_fg_bg(struct child_prog *child)
259{
260	int i, jobnum;
261	struct job *job;
262
263	/* If they gave us no args, assume they want the last backgrounded task */
264	if (!child->argv[1]) {
265		for (job = child->family->job_list->head; job; job = job->next) {
266			if (job->jobid == last_jobid) {
267				goto found;
268			}
269		}
270		bb_error_msg("%s: no current job", child->argv[0]);
271		return EXIT_FAILURE;
272	}
273	if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) {
274		bb_error_msg(bb_msg_invalid_arg, child->argv[1], child->argv[0]);
275		return EXIT_FAILURE;
276	}
277	for (job = child->family->job_list->head; job; job = job->next) {
278		if (job->jobid == jobnum) {
279			goto found;
280		}
281	}
282	bb_error_msg("%s: %d: no such job", child->argv[0], jobnum);
283	return EXIT_FAILURE;
284 found:
285	if (*child->argv[0] == 'f') {
286		/* Put the job into the foreground.  */
287		tcsetpgrp(shell_terminal, job->pgrp);
288
289		child->family->job_list->fg = job;
290	}
291
292	/* Restart the processes in the job */
293	for (i = 0; i < job->num_progs; i++)
294		job->progs[i].is_stopped = 0;
295
296	job->stopped_progs = 0;
297
298	i = kill(- job->pgrp, SIGCONT);
299	if (i < 0) {
300		if (errno == ESRCH) {
301			remove_job(&job_list, job);
302		} else {
303			bb_perror_msg("kill (SIGCONT)");
304		}
305	}
306
307	return EXIT_SUCCESS;
308}
309
310/* built-in 'help' handler */
311static int builtin_help(struct child_prog ATTRIBUTE_UNUSED *dummy)
312{
313	const struct built_in_command *x;
314
315	printf("\nBuilt-in commands:\n"
316	       "-------------------\n");
317	for (x = bltins; x <= &VEC_LAST(bltins); x++) {
318		if (x->descr == NULL)
319			continue;
320		printf("%s\t%s\n", x->cmd, x->descr);
321	}
322	putchar('\n');
323	return EXIT_SUCCESS;
324}
325
326/* built-in 'jobs' handler */
327static int builtin_jobs(struct child_prog *child)
328{
329	struct job *job;
330	const char *status_string;
331
332	for (job = child->family->job_list->head; job; job = job->next) {
333		if (job->running_progs == job->stopped_progs)
334			status_string = "Stopped";
335		else
336			status_string = "Running";
337
338		printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
339	}
340	return EXIT_SUCCESS;
341}
342
343
344/* built-in 'pwd' handler */
345static int builtin_pwd(struct child_prog ATTRIBUTE_UNUSED *dummy)
346{
347	update_cwd();
348	puts(cwd);
349	return EXIT_SUCCESS;
350}
351
352/* built-in 'export VAR=value' handler */
353static int builtin_export(struct child_prog *child)
354{
355	int res;
356	char *v = child->argv[1];
357
358	if (v == NULL) {
359		char **e;
360		for (e = environ; *e; e++) {
361			puts(*e);
362		}
363		return 0;
364	}
365	res = putenv(v);
366	if (res)
367		bb_perror_msg("export");
368#if ENABLE_FEATURE_EDITING_FANCY_PROMPT
369	if (strncmp(v, "PS1=", 4) == 0)
370		PS1 = getenv("PS1");
371#endif
372
373#if ENABLE_LOCALE_SUPPORT
374	// TODO: why getenv? "" would be just as good...
375	if (strncmp(v, "LC_ALL=", 7) == 0)
376		setlocale(LC_ALL, getenv("LC_ALL"));
377	if (strncmp(v, "LC_CTYPE=", 9) == 0)
378		setlocale(LC_CTYPE, getenv("LC_CTYPE"));
379#endif
380
381	return res;
382}
383
384/* built-in 'read VAR' handler */
385static int builtin_read(struct child_prog *child)
386{
387	int res = 0, len;
388	char *s;
389	char string[MAX_READ];
390
391	if (child->argv[1]) {
392		/* argument (VAR) given: put "VAR=" into buffer */
393		safe_strncpy(string, child->argv[1], MAX_READ-1);
394		len = strlen(string);
395		string[len++] = '=';
396		string[len]   = '\0';
397		fgets(&string[len], sizeof(string) - len, stdin);	/* read string */
398		res = strlen(string);
399		if (res > len)
400			string[--res] = '\0';	/* chomp trailing newline */
401		/*
402		** string should now contain "VAR=<value>"
403		** copy it (putenv() won't do that, so we must make sure
404		** the string resides in a static buffer!)
405		*/
406		res = -1;
407		s = strdup(string);
408		if (s)
409			res = putenv(s);
410		if (res)
411			bb_perror_msg("read");
412	} else
413		fgets(string, sizeof(string), stdin);
414
415	return res;
416}
417
418/* Built-in '.' handler (read-in and execute commands from file) */
419static int builtin_source(struct child_prog *child)
420{
421	FILE *input;
422	int status;
423
424	input = fopen_or_warn(child->argv[1], "r");
425	if (!input) {
426		return EXIT_FAILURE;
427	}
428
429	llist_add_to(&close_me_list, (void *)(long)fileno(input));
430	/* Now run the file */
431	status = busy_loop(input);
432	fclose(input);
433	llist_pop(&close_me_list);
434	return status;
435}
436
437/* built-in 'unset VAR' handler */
438static int builtin_unset(struct child_prog *child)
439{
440	if (child->argv[1] == NULL) {
441		printf(bb_msg_requires_arg, "unset");
442		return EXIT_FAILURE;
443	}
444	unsetenv(child->argv[1]);
445	return EXIT_SUCCESS;
446}
447
448#if ENABLE_LASH_JOB_CONTROL
449/* free up all memory from a job */
450static void free_job(struct job *cmd)
451{
452	int i;
453	struct jobset *keep;
454
455	for (i = 0; i < cmd->num_progs; i++) {
456		free(cmd->progs[i].argv);
457#if ENABLE_LASH_PIPE_N_REDIRECTS
458		if (cmd->progs[i].redirects)
459			free(cmd->progs[i].redirects);
460#endif
461	}
462	free(cmd->progs);
463	free(cmd->text);
464	free(cmd->cmdbuf);
465	keep = cmd->job_list;
466	memset(cmd, 0, sizeof(struct job));
467	cmd->job_list = keep;
468}
469
470/* remove a job from a jobset */
471static void remove_job(struct jobset *j_list, struct job *job)
472{
473	struct job *prevjob;
474
475	free_job(job);
476	if (job == j_list->head) {
477		j_list->head = job->next;
478	} else {
479		prevjob = j_list->head;
480		while (prevjob->next != job)
481			prevjob = prevjob->next;
482		prevjob->next = job->next;
483	}
484
485	if (j_list->head)
486		last_jobid = j_list->head->jobid;
487	else
488		last_jobid = 0;
489
490	free(job);
491}
492
493/* Checks to see if any background processes have exited -- if they
494   have, figure out why and see if a job has completed */
495static void checkjobs(struct jobset *j_list)
496{
497	struct job *job;
498	pid_t childpid;
499	int status;
500	int prognum = 0;
501
502	while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
503		for (job = j_list->head; job; job = job->next) {
504			prognum = 0;
505			while (prognum < job->num_progs &&
506				   job->progs[prognum].pid != childpid) prognum++;
507			if (prognum < job->num_progs)
508				break;
509		}
510
511		/* This happens on backticked commands */
512		if (job == NULL)
513			return;
514
515		if (WIFEXITED(status) || WIFSIGNALED(status)) {
516			/* child exited */
517			job->running_progs--;
518			job->progs[prognum].pid = 0;
519
520			if (!job->running_progs) {
521				printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
522				last_jobid = 0;
523				remove_job(j_list, job);
524			}
525		} else {
526			/* child stopped */
527			job->stopped_progs++;
528			job->progs[prognum].is_stopped = 1;
529		}
530	}
531
532	if (childpid == -1 && errno != ECHILD)
533		bb_perror_msg("waitpid");
534}
535#else
536static void checkjobs(struct jobset *j_list)
537{
538}
539static void free_job(struct job *cmd)
540{
541}
542static void remove_job(struct jobset *j_list, struct job *job)
543{
544}
545#endif
546
547#if ENABLE_LASH_PIPE_N_REDIRECTS
548/* squirrel != NULL means we squirrel away copies of stdin, stdout,
549 * and stderr if they are redirected. */
550static int setup_redirects(struct child_prog *prog, int squirrel[])
551{
552	int i;
553	int openfd;
554	int mode = O_RDONLY;
555	struct redir_struct *redir = prog->redirects;
556
557	for (i = 0; i < prog->num_redirects; i++, redir++) {
558		switch (redir->type) {
559		case REDIRECT_INPUT:
560			mode = O_RDONLY;
561			break;
562		case REDIRECT_OVERWRITE:
563			mode = O_WRONLY | O_CREAT | O_TRUNC;
564			break;
565		case REDIRECT_APPEND:
566			mode = O_WRONLY | O_CREAT | O_APPEND;
567			break;
568		}
569
570		openfd = open3_or_warn(redir->filename, mode, 0666);
571		if (openfd < 0) {
572			/* this could get lost if stderr has been redirected, but
573			   bash and ash both lose it as well (though zsh doesn't!) */
574			return 1;
575		}
576
577		if (openfd != redir->fd) {
578			if (squirrel && redir->fd < 3) {
579				squirrel[redir->fd] = dup(redir->fd);
580				fcntl(squirrel[redir->fd], F_SETFD, FD_CLOEXEC);
581			}
582			dup2(openfd, redir->fd);
583			close(openfd);
584		}
585	}
586
587	return 0;
588}
589
590static void restore_redirects(int squirrel[])
591{
592	int i, fd;
593	for (i = 0; i < 3; i++) {
594		fd = squirrel[i];
595		if (fd != -1) {
596			/* No error checking.  I sure wouldn't know what
597			 * to do with an error if I found one! */
598			dup2(fd, i);
599			close(fd);
600		}
601	}
602}
603#else
604static inline int setup_redirects(struct child_prog *prog, int squirrel[])
605{
606	return 0;
607}
608static inline void restore_redirects(int squirrel[])
609{
610}
611#endif
612
613static inline void cmdedit_set_initial_prompt(void)
614{
615#if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
616	PS1 = NULL;
617#else
618	PS1 = getenv("PS1");
619	if (PS1 == 0)
620		PS1 = "\\w \\$ ";
621#endif
622}
623
624static inline const char* setup_prompt_string(void)
625{
626#if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
627	/* Set up the prompt */
628	if (shell_context == 0) {
629		char *ns;
630		free((char*)PS1);
631		ns = xmalloc(strlen(cwd)+4);
632		sprintf(ns, "%s %c ", cwd, (geteuid() != 0) ? '$': '#');
633		PS1 = ns;
634		return ns;
635	} else {
636		return PS2;
637	}
638#else
639	return (shell_context == 0)? PS1 : PS2;
640#endif
641}
642
643#if ENABLE_FEATURE_EDITING
644static line_input_t *line_input_state;
645#endif
646
647static int get_command_bufsiz(FILE * source, char *command)
648{
649	const char *prompt_str;
650
651	if (source == NULL) {
652		if (local_pending_command) {
653			/* a command specified (-c option): return it & mark it done */
654			strncpy(command, local_pending_command, BUFSIZ);
655			local_pending_command = NULL;
656			return 0;
657		}
658		return 1;
659	}
660
661	if (source == stdin) {
662		prompt_str = setup_prompt_string();
663
664#if ENABLE_FEATURE_EDITING
665		/*
666		** enable command line editing only while a command line
667		** is actually being read; otherwise, we'll end up bequeathing
668		** atexit() handlers and other unwanted stuff to our
669		** child processes (rob@sysgo.de)
670		*/
671		read_line_input(prompt_str, command, BUFSIZ, line_input_state);
672		return 0;
673#else
674		fputs(prompt_str, stdout);
675#endif
676	}
677
678	if (!fgets(command, BUFSIZ - 2, source)) {
679		if (source == stdin)
680			puts("");
681		return 1;
682	}
683
684	return 0;
685}
686
687static char * strsep_space(char *string, int * ix)
688{
689	/* Short circuit the trivial case */
690	if (!string || ! string[*ix])
691		return NULL;
692
693	/* Find the end of the token. */
694	while (string[*ix] && !isspace(string[*ix]) ) {
695		(*ix)++;
696	}
697
698	/* Find the end of any whitespace trailing behind
699	 * the token and let that be part of the token */
700	while (string[*ix] && (isspace)(string[*ix]) ) {
701		(*ix)++;
702	}
703
704	if (!*ix) {
705		/* Nothing useful was found */
706		return NULL;
707	}
708
709	return xstrndup(string, *ix);
710}
711
712static int expand_arguments(char *command)
713{
714	static const char out_of_space[] ALIGN1 = "out of space during expansion";
715
716	int total_length = 0, length, i, retval, ix = 0;
717	expand_t expand_result;
718	char *tmpcmd, *cmd, *cmd_copy;
719	char *src, *dst, *var;
720	int flags = GLOB_NOCHECK
721#ifdef GLOB_BRACE
722		| GLOB_BRACE
723#endif
724#ifdef GLOB_TILDE
725		| GLOB_TILDE
726#endif
727		;
728
729	/* get rid of the terminating \n */
730	chomp(command);
731
732	/* Fix up escape sequences to be the Real Thing(tm) */
733	while (command && command[ix]) {
734		if (command[ix] == '\\') {
735			const char *tmp = command+ix+1;
736			command[ix] = bb_process_escape_sequence(  &tmp );
737			memmove(command+ix + 1, tmp, strlen(tmp)+1);
738		}
739		ix++;
740	}
741	/* Use glob and then fixup environment variables and such */
742
743	/* It turns out that glob is very stupid.  We have to feed it one word at a
744	 * time since it can't cope with a full string.  Here we convert command
745	 * (char*) into cmd (char**, one word per string) */
746
747	/* We need a clean copy, so strsep can mess up the copy while
748	 * we write stuff into the original (in a minute) */
749	cmd = cmd_copy = xstrdup(command);
750	*command = '\0';
751	for (ix = 0, tmpcmd = cmd;
752			(tmpcmd = strsep_space(cmd, &ix)) != NULL; cmd += ix, ix = 0) {
753		if (*tmpcmd == '\0')
754			break;
755		/* we need to trim() the result for glob! */
756		trim(tmpcmd);
757		retval = glob(tmpcmd, flags, NULL, &expand_result);
758		free(tmpcmd); /* Free mem allocated by strsep_space */
759		if (retval == GLOB_NOSPACE) {
760			/* Mem may have been allocated... */
761			globfree(&expand_result);
762			bb_error_msg(out_of_space);
763			return FALSE;
764		} else if (retval != 0) {
765			/* Some other error.  GLOB_NOMATCH shouldn't
766			 * happen because of the GLOB_NOCHECK flag in
767			 * the glob call. */
768			bb_error_msg("syntax error");
769			return FALSE;
770		} else {
771			/* Convert from char** (one word per string) to a simple char*,
772			 * but don't overflow command which is BUFSIZ in length */
773			for (i = 0; i < expand_result.gl_pathc; i++) {
774				length = strlen(expand_result.gl_pathv[i]);
775				if (total_length+length+1 >= BUFSIZ) {
776					bb_error_msg(out_of_space);
777					return FALSE;
778				}
779				strcat(command+total_length, " ");
780				total_length += 1;
781				strcat(command+total_length, expand_result.gl_pathv[i]);
782				total_length += length;
783			}
784			globfree(&expand_result);
785		}
786	}
787	free(cmd_copy);
788	trim(command);
789
790	/* Now do the shell variable substitutions which
791	 * wordexp can't do for us, namely $? and $! */
792	src = command;
793	while ((dst = strchr(src,'$')) != NULL) {
794		var = NULL;
795		switch (*(dst+1)) {
796			case '?':
797				var = itoa(last_return_code);
798				break;
799			case '!':
800				if (last_bg_pid == -1)
801					*var = '\0';
802				else
803					var = itoa(last_bg_pid);
804				break;
805				/* Everything else like $$, $#, $[0-9], etc. should all be
806				 * expanded by wordexp(), so we can in theory skip that stuff
807				 * here, but just to be on the safe side (i.e., since uClibc
808				 * wordexp doesn't do this stuff yet), lets leave it in for
809				 * now. */
810			case '$':
811				var = itoa(getpid());
812				break;
813			case '#':
814				var = itoa(argc-1);
815				break;
816			case '0':case '1':case '2':case '3':case '4':
817			case '5':case '6':case '7':case '8':case '9':
818				{
819					int ixx = *(dst+1)-48+1;
820					if (ixx >= argc) {
821						var = '\0';
822					} else {
823						var = argv[ixx];
824					}
825				}
826				break;
827
828		}
829		if (var) {
830			/* a single character construction was found, and
831			 * already handled in the case statement */
832			src = dst + 2;
833		} else {
834			/* Looks like an environment variable */
835			char delim_hold;
836			int num_skip_chars = 0;
837			int dstlen = strlen(dst);
838			/* Is this a ${foo} type variable? */
839			if (dstlen >= 2 && *(dst+1) == '{') {
840				src = strchr(dst+1, '}');
841				num_skip_chars = 1;
842			} else {
843				src = dst + 1;
844				while ((isalnum)(*src) || *src == '_') src++;
845			}
846			if (src == NULL) {
847				src = dst+dstlen;
848			}
849			delim_hold = *src;
850			*src = '\0';  /* temporary */
851			var = getenv(dst + 1 + num_skip_chars);
852			*src = delim_hold;
853			src += num_skip_chars;
854		}
855		if (var == NULL) {
856			/* Seems we got an un-expandable variable.  So delete it. */
857			var = (char*)"";
858		}
859		{
860			int subst_len = strlen(var);
861			int trail_len = strlen(src);
862			if (dst+subst_len+trail_len >= command+BUFSIZ) {
863				bb_error_msg(out_of_space);
864				return FALSE;
865			}
866			/* Move stuff to the end of the string to accommodate
867			 * filling the created gap with the new stuff */
868			memmove(dst+subst_len, src, trail_len+1);
869			/* Now copy in the new stuff */
870			memcpy(dst, var, subst_len);
871			src = dst+subst_len;
872		}
873	}
874
875	return TRUE;
876}
877
878/* Return cmd->num_progs as 0 if no command is present (e.g. an empty
879   line). If a valid command is found, command_ptr is set to point to
880   the beginning of the next command (if the original command had more
881   then one job associated with it) or NULL if no more commands are
882   present. */
883static int parse_command(char **command_ptr, struct job *job, int *inbg)
884{
885	char *command;
886	char *return_command = NULL;
887	char *src, *buf;
888	int argc_l;
889	int flag;
890	int argv_alloced;
891	char quote = '\0';
892	struct child_prog *prog;
893#if ENABLE_LASH_PIPE_N_REDIRECTS
894	int i;
895	char *chptr;
896#endif
897
898	/* skip leading white space */
899	*command_ptr = skip_whitespace(*command_ptr);
900
901	/* this handles empty lines or leading '#' characters */
902	if (!**command_ptr || (**command_ptr == '#')) {
903		job->num_progs = 0;
904		return 0;
905	}
906
907	*inbg = 0;
908	job->num_progs = 1;
909	job->progs = xmalloc(sizeof(*job->progs));
910
911	/* We set the argv elements to point inside of this string. The
912	   memory is freed by free_job(). Allocate twice the original
913	   length in case we need to quote every single character.
914
915	   Getting clean memory relieves us of the task of NULL
916	   terminating things and makes the rest of this look a bit
917	   cleaner (though it is, admittedly, a tad less efficient) */
918	job->cmdbuf = command = xzalloc(2*strlen(*command_ptr) + 1);
919	job->text = NULL;
920
921	prog = job->progs;
922	prog->num_redirects = 0;
923	prog->is_stopped = 0;
924	prog->family = job;
925#if ENABLE_LASH_PIPE_N_REDIRECTS
926	prog->redirects = NULL;
927#endif
928
929	argv_alloced = 5;
930	prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
931	prog->argv[0] = job->cmdbuf;
932
933	flag = argc_l = 0;
934	buf = command;
935	src = *command_ptr;
936	while (*src && !(flag & LASH_OPT_DONE)) {
937		if (quote == *src) {
938			quote = '\0';
939		} else if (quote) {
940			if (*src == '\\') {
941				src++;
942				if (!*src) {
943					bb_error_msg("character expected after \\");
944					free_job(job);
945					return 1;
946				}
947
948				/* in shell, "\'" should yield \' */
949				if (*src != quote) {
950					*buf++ = '\\';
951					*buf++ = '\\';
952				}
953			} else if (*src == '*' || *src == '?' || *src == '[' ||
954					   *src == ']') *buf++ = '\\';
955			*buf++ = *src;
956		} else if (isspace(*src)) {
957			if (*prog->argv[argc_l] || (flag & LASH_OPT_SAW_QUOTE)) {
958				buf++, argc_l++;
959				/* +1 here leaves room for the NULL which ends argv */
960				if ((argc_l + 1) == argv_alloced) {
961					argv_alloced += 5;
962					prog->argv = xrealloc(prog->argv,
963							sizeof(*prog->argv) * argv_alloced);
964				}
965				prog->argv[argc_l] = buf;
966				flag ^= LASH_OPT_SAW_QUOTE;
967			}
968		} else
969			switch (*src) {
970			case '"':
971			case '\'':
972				quote = *src;
973				flag |= LASH_OPT_SAW_QUOTE;
974				break;
975
976			case '#':			/* comment */
977				if (*(src-1)== '$')
978					*buf++ = *src;
979				else
980					flag |= LASH_OPT_DONE;
981				break;
982
983#if ENABLE_LASH_PIPE_N_REDIRECTS
984			case '>':			/* redirects */
985			case '<':
986				i = prog->num_redirects++;
987				prog->redirects = xrealloc(prog->redirects,
988						sizeof(*prog->redirects) * (i + 1));
989
990				prog->redirects[i].fd = -1;
991				if (buf != prog->argv[argc_l]) {
992					/* the stuff before this character may be the file number
993					   being redirected */
994					prog->redirects[i].fd =
995						strtol(prog->argv[argc_l], &chptr, 10);
996
997					if (*chptr && *prog->argv[argc_l]) {
998						buf++, argc_l++;
999						prog->argv[argc_l] = buf;
1000					}
1001				}
1002
1003				if (prog->redirects[i].fd == -1) {
1004					if (*src == '>')
1005						prog->redirects[i].fd = 1;
1006					else
1007						prog->redirects[i].fd = 0;
1008				}
1009
1010				if (*src++ == '>') {
1011					if (*src == '>')
1012						prog->redirects[i].type =
1013							REDIRECT_APPEND, src++;
1014					else
1015						prog->redirects[i].type = REDIRECT_OVERWRITE;
1016				} else {
1017					prog->redirects[i].type = REDIRECT_INPUT;
1018				}
1019
1020				/* This isn't POSIX sh compliant. Oh well. */
1021				chptr = src;
1022				chptr = skip_whitespace(chptr);
1023
1024				if (!*chptr) {
1025					bb_error_msg("file name expected after %c", *(src-1));
1026					free_job(job);
1027					job->num_progs = 0;
1028					return 1;
1029				}
1030
1031				prog->redirects[i].filename = buf;
1032				while (*chptr && !isspace(*chptr))
1033					*buf++ = *chptr++;
1034
1035				src = chptr - 1;	/* we src++ later */
1036				prog->argv[argc_l] = ++buf;
1037				break;
1038
1039			case '|':			/* pipe */
1040				/* finish this command */
1041				if (*prog->argv[argc_l] || flag & LASH_OPT_SAW_QUOTE)
1042					argc_l++;
1043				if (!argc_l) {
1044					goto empty_command_in_pipe;
1045				}
1046				prog->argv[argc_l] = NULL;
1047
1048				/* and start the next */
1049				job->num_progs++;
1050				job->progs = xrealloc(job->progs,
1051						sizeof(*job->progs) * job->num_progs);
1052				prog = job->progs + (job->num_progs - 1);
1053				prog->num_redirects = 0;
1054				prog->redirects = NULL;
1055				prog->is_stopped = 0;
1056				prog->family = job;
1057				argc_l = 0;
1058
1059				argv_alloced = 5;
1060				prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1061				prog->argv[0] = ++buf;
1062
1063				src++;
1064				src = skip_whitespace(src);
1065
1066				if (!*src) {
1067empty_command_in_pipe:
1068					bb_error_msg("empty command in pipe");
1069					free_job(job);
1070					job->num_progs = 0;
1071					return 1;
1072				}
1073				src--;			/* we'll ++ it at the end of the loop */
1074
1075				break;
1076#endif
1077
1078#if ENABLE_LASH_JOB_CONTROL
1079			case '&':			/* background */
1080				*inbg = 1;
1081				/* fallthrough */
1082#endif
1083			case ';':			/* multiple commands */
1084				flag |= LASH_OPT_DONE;
1085				return_command = *command_ptr + (src - *command_ptr) + 1;
1086				break;
1087
1088			case '\\':
1089				src++;
1090				if (!*src) {
1091					bb_error_msg("character expected after \\");
1092					free_job(job);
1093					return 1;
1094				}
1095				if (*src == '*' || *src == '[' || *src == ']'
1096					|| *src == '?') *buf++ = '\\';
1097				/* fallthrough */
1098			default:
1099				*buf++ = *src;
1100			}
1101
1102		src++;
1103	}
1104
1105	if (*prog->argv[argc_l] || flag & LASH_OPT_SAW_QUOTE) {
1106		argc_l++;
1107	}
1108	if (!argc_l) {
1109		free_job(job);
1110		return 0;
1111	}
1112	prog->argv[argc_l] = NULL;
1113
1114	if (!return_command) {
1115		job->text = xstrdup(*command_ptr);
1116	} else {
1117		/* This leaves any trailing spaces, which is a bit sloppy */
1118		job->text = xstrndup(*command_ptr, return_command - *command_ptr);
1119	}
1120
1121	*command_ptr = return_command;
1122
1123	return 0;
1124}
1125
1126/* Run the child_prog, no matter what kind of command it uses.
1127 */
1128static int pseudo_exec(struct child_prog *child)
1129{
1130	const struct built_in_command *x;
1131
1132	/* Check if the command matches any of the non-forking builtins.
1133	 * Depending on context, this might be redundant.  But it's
1134	 * easier to waste a few CPU cycles than it is to figure out
1135	 * if this is one of those cases.
1136	 */
1137	/* Check if the command matches any of the forking builtins. */
1138	for (x = bltins; x <= &VEC_LAST(bltins); x++) {
1139		if (strcmp(child->argv[0], x->cmd) == 0) {
1140			_exit(x->function(child));
1141		}
1142	}
1143
1144
1145	/* Check if the command matches any busybox internal
1146	 * commands ("applets") here.  Following discussions from
1147	 * November 2000 on busybox@busybox.net, don't use
1148	 * bb_get_last_path_component().  This way explicit (with
1149	 * slashes) filenames will never be interpreted as an
1150	 * applet, just like with builtins.  This way the user can
1151	 * override an applet with an explicit filename reference.
1152	 * The only downside to this change is that an explicit
1153	 * /bin/foo invocation will fork and exec /bin/foo, even if
1154	 * /bin/foo is a symlink to busybox.
1155	 */
1156	if (ENABLE_FEATURE_SH_STANDALONE) {
1157		run_applet_and_exit(child->argv[0], child->argv);
1158	}
1159
1160	execvp(child->argv[0], child->argv);
1161
1162	/* Do not use bb_perror_msg_and_die() here, since we must not
1163	 * call exit() but should call _exit() instead */
1164	bb_perror_msg("%s", child->argv[0]);
1165	_exit(EXIT_FAILURE);
1166}
1167
1168static void insert_job(struct job *newjob, int inbg)
1169{
1170	struct job *thejob;
1171	struct jobset *j_list = newjob->job_list;
1172
1173	/* find the ID for thejob to use */
1174	newjob->jobid = 1;
1175	for (thejob = j_list->head; thejob; thejob = thejob->next)
1176		if (thejob->jobid >= newjob->jobid)
1177			newjob->jobid = thejob->jobid + 1;
1178
1179	/* add thejob to the list of running jobs */
1180	if (!j_list->head) {
1181		thejob = j_list->head = xmalloc(sizeof(*thejob));
1182	} else {
1183		for (thejob = j_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1184		thejob->next = xmalloc(sizeof(*thejob));
1185		thejob = thejob->next;
1186	}
1187
1188	*thejob = *newjob;   /* physically copy the struct job */
1189	thejob->next = NULL;
1190	thejob->running_progs = thejob->num_progs;
1191	thejob->stopped_progs = 0;
1192
1193#if ENABLE_LASH_JOB_CONTROL
1194	if (inbg) {
1195		/* we don't wait for background thejobs to return -- append it
1196		   to the list of backgrounded thejobs and leave it alone */
1197		printf("[%d] %d\n", thejob->jobid,
1198			   newjob->progs[newjob->num_progs - 1].pid);
1199		last_jobid = newjob->jobid;
1200		last_bg_pid = newjob->progs[newjob->num_progs - 1].pid;
1201	} else {
1202		newjob->job_list->fg = thejob;
1203
1204		/* move the new process group into the foreground */
1205		/* Ignore errors since child could have already exited */
1206		tcsetpgrp(shell_terminal, newjob->pgrp);
1207	}
1208#endif
1209}
1210
1211static int run_command(struct job *newjob, int inbg, int outpipe[2])
1212{
1213	/* struct job *thejob; */
1214	int i;
1215	int nextin, nextout;
1216	int pipefds[2];				/* pipefd[0] is for reading */
1217	const struct built_in_command *x;
1218	struct child_prog *child;
1219
1220	nextin = 0;
1221	for (i = 0; i < newjob->num_progs; i++) {
1222		child = &(newjob->progs[i]);
1223
1224		nextout = 1;
1225		if ((i + 1) < newjob->num_progs) {
1226			xpipe(pipefds);
1227			nextout = pipefds[1];
1228		} else if (outpipe[1] != -1) {
1229			nextout = outpipe[1];
1230		}
1231
1232		/* Check if the command matches any non-forking builtins,
1233		 * but only if this is a simple command.
1234		 * Non-forking builtins within pipes have to fork anyway,
1235		 * and are handled in pseudo_exec.  "echo foo | read bar"
1236		 * is doomed to failure, and doesn't work on bash, either.
1237		 */
1238		if (newjob->num_progs == 1) {
1239			int rcode;
1240			int squirrel[] = {-1, -1, -1};
1241
1242			/* Check if the command sets an environment variable. */
1243			if (strchr(child->argv[0], '=') != NULL) {
1244				child->argv[1] = child->argv[0];
1245				return builtin_export(child);
1246			}
1247
1248			for (x = bltins; x <= &VEC_LAST(bltins); x++) {
1249				if (strcmp(child->argv[0], x->cmd) == 0) {
1250					setup_redirects(child, squirrel);
1251					rcode = x->function(child);
1252					restore_redirects(squirrel);
1253					return rcode;
1254				}
1255			}
1256#if ENABLE_FEATURE_SH_STANDALONE
1257			{
1258				const struct bb_applet *a = find_applet_by_name(child->argv[i]);
1259				if (a && a->nofork) {
1260					setup_redirects(child, squirrel);
1261					rcode = run_nofork_applet(a, child->argv + i);
1262					restore_redirects(squirrel);
1263					return rcode;
1264				}
1265			}
1266#endif
1267		}
1268
1269#if BB_MMU
1270		child->pid = fork();
1271#else
1272		child->pid = vfork();
1273#endif
1274		if (!child->pid) {
1275			/* Set the handling for job control signals back to the default.  */
1276			signal(SIGINT, SIG_DFL);
1277			signal(SIGQUIT, SIG_DFL);
1278			signal(SIGTSTP, SIG_DFL);
1279			signal(SIGTTIN, SIG_DFL);
1280			signal(SIGTTOU, SIG_DFL);
1281			signal(SIGCHLD, SIG_DFL);
1282
1283			/* Close all open filehandles. */
1284			while (close_me_list)
1285				close((long)llist_pop(&close_me_list));
1286
1287			if (outpipe[1] != -1) {
1288				close(outpipe[0]);
1289			}
1290			if (nextin != 0) {
1291				dup2(nextin, 0);
1292				close(nextin);
1293			}
1294
1295			if (nextout != 1) {
1296				dup2(nextout, 1);
1297				dup2(nextout, 2);  /* Really? */
1298				close(nextout);
1299				close(pipefds[0]);
1300			}
1301
1302			/* explicit redirects override pipes */
1303			setup_redirects(child,NULL);
1304
1305			pseudo_exec(child);
1306		}
1307		if (outpipe[1] != -1) {
1308			close(outpipe[1]);
1309		}
1310
1311		/* put our child in the process group whose leader is the
1312		   first process in this pipe */
1313		setpgid(child->pid, newjob->progs[0].pid);
1314		if (nextin != 0)
1315			close(nextin);
1316		if (nextout != 1)
1317			close(nextout);
1318
1319		/* If there isn't another process, nextin is garbage
1320		   but it doesn't matter */
1321		nextin = pipefds[0];
1322	}
1323
1324	newjob->pgrp = newjob->progs[0].pid;
1325
1326	insert_job(newjob, inbg);
1327
1328	return 0;
1329}
1330
1331static int busy_loop(FILE * input)
1332{
1333	char *command;
1334	char *next_command = NULL;
1335	struct job newjob;
1336	int i;
1337	int inbg = 0;
1338	int status;
1339#if ENABLE_LASH_JOB_CONTROL
1340	pid_t  parent_pgrp;
1341	/* save current owner of TTY so we can restore it on exit */
1342	parent_pgrp = tcgetpgrp(shell_terminal);
1343#endif
1344	newjob.job_list = &job_list;
1345	newjob.job_context = DEFAULT_CONTEXT;
1346
1347	command = xzalloc(BUFSIZ);
1348
1349	while (1) {
1350		if (!job_list.fg) {
1351			/* no job is in the foreground */
1352
1353			/* see if any background processes have exited */
1354			checkjobs(&job_list);
1355
1356			if (!next_command) {
1357				if (get_command_bufsiz(input, command))
1358					break;
1359				next_command = command;
1360			}
1361
1362			if (!expand_arguments(next_command)) {
1363				free(command);
1364				command = xzalloc(BUFSIZ);
1365				next_command = NULL;
1366				continue;
1367			}
1368
1369			if (!parse_command(&next_command, &newjob, &inbg) &&
1370				newjob.num_progs) {
1371				int pipefds[2] = { -1, -1 };
1372				debug_printf("job=%p fed to run_command by busy_loop()'\n",
1373						&newjob);
1374				run_command(&newjob, inbg, pipefds);
1375			}
1376			else {
1377				free(command);
1378				command = xzalloc(BUFSIZ);
1379				next_command = NULL;
1380			}
1381		} else {
1382			/* a job is running in the foreground; wait for it */
1383			i = 0;
1384			while (!job_list.fg->progs[i].pid ||
1385				   job_list.fg->progs[i].is_stopped == 1) i++;
1386
1387			if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED) < 0) {
1388				if (errno != ECHILD) {
1389					bb_perror_msg_and_die("waitpid(%d)", job_list.fg->progs[i].pid);
1390				}
1391			}
1392
1393			if (WIFEXITED(status) || WIFSIGNALED(status)) {
1394				/* the child exited */
1395				job_list.fg->running_progs--;
1396				job_list.fg->progs[i].pid = 0;
1397
1398				last_return_code = WEXITSTATUS(status);
1399
1400				if (!job_list.fg->running_progs) {
1401					/* child exited */
1402					remove_job(&job_list, job_list.fg);
1403					job_list.fg = NULL;
1404				}
1405			}
1406#if ENABLE_LASH_JOB_CONTROL
1407			else {
1408				/* the child was stopped */
1409				job_list.fg->stopped_progs++;
1410				job_list.fg->progs[i].is_stopped = 1;
1411
1412				if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1413					printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1414						   "Stopped", job_list.fg->text);
1415					job_list.fg = NULL;
1416				}
1417			}
1418
1419			if (!job_list.fg) {
1420				/* move the shell to the foreground */
1421				/* suppress messages when run from /linuxrc mag@sysgo.de */
1422				if (tcsetpgrp(shell_terminal, getpgrp()) && errno != ENOTTY)
1423					bb_perror_msg("tcsetpgrp");
1424			}
1425#endif
1426		}
1427	}
1428	free(command);
1429
1430#if ENABLE_LASH_JOB_CONTROL
1431	/* return controlling TTY back to parent process group before exiting */
1432	if (tcsetpgrp(shell_terminal, parent_pgrp) && errno != ENOTTY)
1433		bb_perror_msg("tcsetpgrp");
1434#endif
1435
1436	/* return exit status if called with "-c" */
1437	if (input == NULL && WIFEXITED(status))
1438		return WEXITSTATUS(status);
1439
1440	return 0;
1441}
1442
1443#if ENABLE_FEATURE_CLEAN_UP
1444static void free_memory(void)
1445{
1446	free(cwd);
1447
1448	if (job_list.fg && !job_list.fg->running_progs) {
1449		remove_job(&job_list, job_list.fg);
1450	}
1451}
1452#else
1453void free_memory(void);
1454#endif
1455
1456#if ENABLE_LASH_JOB_CONTROL
1457/* Make sure we have a controlling tty.  If we get started under a job
1458 * aware app (like bash for example), make sure we are now in charge so
1459 * we don't fight over who gets the foreground */
1460static void setup_job_control(void)
1461{
1462	int status;
1463	pid_t shell_pgrp;
1464
1465	/* Loop until we are in the foreground.  */
1466	while ((status = tcgetpgrp(shell_terminal)) >= 0) {
1467		shell_pgrp = getpgrp();
1468		if (status == shell_pgrp) {
1469			break;
1470		}
1471		kill(- shell_pgrp, SIGTTIN);
1472	}
1473
1474	/* Ignore interactive and job-control signals.  */
1475	signal(SIGINT, SIG_IGN);
1476	signal(SIGQUIT, SIG_IGN);
1477	signal(SIGTSTP, SIG_IGN);
1478	signal(SIGTTIN, SIG_IGN);
1479	signal(SIGTTOU, SIG_IGN);
1480	signal(SIGCHLD, SIG_IGN);
1481
1482	/* Put ourselves in our own process group.  */
1483	setsid();
1484	shell_pgrp = getpid();
1485	setpgid(shell_pgrp, shell_pgrp);
1486
1487	/* Grab control of the terminal.  */
1488	tcsetpgrp(shell_terminal, shell_pgrp);
1489}
1490#else
1491static inline void setup_job_control(void)
1492{
1493}
1494#endif
1495
1496int lash_main(int argc_l, char **argv_l);
1497int lash_main(int argc_l, char **argv_l)
1498{
1499	unsigned opt;
1500	FILE *input = stdin;
1501	argc = argc_l;
1502	argv = argv_l;
1503
1504#if ENABLE_FEATURE_EDITING
1505	line_input_state = new_line_input_t(FOR_SHELL);
1506#endif
1507
1508	/* These variables need re-initializing when recursing */
1509	last_jobid = 0;
1510	close_me_list = NULL;
1511	job_list.head = NULL;
1512	job_list.fg = NULL;
1513	last_return_code = 1;
1514
1515	if (argv[0] && argv[0][0] == '-') {
1516		FILE *prof_input;
1517		prof_input = fopen("/etc/profile", "r");
1518		if (prof_input) {
1519			llist_add_to(&close_me_list, (void *)(long)fileno(prof_input));
1520			/* Now run the file */
1521			busy_loop(prof_input);
1522			fclose_if_not_stdin(prof_input);
1523			llist_pop(&close_me_list);
1524		}
1525	}
1526
1527	opt = getopt32(argv_l, "+ic:", &local_pending_command);
1528#define LASH_OPT_i (1<<0)
1529#define LASH_OPT_c (1<<1)
1530	if (opt & LASH_OPT_c) {
1531		input = NULL;
1532		optind++;
1533		argv += optind;
1534	}
1535	/* A shell is interactive if the `-i' flag was given, or if all of
1536	 * the following conditions are met:
1537	 *	  no -c command
1538	 *    no arguments remaining or the -s flag given
1539	 *    standard input is a terminal
1540	 *    standard output is a terminal
1541	 *    Refer to Posix.2, the description of the `sh' utility. */
1542	if (argv[optind] == NULL && input == stdin
1543	 && isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)
1544	) {
1545		opt |= LASH_OPT_i;
1546	}
1547	setup_job_control();
1548	if (opt & LASH_OPT_i) {
1549		/* Looks like they want an interactive shell */
1550		if (!ENABLE_FEATURE_SH_EXTRA_QUIET) {
1551			printf("\n\n%s built-in shell (lash)\n"
1552					"Enter 'help' for a list of built-in commands.\n\n",
1553					bb_banner);
1554		}
1555	} else if (!local_pending_command && argv[optind]) {
1556		//printf( "optind=%d  argv[optind]='%s'\n", optind, argv[optind]);
1557		input = xfopen(argv[optind], "r");
1558		/* be lazy, never mark this closed */
1559		llist_add_to(&close_me_list, (void *)(long)fileno(input));
1560	}
1561
1562	/* initialize the cwd -- this is never freed...*/
1563	update_cwd();
1564
1565	if (ENABLE_FEATURE_CLEAN_UP) atexit(free_memory);
1566
1567	if (ENABLE_FEATURE_EDITING) cmdedit_set_initial_prompt();
1568	else PS1 = NULL;
1569
1570	return busy_loop(input);
1571}
1572