?? hush.c
字號:
}/* built-in 'cd <path>' handler */static int builtin_cd(struct child_prog *child){ char *newdir; if (child->argv[1] == NULL) newdir = getenv("HOME"); else newdir = child->argv[1]; if (chdir(newdir)) { printf("cd: %s: %s\n", newdir, strerror(errno)); return EXIT_FAILURE; } set_cwd(); return EXIT_SUCCESS;}/* built-in 'env' handler */static int builtin_env(struct child_prog *dummy){ char **e = environ; if (e == NULL) return EXIT_FAILURE; for (; *e; e++) { puts(*e); } return EXIT_SUCCESS;}/* built-in 'exec' handler */static int builtin_exec(struct child_prog *child){ if (child->argv[1] == NULL) return EXIT_SUCCESS; /* Really? */ child->argv++; pseudo_exec(child); /* never returns */}/* built-in 'exit' handler */static int builtin_exit(struct child_prog *child){ if (child->argv[1] == NULL) exit(last_return_code); exit (atoi(child->argv[1]));}/* built-in 'export VAR=value' handler */static int builtin_export(struct child_prog *child){ int res = 0; char *name = child->argv[1]; if (name == NULL) { return (builtin_env(child)); } name = strdup(name); if(name) { char *value = strchr(name, '='); if (!value) { char *tmp; /* They are exporting something without an =VALUE */ value = get_local_var(name); if (value) { size_t ln = strlen(name); tmp = realloc(name, ln+strlen(value)+2); if(tmp==NULL) res = -1; else { sprintf(tmp+ln, "=%s", value); name = tmp; } } else { /* bash does not return an error when trying to export * an undefined variable. Do likewise. */ res = 1; } } } if (res<0) perror_msg("export"); else if(res==0) res = set_local_var(name, 1); else res = 0; free(name); return res;}/* built-in 'fg' and 'bg' handler */static int builtin_fg_bg(struct child_prog *child){ int i, jobnum; struct pipe *pi=NULL; if (!interactive) return EXIT_FAILURE; /* If they gave us no args, assume they want the last backgrounded task */ if (!child->argv[1]) { for (pi = job_list; pi; pi = pi->next) { if (pi->jobid == last_jobid) { break; } } if (!pi) { error_msg("%s: no current job", child->argv[0]); return EXIT_FAILURE; } } else { if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) { error_msg("%s: bad argument '%s'", child->argv[0], child->argv[1]); return EXIT_FAILURE; } for (pi = job_list; pi; pi = pi->next) { if (pi->jobid == jobnum) { break; } } if (!pi) { error_msg("%s: %d: no such job", child->argv[0], jobnum); return EXIT_FAILURE; } } if (*child->argv[0] == 'f') { /* Put the job into the foreground. */ tcsetpgrp(shell_terminal, pi->pgrp); } /* Restart the processes in the job */ for (i = 0; i < pi->num_progs; i++) pi->progs[i].is_stopped = 0; if ( (i=kill(- pi->pgrp, SIGCONT)) < 0) { if (i == ESRCH) { remove_bg_job(pi); } else { perror_msg("kill (SIGCONT)"); } } pi->stopped_progs = 0; return EXIT_SUCCESS;}/* built-in 'help' handler */static int builtin_help(struct child_prog *dummy){ struct built_in_command *x; printf("\nBuilt-in commands:\n"); printf("-------------------\n"); for (x = bltins; x->cmd; x++) { if (x->descr==NULL) continue; printf("%s\t%s\n", x->cmd, x->descr); } printf("\n\n"); return EXIT_SUCCESS;}/* built-in 'jobs' handler */static int builtin_jobs(struct child_prog *child){ struct pipe *job; char *status_string; for (job = job_list; job; job = job->next) { if (job->running_progs == job->stopped_progs) status_string = "Stopped"; else status_string = "Running"; printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text); } return EXIT_SUCCESS;}/* built-in 'pwd' handler */static int builtin_pwd(struct child_prog *dummy){ puts(set_cwd()); return EXIT_SUCCESS;}/* built-in 'read VAR' handler */static int builtin_read(struct child_prog *child){ int res; if (child->argv[1]) { char string[BUFSIZ]; char *var = 0; string[0] = 0; /* In case stdin has only EOF */ /* read string */ fgets(string, sizeof(string), stdin); chomp(string); var = malloc(strlen(child->argv[1])+strlen(string)+2); if(var) { sprintf(var, "%s=%s", child->argv[1], string); res = set_local_var(var, 0); } else res = -1; if (res) fprintf(stderr, "read: %m\n"); free(var); /* So not move up to avoid breaking errno */ return res; } else { do res=getchar(); while(res!='\n' && res!=EOF); return 0; }}/* built-in 'set VAR=value' handler */static int builtin_set(struct child_prog *child){ char *temp = child->argv[1]; struct variables *e; if (temp == NULL) for(e = top_vars; e; e=e->next) printf("%s=%s\n", e->name, e->value); else set_local_var(temp, 0); return EXIT_SUCCESS;}/* Built-in 'shift' handler */static int builtin_shift(struct child_prog *child){ int n=1; if (child->argv[1]) { n=atoi(child->argv[1]); } if (n>=0 && n<global_argc) { /* XXX This probably breaks $0 */ global_argc -= n; global_argv += n; return EXIT_SUCCESS; } else { return EXIT_FAILURE; }}/* Built-in '.' handler (read-in and execute commands from file) */static int builtin_source(struct child_prog *child){ FILE *input; int status; if (child->argv[1] == NULL) return EXIT_FAILURE; /* XXX search through $PATH is missing */ input = fopen(child->argv[1], "r"); if (!input) { error_msg("Couldn't open file '%s'", child->argv[1]); return EXIT_FAILURE; } /* Now run the file */ /* XXX argv and argc are broken; need to save old global_argv * (pointer only is OK!) on this stack frame, * set global_argv=child->argv+1, recurse, and restore. */ mark_open(fileno(input)); status = parse_file_outer(input); mark_closed(fileno(input)); fclose(input); return (status);}static int builtin_umask(struct child_prog *child){ mode_t new_umask; const char *arg = child->argv[1]; char *end; if (arg) { new_umask=strtoul(arg, &end, 8); if (*end!='\0' || end == arg) { return EXIT_FAILURE; } } else { printf("%.3o\n", (unsigned int) (new_umask=umask(0))); } umask(new_umask); return EXIT_SUCCESS;}/* built-in 'unset VAR' handler */static int builtin_unset(struct child_prog *child){ /* bash returned already true */ unset_local_var(child->argv[1]); return EXIT_SUCCESS;}static int builtin_not_written(struct child_prog *child){ printf("builtin_%s not written\n",child->argv[0]); return EXIT_FAILURE;}static int b_check_space(o_string *o, int len){ /* It would be easy to drop a more restrictive policy * in here, such as setting a maximum string length */ if (o->length + len > o->maxlen) { char *old_data = o->data; /* assert (data == NULL || o->maxlen != 0); */ o->maxlen += max(2*len, B_CHUNK); o->data = realloc(o->data, 1 + o->maxlen); if (o->data == NULL) { free(old_data); } } return o->data == NULL;}static int b_addchr(o_string *o, int ch){ debug_printf("b_addchr: %c %d %p\n", ch, o->length, o); if (b_check_space(o, 1)) return B_NOSPAC; o->data[o->length] = ch; o->length++; o->data[o->length] = '\0'; return 0;}static void b_reset(o_string *o){ o->length = 0; o->nonnull = 0; if (o->data != NULL) *o->data = '\0';}static void b_free(o_string *o){ b_reset(o); if (o->data != NULL) free(o->data); o->data = NULL; o->maxlen = 0;}/* My analysis of quoting semantics tells me that state information * is associated with a destination, not a source. */static int b_addqchr(o_string *o, int ch, int quote){ if (quote && strchr("*?[\\",ch)) { int rc; rc = b_addchr(o, '\\'); if (rc) return rc; } return b_addchr(o, ch);}/* belongs in utility.c */char *simple_itoa(unsigned int i){ /* 21 digits plus null terminator, good for 64-bit or smaller ints */ static char local[22]; char *p = &local[21]; *p-- = '\0'; do { *p-- = '0' + i % 10; i /= 10; } while (i > 0); return p + 1;}static int b_adduint(o_string *o, unsigned int i){ int r; char *p = simple_itoa(i); /* no escape checking necessary */ do r=b_addchr(o, *p++); while (r==0 && *p); return r;}static int static_get(struct in_str *i){ int ch=*i->p++; if (ch=='\0') return EOF; return ch;}static int static_peek(struct in_str *i){ return *i->p;}static inline void cmdedit_set_initial_prompt(void){#ifndef BB_FEATURE_SH_FANCY_PROMPT PS1 = NULL;#else PS1 = getenv("PS1"); if(PS1==0) PS1 = "\\w \\$ ";#endif }static inline void setup_prompt_string(int promptmode, char **prompt_str){ debug_printf("setup_prompt_string %d ",promptmode);#ifndef BB_FEATURE_SH_FANCY_PROMPT /* Set up the prompt */ if (promptmode == 1) { if (PS1) 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);}static void get_user_input(struct in_str *i){ char *prompt_str; static char the_command[BUFSIZ]; setup_prompt_string(i->promptmode, &prompt_str);#ifdef BB_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;}/* 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 {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -