int execv(FAR const char *path, FAR char * const argv[]) { FAR const struct symtab_s *symtab; int nsymbols; int ret; /* Get the current symbol table selection */ exec_getsymtab(&symtab, &nsymbols); /* Start the task */ ret = exec(path, (FAR char * const *)argv, symtab, nsymbols); if (ret < 0) { sdbg("exec failed: %d\n", errno); return ERROR; } /* Then exit */ exit(0); /* We should not get here, but might be needed by some compilers. Other, * smarter compilers might complain that this code is unreachable. You just * can't win. */ return ERROR; }
static int posix_spawn_exec(FAR pid_t *pidp, FAR const char *path, FAR const posix_spawnattr_t *attr, FAR char * const argv[]) { FAR const struct symtab_s *symtab; int nsymbols; int pid; int ret = OK; DEBUGASSERT(path); /* Get the current symbol table selection */ exec_getsymtab(&symtab, &nsymbols); /* Disable pre-emption so that we can modify the task parameters after * we start the new task; the new task will not actually begin execution * until we re-enable pre-emption. */ sched_lock(); /* Start the task */ pid = exec(path, (FAR char * const *)argv, symtab, nsymbols); if (pid < 0) { ret = get_errno(); sdbg("ERROR: exec failed: %d\n", ret); goto errout; } /* Return the task ID to the caller */ if (pid) { *pidp = pid; } /* Now set the attributes. Note that we ignore all of the return values * here because we have already successfully started the task. If we * return an error value, then we would also have to stop the task. */ if (attr) { (void)spawn_execattrs(pid, attr); } /* Re-enable pre-emption and return */ errout: sched_unlock(); return ret; }
static int spawn_exec(FAR pid_t *pidp, FAR const char *path, FAR const posix_spawnattr_t *attr, FAR char *const argv[]) { struct sched_param param; FAR const struct symtab_s *symtab; int nsymbols; int pid; int ret = OK; DEBUGASSERT(path); /* Get the current symbol table selection */ exec_getsymtab(&symtab, &nsymbols); /* Disable pre-emption so that we can modify the task parameters after * we start the new task; the new task will not actually begin execution * until we re-enable pre-emption. */ sched_lock(); /* Start the task */ pid = exec(path, (FAR const char **)argv, symtab, nsymbols); if (pid < 0) { ret = errno; sdbg("ERROR: exec failed: %d\n", ret); goto errout; } /* Return the task ID to the caller */ if (pid) { *pidp = pid; } /* Now set the attributes. Note that we ignore all of the return values * here because we have already successfully started the task. If we * return an error value, then we would also have to stop the task. */ if (attr) { /* If we are only setting the priority, then call sched_setparm() * to set the priority of the of the new task. */ if ((attr->flags & POSIX_SPAWN_SETSCHEDPARAM) != 0) { /* Get the priority from the attrributes */ param.sched_priority = attr->priority; /* If we are setting *both* the priority and the scheduler, * then we will call sched_setscheduler() below. */ if ((attr->flags & POSIX_SPAWN_SETSCHEDULER) == 0) { svdbg("Setting priority=%d for pid=%d\n", param.sched_priority, pid); (void)sched_setparam(pid, ¶m); } } /* If we are only changing the scheduling policy, then reset * the priority to the default value (the same as this thread) in * preparation for the sched_setscheduler() call below. */ else if ((attr->flags & POSIX_SPAWN_SETSCHEDULER) != 0) { (void)sched_getparam(0, ¶m); } /* Are we setting the scheduling policy? If so, use the priority * setting determined above. */ if ((attr->flags & POSIX_SPAWN_SETSCHEDULER) != 0) { svdbg("Setting policy=%d priority=%d for pid=%d\n", attr->policy, param.sched_priority, pid); (void)sched_setscheduler(pid, attr->policy, ¶m); } } /* Re-enable pre-emption and return */ errout: sched_unlock(); return ret; }