⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hush.c

📁 uboot详细解读可用启动引导LINUX2.6内核
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifndef CONFIG_FEATURE_SH_FANCY_PROMPT	/* Set up the prompt */	if (promptmode == 1) {		free(PS1);		PS1=xmalloc(strlen(cwd)+4);		sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ?  "$ ":"# ");		*prompt_str = PS1;	} else {		*prompt_str = PS2;	}#else	*prompt_str = (promptmode==1)? PS1 : PS2;#endif	debug_printf("result %s\n",*prompt_str);}#endifstatic void get_user_input(struct in_str *i){#ifndef __U_BOOT__	char *prompt_str;	static char the_command[BUFSIZ];	setup_prompt_string(i->promptmode, &prompt_str);#ifdef CONFIG_FEATURE_COMMAND_EDITING	/*	 ** enable command line editing only while a command line	 ** is actually being read; otherwise, we'll end up bequeathing	 ** atexit() handlers and other unwanted stuff to our	 ** child processes (rob@sysgo.de)	 */	cmdedit_read_input(prompt_str, the_command);#else	fputs(prompt_str, stdout);	fflush(stdout);	the_command[0]=fgetc(i->file);	the_command[1]='\0';#endif	fflush(stdout);	i->p = the_command;#else	extern char console_buffer[CFG_CBSIZE];	int n;	static char the_command[CFG_CBSIZE];#ifdef CONFIG_BOOT_RETRY_TIME#  ifdef CONFIG_RESET_TO_RETRY	extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);#  else#	error "This currently only works with CONFIG_RESET_TO_RETRY enabled"#  endif	reset_cmd_timeout();#endif	i->__promptme = 1;	if (i->promptmode == 1) {		n = readline(CFG_PROMPT);	} else {		n = readline(CFG_PROMPT_HUSH_PS2);	}#ifdef CONFIG_BOOT_RETRY_TIME	if (n == -2) {	  puts("\nTimeout waiting for command\n");#  ifdef CONFIG_RESET_TO_RETRY	  do_reset(NULL, 0, 0, NULL);#  else#	error "This currently only works with CONFIG_RESET_TO_RETRY enabled"#  endif	}#endif	if (n == -1 ) {		flag_repeat = 0;		i->__promptme = 0;	}	n = strlen(console_buffer);	console_buffer[n] = '\n';	console_buffer[n+1]= '\0';	if (had_ctrlc()) flag_repeat = 0;	clear_ctrlc();	do_repeat = 0;	if (i->promptmode == 1) {		if (console_buffer[0] == '\n'&& flag_repeat == 0) {			strcpy(the_command,console_buffer);		}		else {			if (console_buffer[0] != '\n') {				strcpy(the_command,console_buffer);				flag_repeat = 1;			}			else {				do_repeat = 1;			}		}		i->p = the_command;	}	else {		if (console_buffer[0] != '\n') {			if (strlen(the_command) + strlen(console_buffer)			    < CFG_CBSIZE) {				n = strlen(the_command);				the_command[n-1] = ' ';				strcpy(&the_command[n],console_buffer);			}			else {				the_command[0] = '\n';				the_command[1] = '\0';				flag_repeat = 0;			}		}		if (i->__promptme == 0) {			the_command[0] = '\n';			the_command[1] = '\0';		}		i->p = console_buffer;	}#endif}/* This is the magic location that prints prompts * and gets data back from the user */static int file_get(struct in_str *i){	int ch;	ch = 0;	/* If there is data waiting, eat it up */	if (i->p && *i->p) {		ch = *i->p++;	} else {		/* need to double check i->file because we might be doing something		 * more complicated by now, like sourcing or substituting. */#ifndef __U_BOOT__		if (i->__promptme && interactive && i->file == stdin) {			while(! i->p || (interactive && strlen(i->p)==0) ) {#else			while(! i->p  || strlen(i->p)==0 ) {#endif				get_user_input(i);			}			i->promptmode=2;#ifndef __U_BOOT__			i->__promptme = 0;#endif			if (i->p && *i->p) {				ch = *i->p++;			}#ifndef __U_BOOT__		} else {			ch = fgetc(i->file);		}#endif		debug_printf("b_getch: got a %d\n", ch);	}#ifndef __U_BOOT__	if (ch == '\n') i->__promptme=1;#endif	return ch;}/* All the callers guarantee this routine will never be * used right after a newline, so prompting is not needed. */static int file_peek(struct in_str *i){#ifndef __U_BOOT__	if (i->p && *i->p) {#endif		return *i->p;#ifndef __U_BOOT__	} else {		i->peek_buf[0] = fgetc(i->file);		i->peek_buf[1] = '\0';		i->p = i->peek_buf;		debug_printf("b_peek: got a %d\n", *i->p);		return *i->p;	}#endif}#ifndef __U_BOOT__static void setup_file_in_str(struct in_str *i, FILE *f)#elsestatic void setup_file_in_str(struct in_str *i)#endif{	i->peek = file_peek;	i->get = file_get;	i->__promptme=1;	i->promptmode=1;#ifndef __U_BOOT__	i->file = f;#endif	i->p = NULL;}static void setup_string_in_str(struct in_str *i, const char *s){	i->peek = static_peek;	i->get = static_get;	i->__promptme=1;	i->promptmode=1;	i->p = s;}#ifndef __U_BOOT__static void mark_open(int fd){	struct close_me *new = xmalloc(sizeof(struct close_me));	new->fd = fd;	new->next = close_me_head;	close_me_head = new;}static void mark_closed(int fd){	struct close_me *tmp;	if (close_me_head == NULL || close_me_head->fd != fd)		error_msg_and_die("corrupt close_me");	tmp = close_me_head;	close_me_head = close_me_head->next;	free(tmp);}static void close_all(void){	struct close_me *c;	for (c=close_me_head; c; c=c->next) {		close(c->fd);	}	close_me_head = NULL;}/* squirrel != NULL means we squirrel away copies of stdin, stdout, * and stderr if they are redirected. */static int setup_redirects(struct child_prog *prog, int squirrel[]){	int openfd, mode;	struct redir_struct *redir;	for (redir=prog->redirects; redir; redir=redir->next) {		if (redir->dup == -1 && redir->word.gl_pathv == NULL) {			/* something went wrong in the parse.  Pretend it didn't happen */			continue;		}		if (redir->dup == -1) {			mode=redir_table[redir->type].mode;			openfd = open(redir->word.gl_pathv[0], mode, 0666);			if (openfd < 0) {			/* this could get lost if stderr has been redirected, but			   bash and ash both lose it as well (though zsh doesn't!) */				perror_msg("error opening %s", redir->word.gl_pathv[0]);				return 1;			}		} else {			openfd = redir->dup;		}		if (openfd != redir->fd) {			if (squirrel && redir->fd < 3) {				squirrel[redir->fd] = dup(redir->fd);			}			if (openfd == -3) {				close(openfd);			} else {				dup2(openfd, redir->fd);				if (redir->dup == -1)					close (openfd);			}		}	}	return 0;}static void restore_redirects(int squirrel[]){	int i, fd;	for (i=0; i<3; i++) {		fd = squirrel[i];		if (fd != -1) {			/* No error checking.  I sure wouldn't know what			 * to do with an error if I found one! */			dup2(fd, i);			close(fd);		}	}}/* never returns *//* XXX no exit() here.  If you don't exec, use _exit instead. * The at_exit handlers apparently confuse the calling process, * in particular stdin handling.  Not sure why? */static void pseudo_exec(struct child_prog *child){	int i, rcode;	char *p;	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]);			p = insert_var_value(child->argv[i]);			putenv(strdup(p));			if (p != child->argv[i]) free(p);		}		child->argv+=i;  /* XXX this hack isn't so horrible, since we are about					to exit, and therefore don't need to keep data					structures consistent for free() use. */		/* If a variable is assigned in a forest, and nobody listens,		 * was it ever really set?		 */		if (child->argv[0] == NULL) {			_exit(EXIT_SUCCESS);		}		/*		 * Check if the command matches any of the builtins.		 * Depending on context, this might be redundant.  But it's		 * easier to waste a few CPU cycles than it is to figure out		 * if this is one of those cases.		 */		for (x = bltins; x->cmd; x++) {			if (strcmp(child->argv[0], x->cmd) == 0 ) {				debug_printf("builtin exec %s\n", child->argv[0]);				rcode = x->function(child);				fflush(stdout);				_exit(rcode);			}		}		/* Check if the command matches any busybox internal commands		 * ("applets") here.		 * FIXME: This feature is not 100% safe, since		 * BusyBox is not fully reentrant, so we have no guarantee the things		 * from the .bss are still zeroed, or that things from .data are still		 * at their defaults.  We could exec ourself from /proc/self/exe, but I		 * really dislike relying on /proc for things.  We could exec ourself		 * from global_argv[0], but if we are in a chroot, we may not be able		 * to find ourself... */#ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL		{			int argc_l;			char** argv_l=child->argv;			char *name = child->argv[0];#ifdef CONFIG_FEATURE_SH_APPLETS_ALWAYS_WIN			/* Following discussions from November 2000 on the busybox mailing			 * list, the default configuration, (without			 * get_last_path_component()) lets the user force use of an			 * external command by specifying the full (with slashes) filename.			 * If you enable CONFIG_FEATURE_SH_APPLETS_ALWAYS_WIN then applets			 * _aways_ override external commands, so if you want to run			 * /bin/cat, it will use BusyBox cat even if /bin/cat exists on the			 * filesystem and is _not_ busybox.  Some systems may want this,			 * most do not.  */			name = get_last_path_component(name);#endif			/* Count argc for use in a second... */			for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);			optind = 1;			debug_printf("running applet %s\n", name);			run_applet_by_name(name, argc_l, child->argv);		}#endif		debug_printf("exec of %s\n",child->argv[0]);		execvp(child->argv[0],child->argv);		perror_msg("couldn't exec: %s",child->argv[0]);		_exit(1);	} else if (child->group) {		debug_printf("runtime nesting to group\n");		interactive=0;    /* crucial!!!! */		rcode = run_list_real(child->group);		/* OK to leak memory by not calling free_pipe_list,		 * since this process is about to exit */		_exit(rcode);	} else {		/* Can happen.  See what bash does with ">foo" by itself. */		debug_printf("trying to pseudo_exec null command\n");		_exit(EXIT_SUCCESS);	}}static void insert_bg_job(struct pipe *pi){	struct pipe *thejob;	/* Linear search for the ID of the job to use */	pi->jobid = 1;	for (thejob = job_list; thejob; thejob = thejob->next)		if (thejob->jobid >= pi->jobid)			pi->jobid = thejob->jobid + 1;	/* add thejob to the list of running jobs */	if (!job_list) {		thejob = job_list = xmalloc(sizeof(*thejob));	} else {		for (thejob = job_list; thejob->next; thejob = thejob->next) /* nothing */;		thejob->next = xmalloc(sizeof(*thejob));		thejob = thejob->next;	}	/* physically copy the struct job */	memcpy(thejob, pi, sizeof(struct pipe));	thejob->next = NULL;	thejob->running_progs = thejob->num_progs;	thejob->stopped_progs = 0;	thejob->text = xmalloc(BUFSIZ); /* cmdedit buffer size */	/*if (pi->progs[0] && pi->progs[0].argv && pi->progs[0].argv[0]) */	{		char *bar=thejob->text;		char **foo=pi->progs[0].argv;		while(foo && *foo) {			bar += sprintf(bar, "%s ", *foo++);		}	}	/* we don't wait for background thejobs to return -- append it	   to the list of backgrounded thejobs and leave it alone */	printf("[%d] %d\n", thejob->jobid, thejob->progs[0].pid);	last_bg_pid = thejob->progs[0].pid;	last_jobid = thejob->jobid;}/* remove a backgrounded job */static void remove_bg_job(struct pipe *pi){	struct pipe *prev_pipe;	if (pi == job_list) {		job_list = pi->next;	} else {		prev_pipe = job_list;		while (prev_pipe->next != pi)			prev_pipe = prev_pipe->next;		prev_pipe->next = pi->next;	}	if (job_list)		last_jobid = job_list->jobid;	else		last_jobid = 0;	pi->stopped_progs = 0;	free_pipe(pi, 0);	free(pi);}/* Checks to see if any processes have exited -- if they   have, figure out why and see if a job has completed */static int checkjobs(struct pipe* fg_pipe){	int attributes;	int status;	int prognum = 0;	struct pipe *pi;	pid_t childpid;	attributes = WUNTRACED;	if (fg_pipe==NULL) {		attributes |= WNOHANG;	}	while ((childpid = waitpid(-1, &status, attributes)) > 0) {		if (fg_pipe) {			int i, rcode = 0;			for (i=0; i < fg_pipe->num_progs; i++) {				if (fg_pipe->progs[i].pid == childpid) {					if (i==fg_pipe->num_progs-1)						rcode=WEXITSTATUS(status);					(fg_pipe->num_progs)--;					return(rcode);				}			}		}		for (pi = job_list; pi; pi = pi->next) {			prognum = 0;			while (prognum < pi->num_progs && pi->progs[prognum].pid != childpid) {				prognum++;			}			if (prognum < pi->num_progs)				break;		}		if(pi==NULL) {			debug_printf("checkjobs: pid %d was not in our list!\n", childpid);			continue;		}		if (WIFEXITED(status) || WIFSIGNALED(status)) {			/* child exited */			pi->running_progs--;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -