/// Execute a builtin command proc_status_t builtin_run(parser_t &parser, int job_pgid, wchar_t **argv, io_streams_t &streams) { UNUSED(parser); UNUSED(streams); if (argv == NULL || argv[0] == NULL) return proc_status_t::from_exit_code(STATUS_INVALID_ARGS); // We can be handed a keyword by the parser as if it was a command. This happens when the user // follows the keyword by `-h` or `--help`. Since it isn't really a builtin command we need to // handle displaying help for it here. if (argv[1] && !argv[2] && parse_util_argument_is_help(argv[1]) && cmd_needs_help(argv[0])) { builtin_print_help(parser, streams, argv[0], streams.out); return proc_status_t::from_exit_code(STATUS_CMD_OK); } if (const builtin_data_t *data = builtin_lookup(argv[0])) { // If we are interactive, save the foreground pgroup and restore it after in case the // builtin needs to read from the terminal. See #4540. bool grab_tty = is_interactive_session && isatty(streams.stdin_fd); pid_t pgroup_to_restore = grab_tty ? terminal_acquire_before_builtin(job_pgid) : -1; int ret = data->func(parser, streams, argv); if (pgroup_to_restore >= 0) { tcsetpgrp(STDIN_FILENO, pgroup_to_restore); } return proc_status_t::from_exit_code(ret); } debug(0, UNKNOWN_BUILTIN_ERR_MSG, argv[0]); return proc_status_t::from_exit_code(STATUS_CMD_ERROR); }
static int ast_do_simple( int line, int argc, char **argv, int fds[3], time_t stoptime ) { char *cmd; int length=0; int i; for( i=0; i<argc; i++ ) { length+=strlen(argv[i])+1; } cmd = xxmalloc(length+1); cmd[0] = 0; for( i=0; i<argc; i++ ) { strcat(cmd,argv[i]); strcat(cmd," "); } ftsh_error(FTSH_ERROR_COMMAND,line,"%s",cmd); free(cmd); if(hash_table_lookup(ftable,argv[0]) || builtin_lookup(argv[0]) ) { return ast_do_internal(line,argc,argv,fds,stoptime); } else { return ast_do_external(line,argc,argv,fds,stoptime); } }
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; }
/// Return a one-line description of the specified builtin. const wchar_t *builtin_get_desc(const wcstring &name) { const wchar_t *result = L""; const builtin_data_t *builtin = builtin_lookup(name); if (builtin) { result = _(builtin->desc); } return result; }
int builtin_help(shell_t* sh, int argc, const char* argv[]) { if (argc == 2) { builtin_t* b = builtin_lookup(argv[1], BFLAG_NONE); if (!b) { printf("no such command '%s'\n", argv[1]); } else { printf("%s %s\n", b->command, b->help); } } else { printf("commands: \n"); builtin_foreach(help_helper); printf("\n"); } return 0; }
int builtin_builtin(shell_t* sh, int argc, const char** argv) { if (argc < 2) { fprintf(stderr, "usage: builtin <cmd> (on|off)\n"); return -1; } builtin_t* b = builtin_lookup(argv[1], BFLAG_NONE); if (!b) { fprintf(stderr, "no such builtin: %s\n", argv[1]); return -1; } if (argc < 3) { printf("builtin %s is currently %sabled\n", argv[1], b->flags & BFLAG_ENABLED ? "en" : "dis"); return 0; } bool enable = !strcmp(argv[2], "on"); if (enable && b->flags & BFLAG_ENABLED) { fprintf(stderr, "builtin %s is already enabled\n", argv[1]); return -1; } if (!enable && !(b->flags & BFLAG_ENABLED)) { fprintf(stderr, "builtin %s is already disabled\n", argv[1]); return -1; } if (enable) { b->flags |= BFLAG_ENABLED; printf("now using builtin %s\n", argv[1]); } else { b->flags &= ~(BFLAG_ENABLED); printf("no longer using builtin %s\n", argv[1]); } return 0; }
const builtin_s *builtin_find( const char *service_name, int type ) { const builtin_s *bsp ; const char *func = "builtin_find" ; if ( (bsp = builtin_lookup( builtin_services, service_name, type )) ) return( bsp ) ; else { const char *type_name; const struct name_value *sock_type = nv_find_name( socket_types, type ); if (sock_type == NULL) type_name = "Unknown socket type"; else type_name = sock_type->name; msg( LOG_ERR, func, "No such internal service: %s/%s - DISABLING", service_name, type_name ) ; return( NULL ) ; } }
/// Is there a builtin command with the given name? bool builtin_exists(const wcstring &cmd) { return static_cast<bool>(builtin_lookup(cmd)); }
static void try_fold_cast(tree_t node, tree_t *pp1) { typeinfo_t tdst; typeinfo_t tsrc; int isrc, idst; c_value_t vout, tval; int stat; tree_t psrc; ASSERT(node); ASSERT(node->kind == NODE_EXPRCAST); if (!pp1) return; tdst = sema_get_expr_type(node); psrc = node->node.refs[6]; if (!psrc) return; if (psrc->kind == NODE_EXPRSTRING) { // if cast to another char * type, ignore it if (tdst->tag != CPT_POINTER) return; if (!sema_is_character_type(tdst->t_pointer.type)) return; psrc->node.sema = sinfo_create_type(tdst); *pp1 = psrc; psrc->node.refs[0] = node->node.refs[0]; return; } if (psrc->kind == NODE_EXPRIDENT && builtin_lookup(psrc->node.refs[3]->id.id) == C_BUILTIN_FUNCTION) { if (tdst->tag != CPT_POINTER) return; if (!sema_is_character_type(tdst->t_pointer.type)) return; psrc->node.sema = sinfo_create_type(tdst); *pp1 = psrc; psrc->node.refs[0] = node->node.refs[0]; return; } if (psrc->kind != NODE_EXPRCONST) return; tsrc = sema_get_expr_type(psrc); memset(&vout, 0, sizeof(vout)); if (tdst->tag == CPT_POINTER && tsrc->tag == CPT_POINTER) { tval = psrc->node.refs[3]->val.val; // FIXME: this is ugly hack, because c_value lacks NULL pointer checks tval.tag = C_INT; if (!c_value_is_zero(&tval)) return; vout.tag = C_POINTER; } else if (tdst->tag == CPT_POINTER && tsrc->tag == CPT_ARITH && c_value_is_zero(&psrc->node.refs[3]->val.val)) { vout.tag = C_POINTER; } else if (tdst->tag == CPT_ARITH && tsrc->tag == CPT_ARITH) { isrc = sema_typeinfo_to_index(tsrc); ASSERT(isrc >= C_FIRST_ARITH && isrc <= C_LAST_ARITH); idst = sema_typeinfo_to_index(tdst); ASSERT(idst >= C_FIRST_ARITH && idst <= C_LAST_ARITH); stat = c_value_cast(&psrc->node.refs[3]->val.val, idst, &vout); (void) stat; } else { return; } psrc->node.refs[3]->val.val = vout; psrc->node.sema = sinfo_create_type(tdst); *pp1 = psrc; psrc->node.refs[0] = node->node.refs[0]; }