static int ast_do_internal( int line, int argc, char **argv, int fds[3], time_t stoptime ) { struct ast_function *f; builtin_func_t b; int oldfds[3]; int result=0; f = hash_table_lookup(ftable,argv[0]); b = builtin_lookup(argv[0]); if(f) ftsh_error(FTSH_ERROR_STRUCTURE,f->function_line,"FUNCTION %s",f->name->text); if(b || variable_frame_push(f->function_line,argc,argv)) { if(fds[0]!=0) { oldfds[0] = dup(0); if(oldfds[0]<0) ftsh_fatal(line,"out of file descriptors"); dup2(fds[0],0); } if(fds[1]!=1) { oldfds[1] = dup(1); if(oldfds[1]<0) ftsh_fatal(line,"out of file descriptors"); dup2(fds[1],1); } if(fds[2]!=2) { oldfds[2] = dup(2); if(oldfds[2]<0) ftsh_fatal(line,"out of file descriptors"); dup2(fds[2],2); } if(f) { result = ast_group_execute(f->body,stoptime); } else { result = b(line,argc,argv,stoptime); } if(fds[2]!=2) { dup2(oldfds[2],2); close(oldfds[2]); } if(fds[1]!=1) { dup2(oldfds[1],1); close(oldfds[1]); } if(fds[0]!=0) { dup2(oldfds[0],0); close(oldfds[0]); } if(f) variable_frame_pop(); } if(f) ftsh_error(FTSH_ERROR_STRUCTURE,f->end_line,"END"); return result; }
int ast_program_execute( struct ast_group *program, time_t stoptime ) { struct ast_group *g; struct ast_function *f, *old; /* First, fill up the function table with all of the functions in this entire syntax tree. */ ftable = hash_table_create(127,hash_string); if(!ftable) ftsh_fatal(0,"out of memory"); for( g=program; g; g=g->next ) { if(g->command->type==AST_COMMAND_FUNCTION) { f = g->command->u.function; old = hash_table_remove(ftable,f->name->text); if(old) { ftsh_error(FTSH_ERROR_SYNTAX,f->function_line,"function %s is defined twice (first at line %d)",f->name->text,old->function_line); return 0; } if(!hash_table_insert(ftable,f->name->text,f)) { ftsh_fatal(f->function_line,"out of memory"); } } } return ast_group_execute(program,stoptime); }
static char * variable_get( const char *name, int line, int withquotes ) { char buffer[100]; int arg; if(!strcmp(name,"$")) { sprintf(buffer,"%d",(int)getpid()); return xxstrdup(buffer); } else if(!strcmp(name,"#")) { sprintf(buffer,"%d",head->argc-1); return xxstrdup(buffer); } else if(!strcmp(name,"@")) { return variable_print_argv(withquotes); } else if(!strcmp(name,"*")) { return variable_print_argv(0); } else if( sscanf(name,"%d",&arg)==1 ) { if(arg>=head->argc) { return xxstrdup(""); } else { return xxstrdup(head->argv[arg]); } } else if( isvalid(name) ) { char *result = getenv(name); if(result) return xxstrdup(result); result = buffer_load(name); if(result) string_chomp(result); return result; } else { ftsh_fatal(line,"${%s} is an invalid variable name!",name); return 0; } }
void variable_frame_pop() { struct vstack *v; v = head; if(!v || !v->next ) { ftsh_fatal(0,"stack underflow"); } head = v->next; free(v); vstackdepth--; }