/** * execute a procedure */ int sblmgr_procexec(int lib_id, int index) { #if defined(LNX_EXTLIB) || defined(WIN_EXTLIB) slib_t *lib; var_t ret; slib_par_t *ptable = NULL; int (*pexec) (int, int, slib_par_t *, var_t *); int pcount = 0; int success = 0; if (lib_id < 0 || lib_id >= slib_count) { return 0; } lib = &slib_table[lib_id]; pexec = slib_getoptptr(lib, "sblib_proc_exec"); if (pexec == NULL) { return 0; } // build parameter table ptable = malloc(sizeof(slib_par_t) * MAX_PARAM); pcount = slib_build_ptable(ptable); if (prog_error) { slib_free_ptable(ptable, pcount); free(ptable); return 0; } // exec v_init(&ret); success = pexec(index - lib->first_proc, pcount, ptable, &ret); // error if (!success) { if (ret.type == V_STR) { err_throw("lib:%s: %s\n", lib->name, ret.v.p.ptr); } else { err_throw("lib:%s: Unspecified error\n", lib->name); } } // clean-up if (ptable) { slib_free_ptable(ptable, pcount); free(ptable); } v_free(&ret); return success; #else return 0; #endif }
int prun(FAR char *exepath, size_t varsize, size_t strsize) { FAR struct pexec_s *st; int errcode; int ret = OK; /* Load the POFF file into memory */ st = pload(exepath, varsize, varsize); if (!st) { bdbg("ERROR: Could not load %s\n", exepath); return -ENOEXEC; } bvdbg("Loaded %s\n", exepath); /* Execute the P-Code program until a stopping condition occurs */ for (;;) { /* Execute the instruction; Check for exceptional conditions */ errcode = pexec(st); if (errcode != eNOERROR) { break; } } if (errcode != eEXIT) { /* REVISIT: Select a more appropriated return errocode */ bdbg("ERROR: Runtime error 0x%02x -- Execution Stopped\n", errcode); ret = -ENOEXEC; } /* Clean up resources used by the interpreter */ bvdbg("Execution terminated\n"); pexec_release(st); return ret; }
/* * Execute the shell command tree pointed to by t. */ static void execute(struct tnode *t, int *pin, int *pout) { struct tnode *t1; enum tnflags f; pid_t cpid; int i, pfd[2]; const char **gav; const char *cmd, *p; if (t == NULL) return; switch (t->ntype) { case TLIST: f = t->nflags & (FFIN | FPIN | FINTR); if ((t1 = t->nleft) != NULL) t1->nflags |= f; execute(t1, NULL, NULL); if ((t1 = t->nright) != NULL) t1->nflags |= f; execute(t1, NULL, NULL); return; case TPIPE: if (pipe(pfd) == -1) { err(SH_ERR, FMT1S, ERR_PIPE); if (pin != NULL) { (void)close(pin[0]); (void)close(pin[1]); } return; } f = t->nflags; if ((t1 = t->nleft) != NULL) t1->nflags |= FPOUT | (f & (FFIN|FPIN|FINTR|FPRS)); execute(t1, pin, pfd); if ((t1 = t->nright) != NULL) t1->nflags |= FPIN | (f & (FAND|FPOUT|FINTR|FPRS)); execute(t1, pfd, pout); (void)close(pfd[0]); (void)close(pfd[1]); return; case TCOMMAND: if (t->nav == NULL || t->nav[0] == NULL) { /* should never (but can) be true */ err(SH_ERR, FMT1S, "execute: Invalid command"); return; } cmd = t->nav[0]; if (EQUAL(cmd, ":")) { status = SH_TRUE; return; } if (EQUAL(cmd, "chdir")) { ascan(t->nav[1], &trim); if (t->nav[1] == NULL) err(SH_ERR, FMT2S, cmd, ERR_ARGCOUNT); else if (chdir(t->nav[1]) == -1) err(SH_ERR, FMT2S, cmd, ERR_BADDIR); else status = SH_TRUE; return; } if (EQUAL(cmd, "exit")) { if (prompt == NULL) { (void)lseek(FD0, (off_t)0, SEEK_END); EXIT(status); } return; } if (EQUAL(cmd, "login") || EQUAL(cmd, "newgrp")) { if (prompt != NULL) { p = (*cmd == 'l') ? PATH_LOGIN : PATH_NEWGRP; vscan(t->nav, &trim); (void)sasignal(SIGINT, SIG_DFL); (void)sasignal(SIGQUIT, SIG_DFL); (void)pexec(p, (char *const *)t->nav); (void)sasignal(SIGINT, SIG_IGN); (void)sasignal(SIGQUIT, SIG_IGN); } err(SH_ERR, FMT2S, cmd, ERR_EXEC); return; } if (EQUAL(cmd, "shift")) { if (dolc > 1) { dolv = &dolv[1]; dolc--; status = SH_TRUE; return; } err(SH_ERR, FMT2S, cmd, ERR_NOARGS); return; } if (EQUAL(cmd, "wait")) { pwait(-1); return; } /*FALLTHROUGH*/ case TSUBSHELL: f = t->nflags; if ((cpid = ((f & FNOFORK) != 0) ? 0 : fork()) == -1) { err(SH_ERR, FMT1S, ERR_FORK); return; } /**** Parent! ****/ if (cpid != 0) { if (pin != NULL && (f & FPIN) != 0) { (void)close(pin[0]); (void)close(pin[1]); } if ((f & FPRS) != 0) fd_print(FD2, "%u\n", (unsigned)cpid); if ((f & FAND) != 0) return; if ((f & FPOUT) == 0) pwait(cpid); return; } /**** Child! ****/ /* * Redirect (read) input from pipe. */ if (pin != NULL && (f & FPIN) != 0) { if (dup2(pin[0], FD0) == -1) err(FC_ERR, FMT1S, strerror(errno)); (void)close(pin[0]); (void)close(pin[1]); } /* * Redirect (write) output to pipe. */ if (pout != NULL && (f & FPOUT) != 0) { if (dup2(pout[1], FD1) == -1) err(FC_ERR, FMT1S, strerror(errno)); (void)close(pout[0]); (void)close(pout[1]); } /* * Redirect (read) input from file. */ if (t->nfin != NULL && (f & FPIN) == 0) { f |= FFIN; ascan(t->nfin, &trim); if ((i = open(t->nfin, O_RDONLY)) == -1) err(FC_ERR, FMT2S, t->nfin, ERR_OPEN); if (dup2(i, FD0) == -1) err(FC_ERR, FMT1S, strerror(errno)); (void)close(i); } /* * Redirect (write) output to file. */ if (t->nfout != NULL && (f & FPOUT) == 0) { if ((f & FCAT) != 0) i = O_WRONLY | O_APPEND | O_CREAT; else i = O_WRONLY | O_TRUNC | O_CREAT; ascan(t->nfout, &trim); if ((i = open(t->nfout, i, 0666)) == -1) err(FC_ERR, FMT2S, t->nfout, ERR_CREATE); if (dup2(i, FD1) == -1) err(FC_ERR, FMT1S, strerror(errno)); (void)close(i); } /* * Set the action for the SIGINT and SIGQUIT signals, and * redirect input for `&' commands from `/dev/null' if needed. */ if ((f & FINTR) != 0) { (void)sasignal(SIGINT, SIG_IGN); (void)sasignal(SIGQUIT, SIG_IGN); if (t->nfin == NULL && (f & (FFIN|FPIN|FPRS)) == FPRS) { (void)close(FD0); if (open("/dev/null", O_RDONLY) != FD0) err(FC_ERR,FMT2S,"/dev/null",ERR_OPEN); } } else { if ((sig_child & S_SIGINT) != 0) (void)sasignal(SIGINT, SIG_DFL); if ((sig_child & S_SIGQUIT) != 0) (void)sasignal(SIGQUIT, SIG_DFL); } /* Set the SIGTERM signal to its default action if needed. */ if ((sig_child & S_SIGTERM) != 0) (void)sasignal(SIGTERM, SIG_DFL); if (t->ntype == TSUBSHELL) { if ((t1 = t->nsub) != NULL) t1->nflags |= (f & (FFIN | FPIN | FINTR)); execute(t1, NULL, NULL); _exit(status); } glob_flag = false; vscan(t->nav, &tglob); if (glob_flag) { for (i = 0; t->nav[i] != NULL; i++) ; /* nothing */ #ifdef DEBUG #ifdef DEBUG_GLOB fd_print(FD2, "execute: i == %2d;\n", i); fd_print(FD2, " : (i + 2) == %2d;\n", (i + 2)); fd_print(FD2, " : (i + 1) == %2d;\n", (i + 1)); #endif #endif gav = xmalloc((i + 2) * sizeof(char *)); gav[0] = "glob6"; cmd = gav[0]; (void)memcpy(&gav[1], t->nav, (i + 1) * sizeof(char *)); #ifdef DEBUG #ifdef DEBUG_GLOB for (i = 0; gav[i] != NULL; i++) fd_print(FD2, " : gav[%2d] == %s;\n", i, gav[i]); fd_print(FD2, " : gav[%2d] == NULL;\n", i); #endif #endif (void)err_pexec(cmd, (char *const *)gav); } else { vscan(t->nav, &trim); cmd = t->nav[0]; (void)err_pexec(cmd, (char *const *)t->nav); } /*NOTREACHED*/ } }
void linux_hotplug_hotplug_event_handler (struct einit_event *ev) { if (ev->stringset) { char *subsystem = NULL; char *firmware = NULL; char *devpath = NULL; int i = 0; struct cfgnode *node = cfg_getnode ("configuration-system-hotplug-support-legacy-hotplug-scripts", NULL); for (; ev->stringset[i]; i+=2) { if (strmatch (ev->stringset[i], "SUBSYSTEM")) { subsystem = ev->stringset[i+1]; } else if (strmatch (ev->stringset[i], "FIRMWARE")) { firmware = ev->stringset[i+1]; } else if (strmatch (ev->stringset[i], "DEVPATH")) { devpath = ev->stringset[i+1]; } } if (node && node->flag) { char **commands = NULL; if (subsystem) { char n = 0; for (; n < 2; n++) { char buffer[BUFFERSIZE]; char *tbuffer = (n == 1) ? "/etc/einit/hotplug.d/default/" : NULL; switch (n) { case 0: esprintf(buffer, BUFFERSIZE, "/etc/einit/hotplug.d/%s/", subsystem); tbuffer = buffer; break; case 1: break; default: tbuffer = NULL; break; } if (tbuffer) { struct stat st; if (!stat (tbuffer, &st) && S_ISDIR(st.st_mode)) { char **cm = readdirfilter (NULL, tbuffer, "\\.hotplug$", NULL, 0); if (cm) { commands = (char **)setcombine_nc ((void **)commands, (const void **)cm, SET_TYPE_STRING); efree (cm); } } } } } if (commands) { char **env = NULL; char *command; ssize_t blen = strlen (subsystem) + 2; char **cd = NULL; for (i = 0; ev->stringset[i]; i+=2) { env = straddtoenviron (env, ev->stringset[i], ev->stringset[i+1]); } for (i = 0; commands[i]; i++) { int len = blen + strlen (commands[i]); char *t = emalloc (len); esprintf (t, len, "%s %s", commands[i], subsystem); cd = set_str_add (cd, t); efree (t); } if (cd) { command = set2str (';', (const char **)cd); pexec(command, NULL, 0, 0, NULL, NULL, env, NULL); efree (cd); efree (command); } efree (env); efree (commands); } } if (firmware && (ev->type == einit_hotplug_add)) { char buffer[BUFFERSIZE]; int tblen = sizeof(SYS_DIR) + strlen (devpath) + 11; FILE *f; struct stat st; char *targetbuffer = emalloc (tblen); notice (2, "need firmware: %s", firmware); esprintf (buffer, BUFFERSIZE, FIRMWARE_DIR "/%s", firmware); if (stat (buffer, &st)) { esprintf (targetbuffer, tblen, SYS_DIR "/%s/loading", devpath); if ((f = fopen (targetbuffer, "w"))) { fputs ("-1\n", f); fclose (f); } notice (3, "can't locate firmware: %s", buffer); } else { esprintf (targetbuffer, tblen, SYS_DIR "/%s/loading", devpath); if ((f = fopen (targetbuffer, "w"))) { fputs ("1\n", f); fclose (f); } esprintf (targetbuffer, tblen, SYS_DIR "/%s/data", devpath); ssize_t ll = 0; char *firmware_data = readfile_l (buffer, &ll); if (firmware_data && ll) { if ((f = fopen (targetbuffer, "w"))) { int rembytes = ll; while (rembytes > 0) { size_t bw = fwrite (firmware_data +ll -rembytes, rembytes, 1, f); if (bw == 1) break; if (bw < 0) { notice (3, "error writing firmware: %s", buffer); } } fclose (f); } esprintf (targetbuffer, tblen, SYS_DIR "/%s/loading", devpath); if ((f = fopen (targetbuffer, "w"))) { fputs ("0\n", f); fclose (f); } notice (3, "firmware loaded okay: %s", buffer); } else { esprintf (targetbuffer, tblen, SYS_DIR "/%s/loading", devpath); if ((f = fopen (targetbuffer, "w"))) { fputs ("-1\n", f); fclose (f); } notice (3, "can't load firmware: %s", buffer); } } notice (3, "done loading firmware: %s", buffer); efree (targetbuffer); } } }
/* * Execute a file or path name w/ error handling. * This function never returns. */ void err_pexec(const char *file, char *const *argv) { long l; const char *f, *n; (void)pexec(file, argv); #ifdef DEBUG fd_print(FD2, "err_pexec: strerror(errno) == %s;\n", strerror(errno)); #endif f = (file == NULL) ? "(null)" : file; n = getmyname(); if (EQUAL(n, "glob6")) { if (errno == ENOEXEC) err(SH_ERR, FMT1S, ERR_NOSHELL); if (errno == E2BIG) err(SH_ERR, FMT1S, ERR_E2BIG); err(SH_ERR, FMT1S, ERR_GNOTFOUND); } else if (EQUAL(n, "sh6")) { if (errno == ENOEXEC) err(125, FMT1S, ERR_NOSHELL); if (errno == E2BIG) err(126, FMT2S, f, ERR_E2BIG); if (errno != ENOENT && errno != ENOTDIR) err(126, FMT2S, f, ERR_EXEC); err(127, FMT2S, f, ERR_NOTFOUND); } else { l = no_lnum ? -1 : get_lnum(); if (name != NULL) { if (l != -1) { if (errno == ENOEXEC) err(125,FMT4LS,n,name,l,f, ERR_NOSHELL); if (errno == E2BIG) err(126,FMT4LS,n,name, l, f, ERR_E2BIG); if (errno != ENOENT && errno != ENOTDIR) err(126,FMT4LS,n, name, l, f, ERR_EXEC); err(127, FMT4LS, n, name, l, f, ERR_NOTFOUND); } else { if (errno == ENOEXEC) err(125,FMT4S, n, name, f, ERR_NOSHELL); if (errno == E2BIG) err(126, FMT4S, n, name, f, ERR_E2BIG); if (errno != ENOENT && errno != ENOTDIR) err(126, FMT4S, n, name, f, ERR_EXEC); err(127, FMT4S, n, name, f, ERR_NOTFOUND); } } else { if (l != -1) { if (errno == ENOEXEC) err(125, FMT3LFS, n, l, f, ERR_NOSHELL); if (errno == E2BIG) err(126, FMT3LFS, n, l, f, ERR_E2BIG); if (errno != ENOENT && errno != ENOTDIR) err(126, FMT3LFS, n, l, f, ERR_EXEC); err(127, FMT3LFS, n, l, f, ERR_NOTFOUND); } else { if (errno == ENOEXEC) err(125, FMT3S, n, f, ERR_NOSHELL); if (errno == E2BIG) err(126, FMT3S, n, f, ERR_E2BIG); if (errno != ENOENT && errno != ENOTDIR) err(126, FMT3S, n, f, ERR_EXEC); err(127, FMT3S, n, f, ERR_NOTFOUND); } } } }
void *linux_kernel_modules_load_exec (void *c) { pexec (c, NULL, 0, 0, NULL, NULL, NULL, NULL); return NULL; }