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 task_spawn_exec(FAR pid_t *pidp, FAR const char *name, main_t entry, FAR const posix_spawnattr_t *attr, FAR char * const *argv) { size_t stacksize; int priority; int pid; int ret = OK; /* 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(); /* Use the default task priority and stack size if no attributes are provided */ if (attr) { priority = attr->priority; stacksize = attr->stacksize; } else { struct sched_param param; /* Set the default priority to the same priority as this task */ ret = sched_getparam(0, ¶m); if (ret < 0) { goto errout; } priority = param.sched_priority; stacksize = CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE; } /* Start the task */ pid = task_create(name, priority, stacksize, entry, argv); if (pid < 0) { ret = get_errno(); serr("ERROR: task_create 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; }