nuttx/sched/task/task_spawn.c
Ville Juven 6e9e215943 sched/task: Remove spawn_proxyattrs as obsolete implementation
Like the name implies, it is supposed to set the spawn attributes for
the NuttX specific "spawn proxy task" which was historically used as
a proxy to spawn new tasks. The proxy handled file actions and the signal
mask which are inherited from the parent.

The proxy task does not exist anymore, thus the proxy task attributes
do not need to be set anymore either.

Also, the function is currently still used, but the signal mask is set
for the spawning process, not the proxy process, and this is most
DEFINITELY an error (as the spawning process's signal mask changes
unexpectedly).

Setting the signal mask for the newly spawned process is simple, just
set it directly, if instructed to do so. This will be done in a later
patch!
2023-10-30 22:30:03 +08:00

342 lines
11 KiB
C

/****************************************************************************
* sched/task/task_spawn.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/wait.h>
#include <sched.h>
#include <spawn.h>
#include <assert.h>
#include <debug.h>
#include <errno.h>
#include <nuttx/fs/fs.h>
#include <nuttx/sched.h>
#include <nuttx/kthread.h>
#include <nuttx/spawn.h>
#include "sched/sched.h"
#include "group/group.h"
#include "task/spawn.h"
#include "task/task.h"
#ifndef CONFIG_BUILD_KERNEL
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: nxtask_spawn_create
*
* Description:
* This function creates and activates a new thread of the specified type
* with a specified priority and returns its system-assigned ID. It is the
* internal, common implementation of task_create() and kthread_create().
* See comments with task_create() for further information.
*
* Input Parameters:
* name - Name of the new task
* ttype - Type of the new task
* priority - Priority of the new task
* stack_addr - Address of the stack needed
* stack_size - Size (in bytes) of the stack needed
* entry - Entry point of a new task
* arg - A pointer to an array of input parameters. The array
* should be terminated with a NULL argv[] value. If no
* parameters are required, argv may be NULL.
* envp - A pointer to an array of environment strings. Terminated
* with a NULL entry.
* actions - The spawn file actions
*
* Returned Value:
* Returns the positive, non-zero process ID of the new task or a negated
* errno value to indicate the nature of any failure. If memory is
* insufficient or the task cannot be created -ENOMEM will be returned.
*
****************************************************************************/
static int nxtask_spawn_create(FAR const char *name, int priority,
FAR void *stack_addr, int stack_size,
main_t entry, FAR char * const argv[],
FAR char * const envp[],
FAR const posix_spawn_file_actions_t *actions,
FAR const posix_spawnattr_t *attr)
{
FAR struct task_tcb_s *tcb;
pid_t pid;
int ret;
/* Allocate a TCB for the new task. */
tcb = kmm_zalloc(sizeof(struct task_tcb_s));
if (tcb == NULL)
{
serr("ERROR: Failed to allocate TCB\n");
return -ENOMEM;
}
/* Setup the task type */
tcb->cmn.flags = TCB_FLAG_TTYPE_TASK;
/* Initialize the task */
ret = nxtask_init(tcb, name, priority, stack_addr, stack_size,
entry, argv, envp);
if (ret < OK)
{
kmm_free(tcb);
return ret;
}
/* Get the assigned pid before we start the task */
pid = tcb->cmn.pid;
/* Perform file actions */
if (actions != NULL)
{
ret = spawn_file_actions(&tcb->cmn, actions);
if (ret < 0)
{
goto errout_with_taskinit;
}
}
/* Close the file descriptors with O_CLOEXEC before active task */
files_close_onexec(&tcb->cmn);
/* Set the attributes */
if (attr)
{
ret = spawn_execattrs(pid, attr);
if (ret < 0)
{
goto errout_with_taskinit;
}
}
/* Activate the task */
nxtask_activate(&tcb->cmn);
return pid;
errout_with_taskinit:
nxtask_uninit(tcb);
return ret;
}
/****************************************************************************
* Name: nxtask_spawn_exec
*
* Description:
* Execute the task from the file system.
*
* Input Parameters:
*
* pidp - Upon successful completion, this will return the task ID of the
* child task in the variable pointed to by a non-NULL 'pid' argument.|
*
* name - The name to assign to the child task.
*
* entry - The child task's entry point (an address in memory)
*
* actions - The spawn file actions
*
* attr - If the value of the 'attr' parameter is NULL, the all default
* values for the POSIX spawn attributes will be used. Otherwise, the
* attributes will be set according to the spawn flags. The
* following spawn flags are supported:
*
* - POSIX_SPAWN_SETSCHEDPARAM: Set new tasks priority to the sched_param
* value.
* - POSIX_SPAWN_SETSCHEDULER: Set the new tasks scheduler priority to
* the sched_policy value.
*
* NOTE: POSIX_SPAWN_SETSIGMASK is handled in nxtask_spawn_proxy().
*
* argv - argv[] is the argument list for the new task. argv[] is an
* array of pointers to null-terminated strings. The list is terminated
* with a null pointer.
*
* envp - A pointer to an array of environment strings. Terminated with
* a NULL entry.
*
* Returned Value:
* This function will return zero on success. Otherwise, an error number
* will be returned as the function return value to indicate the error.
* This errno value may be that set by execv(), sched_setpolicy(), or
* sched_setparam().
*
****************************************************************************/
static int nxtask_spawn_exec(FAR pid_t *pidp, FAR const char *name,
main_t entry,
FAR const posix_spawn_file_actions_t *actions,
FAR const posix_spawnattr_t *attr,
FAR char * const *argv, FAR char * const envp[])
{
FAR void *stackaddr = NULL;
size_t stacksize;
int priority;
int pid;
int ret = OK;
/* Use the default priority and stack size if no attributes are provided */
if (attr)
{
priority = attr->priority;
stacksize = attr->stacksize;
stackaddr = attr->stackaddr;
}
else
{
struct sched_param param;
/* Set the default priority to the same priority as this task */
ret = nxsched_get_param(0, &param);
if (ret < 0)
{
return ret;
}
priority = param.sched_priority;
stacksize = CONFIG_POSIX_SPAWN_DEFAULT_STACKSIZE;
}
/* Start the task */
pid = nxtask_spawn_create(name, priority, stackaddr,
stacksize, entry, argv,
envp ? envp : environ, actions, attr);
if (pid < 0)
{
ret = pid;
serr("ERROR: nxtask_spawn_create failed: %d\n", ret);
return ret;
}
/* Return the task ID to the caller */
if (pid)
{
*pidp = pid;
}
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: task_spawn
*
* Description:
* The task_spawn() function will create a new, child task, where the
* entry point to the task is an address in memory.
*
* Input Parameters:
*
* name - The name to assign to the child task.
*
* entry - The child task's entry point (an address in memory)
*
* file_actions - If 'file_actions' is a null pointer, then file
* descriptors open in the calling process will remain open in the
* child process (unless CONFIG_FDCLONE_STDIO is defined). If
* 'file_actions' is not NULL, then the file descriptors open in the
* child process will be those open in the calling process as modified
* by the spawn file actions object pointed to by file_actions.
*
* attr - If the value of the 'attr' parameter is NULL, the all default
* values for the POSIX spawn attributes will be used. Otherwise, the
* attributes will be set according to the spawn flags. The
* posix_spawnattr_t spawn attributes object type is defined in spawn.h.
* It will contains these attributes, not all of which are supported by
* NuttX:
*
* - POSIX_SPAWN_SETPGROUP: Setting of the new task's process group is
* not supported. NuttX does not support process groups.
* - POSIX_SPAWN_SETSCHEDPARAM: Set new tasks priority to the sched_param
* value.
* - POSIX_SPAWN_SETSCHEDULER: Set the new task's scheduler policy to
* the sched_policy value.
* - POSIX_SPAWN_RESETIDS: Resetting of the effective user ID of the
* child process is not supported. NuttX does not support effective
* user IDs.
* - POSIX_SPAWN_SETSIGMASK: Set the new task's signal mask.
* - POSIX_SPAWN_SETSIGDEF: Resetting signal default actions is not
* supported. NuttX does not support default signal actions.
*
* And the non-standard:
*
* - TASK_SPAWN_SETSTACKSIZE: Set the stack size for the new task.
*
* argv - argv[] is the argument list for the new task. argv[] is an
* array of pointers to null-terminated strings. The list is terminated
* with a null pointer.
*
* envp - envp[] is an array of character pointers to null-terminated
* strings that provide the environment for the new process image.
*
* Returned Value:
* task_spawn() will return process ID of new task on success.
* Otherwise, a negative number will be returned as the function return
* value to indicate the error:
*
* - EINVAL: The value specified by 'file_actions' or 'attr' is invalid.
* - Any errors that might have been return if vfork() and excec[l|v]()
* had been called.
*
****************************************************************************/
int task_spawn(FAR const char *name, main_t entry,
FAR const posix_spawn_file_actions_t *file_actions,
FAR const posix_spawnattr_t *attr,
FAR char * const argv[], FAR char * const envp[])
{
pid_t pid = INVALID_PROCESS_ID;
int ret;
sinfo("name=%s entry=%p file_actions=%p attr=%p argv=%p\n",
name, entry, file_actions, attr, argv);
ret = nxtask_spawn_exec(&pid, name, entry,
file_actions != NULL ? *file_actions : NULL,
attr, argv, envp);
return ret >= 0 ? pid : ret;
}
#endif /* CONFIG_BUILD_KERNEL */