diff --git a/binfmt/CMakeLists.txt b/binfmt/CMakeLists.txt index f0e0abe371..a09e1fa59e 100644 --- a/binfmt/CMakeLists.txt +++ b/binfmt/CMakeLists.txt @@ -61,5 +61,7 @@ if(CONFIG_BUILTIN) list(APPEND SRCS builtin.c) endif() +target_include_directories(binfmt PRIVATE ${CMAKE_SOURCE_DIR}/sched) + target_sources(binfmt PRIVATE ${SRCS}) target_include_directories(binfmt PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/binfmt/Makefile b/binfmt/Makefile index 9f8dbf8f05..004ef03a8a 100644 --- a/binfmt/Makefile +++ b/binfmt/Makefile @@ -58,6 +58,8 @@ endif include libnxflat/Make.defs include libelf/Make.defs +CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)sched + AOBJS = $(ASRCS:.S=$(OBJEXT)) COBJS = $(CSRCS:.c=$(OBJEXT)) diff --git a/binfmt/binfmt_exec.c b/binfmt/binfmt_exec.c index d52645961a..fc8be1e738 100644 --- a/binfmt/binfmt_exec.c +++ b/binfmt/binfmt_exec.c @@ -37,11 +37,11 @@ #ifndef CONFIG_BINFMT_DISABLE /**************************************************************************** - * Public Functions + * Private Functions ****************************************************************************/ /**************************************************************************** - * Name: exec_spawn + * Name: exec_internel * * Description: * exec() configurable version, delivery the spawn attribute if this @@ -64,6 +64,7 @@ * nexports - The number of symbols in the exports table. * actions - The spawn file actions * attr - The spawn attributes. + * spawn - Is spawn in new task. * * Returned Value: * It returns the PID of the exec'ed module. On failure, it returns @@ -71,10 +72,11 @@ * ****************************************************************************/ -int exec_spawn(FAR const char *filename, FAR char * const *argv, - FAR char * const *envp, FAR const struct symtab_s *exports, - int nexports, FAR const posix_spawn_file_actions_t *actions, - FAR const posix_spawnattr_t *attr) +static int exec_internel(FAR const char *filename, + FAR char * const *argv, FAR char * const *envp, + FAR const struct symtab_s *exports, int nexports, + FAR const posix_spawn_file_actions_t *actions, + FAR const posix_spawnattr_t *attr, bool spawn) { FAR struct binary_s *bin; irqstate_t flags; @@ -132,7 +134,7 @@ int exec_spawn(FAR const char *filename, FAR char * const *argv, /* Then start the module */ - pid = exec_module(bin, filename, argv, envp, actions); + pid = exec_module(bin, filename, argv, envp, actions, spawn); if (pid < 0) { ret = pid; @@ -175,6 +177,50 @@ errout: return ret; } +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: exec_spawn + * + * Description: + * exec() configurable version, delivery the spawn attribute if this + * process has special customization. + * + * Input Parameters: + * filename - The path to the program to be executed. If + * CONFIG_LIBC_ENVPATH is defined in the configuration, then + * this may be a relative path from the current working + * directory. Otherwise, path must be the absolute path to the + * program. + * argv - A pointer to an array of string arguments. The end of the + * array is indicated with a NULL entry. + * envp - A pointer to an array of environment strings. Terminated with + * a NULL entry. + * exports - The address of the start of the caller-provided symbol + * table. This symbol table contains the addresses of symbols + * exported by the caller and made available for linking the + * module into the system. + * nexports - The number of symbols in the exports table. + * actions - The spawn file actions + * attr - The spawn attributes. + * + * Returned Value: + * It returns the PID of the exec'ed module. On failure, it returns + * the negative errno value appropriately. + * + ****************************************************************************/ + +int exec_spawn(FAR const char *filename, FAR char * const *argv, + FAR char * const *envp, FAR const struct symtab_s *exports, + int nexports, FAR const posix_spawn_file_actions_t *actions, + FAR const posix_spawnattr_t *attr) +{ + return exec_internel(filename, argv, envp, + exports, nexports, actions, attr, true); +} + /**************************************************************************** * Name: exec * @@ -245,7 +291,8 @@ int exec(FAR const char *filename, FAR char * const *argv, { int ret; - ret = exec_spawn(filename, argv, envp, exports, nexports, NULL, NULL); + ret = exec_internel(filename, argv, envp, + exports, nexports, NULL, NULL, false); if (ret < 0) { set_errno(-ret); diff --git a/binfmt/binfmt_execmodule.c b/binfmt/binfmt_execmodule.c index 62eed84958..6461eb70a7 100644 --- a/binfmt/binfmt_execmodule.c +++ b/binfmt/binfmt_execmodule.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -96,6 +97,91 @@ static void exec_ctors(FAR void *arg) } #endif +/**************************************************************************** + * Name: exec_swap + * + * Description: + * swap the pid of tasks, and reverse parent-child relationship. + * + * Input Parameters: + * ptcb - parent task tcb. + * chtcb - child task tcb. + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void exec_swap(FAR struct tcb_s *ptcb, FAR struct tcb_s *chtcb) +{ + int pndx; + int chndx; + pid_t pid; + irqstate_t flags; +#ifdef HAVE_GROUP_MEMBERS + FAR pid_t *tg_members; +#endif +#ifdef CONFIG_SCHED_HAVE_PARENT +# ifdef CONFIG_SCHED_CHILD_STATUS + FAR struct child_status_s *tg_children; +# else + uint16_t tg_nchildren; +# endif +#endif + + DEBUGASSERT(ptcb); + DEBUGASSERT(chtcb); + + flags = enter_critical_section(); + + pndx = PIDHASH(ptcb->pid); + chndx = PIDHASH(chtcb->pid); + + DEBUGASSERT(g_pidhash[pndx]); + DEBUGASSERT(g_pidhash[chndx]); + + /* Exchange g_pidhash index */ + + g_pidhash[pndx] = chtcb; + g_pidhash[chndx] = ptcb; + + /* Exchange pid */ + + pid = chtcb->pid; + chtcb->pid = ptcb->pid; + ptcb->pid = pid; + + /* Exchange group info. This will reverse parent-child relationship */ + + pid = chtcb->group->tg_pid; + chtcb->group->tg_pid = ptcb->group->tg_pid; + ptcb->group->tg_pid = pid; + + pid = chtcb->group->tg_ppid; + chtcb->group->tg_ppid = ptcb->group->tg_ppid; + ptcb->group->tg_ppid = pid; + +#ifdef HAVE_GROUP_MEMBERS + tg_members = chtcb->group->tg_members; + chtcb->group->tg_members = ptcb->group->tg_members; + ptcb->group->tg_members = tg_members; +#endif + +#ifdef CONFIG_SCHED_HAVE_PARENT +# ifdef CONFIG_SCHED_CHILD_STATUS + tg_children = chtcb->group->tg_children; + chtcb->group->tg_children = ptcb->group->tg_children; + ptcb->group->tg_children = tg_children; +# else + tg_nchildren = chtcb->group->tg_nchildren; + chtcb->group->tg_nchildren = ptcb->group->tg_nchildren; + ptcb->group->tg_nchildren = tg_nchildren; +# endif +#endif + + leave_critical_section(flags); +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -116,7 +202,8 @@ static void exec_ctors(FAR void *arg) int exec_module(FAR struct binary_s *binp, FAR const char *filename, FAR char * const *argv, FAR char * const *envp, - FAR const posix_spawn_file_actions_t *actions) + FAR const posix_spawn_file_actions_t *actions, + bool spawn) { FAR struct task_tcb_s *tcb; #if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL) @@ -292,6 +379,11 @@ int exec_module(FAR struct binary_s *binp, } #endif + if (!spawn) + { + exec_swap(this_task(), (FAR struct tcb_s *)tcb); + } + /* Then activate the task at the provided priority */ nxtask_activate((FAR struct tcb_s *)tcb); diff --git a/include/nuttx/binfmt/binfmt.h b/include/nuttx/binfmt/binfmt.h index f15c88f8dd..4f4281ab5d 100644 --- a/include/nuttx/binfmt/binfmt.h +++ b/include/nuttx/binfmt/binfmt.h @@ -270,7 +270,8 @@ int unload_module(FAR struct binary_s *bin); int exec_module(FAR struct binary_s *binp, FAR const char *filename, FAR char * const *argv, FAR char * const *envp, - FAR const posix_spawn_file_actions_t *actions); + FAR const posix_spawn_file_actions_t *actions, + bool spawn); /**************************************************************************** * Name: exec