Fix a perverse case where vfork() is called from a pthread. Still not recommended
This commit is contained in:
parent
b693fb358a
commit
542e706d7d
@ -79,12 +79,12 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if CONFIG_TASK_NAME_SIZE > 0
|
#if CONFIG_TASK_NAME_SIZE > 0
|
||||||
static inline void vfork_namesetup(FAR struct task_tcb_s *parent,
|
static inline void vfork_namesetup(FAR struct tcb_s *parent,
|
||||||
FAR struct task_tcb_s *child)
|
FAR struct task_tcb_s *child)
|
||||||
{
|
{
|
||||||
/* Copy the name from the parent into the child TCB */
|
/* Copy the name from the parent into the child TCB */
|
||||||
|
|
||||||
strncpy(child->cmn.name, parent->cmn.name, CONFIG_TASK_NAME_SIZE);
|
strncpy(child->cmn.name, parent->name, CONFIG_TASK_NAME_SIZE);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# define vfork_namesetup(p,c)
|
# define vfork_namesetup(p,c)
|
||||||
@ -106,21 +106,33 @@ static inline void vfork_namesetup(FAR struct task_tcb_s *parent,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static inline void vfork_stackargsetup(FAR struct task_tcb_s *parent,
|
static inline void vfork_stackargsetup(FAR struct tcb_s *parent,
|
||||||
FAR struct task_tcb_s *child)
|
FAR struct task_tcb_s *child)
|
||||||
{
|
{
|
||||||
|
/* Is the parent a task? or a pthread? */
|
||||||
|
|
||||||
|
child->argv = NULL;
|
||||||
|
if ((parent->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD)
|
||||||
|
{
|
||||||
|
FAR struct task_tcb_s *ptcb = (FAR struct task_tcb_s *)parent;
|
||||||
uintptr_t offset;
|
uintptr_t offset;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Get the address correction */
|
/* Get the address correction */
|
||||||
|
|
||||||
offset = child->cmn.xcp.regs[REG_SP] - parent->cmn.xcp.regs[REG_SP];
|
offset = child->cmn.xcp.regs[REG_SP] - parent->xcp.regs[REG_SP];
|
||||||
|
|
||||||
|
/* Change the child argv[] to point into its stack (instead of its
|
||||||
|
* parent's stack).
|
||||||
|
*/
|
||||||
|
|
||||||
|
child->argv = (FAR char **)((uintptr_t)ptcb->argv + offset);
|
||||||
|
|
||||||
/* Copy the adjusted address for each argument */
|
/* Copy the adjusted address for each argument */
|
||||||
|
|
||||||
for (i = 0; i < CONFIG_MAX_TASK_ARGS && parent->argv[i]; i++)
|
for (i = 0; i < CONFIG_MAX_TASK_ARGS && ptcb->argv[i]; i++)
|
||||||
{
|
{
|
||||||
uintptr_t newaddr = (uintptr_t)parent->argv[i] + offset;
|
uintptr_t newaddr = (uintptr_t)ptcb->argv[i] + offset;
|
||||||
child->argv[i] = (FAR char *)newaddr;
|
child->argv[i] = (FAR char *)newaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,6 +140,7 @@ static inline void vfork_stackargsetup(FAR struct task_tcb_s *parent,
|
|||||||
|
|
||||||
child->argv[i] = NULL;
|
child->argv[i] = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: vfork_argsetup
|
* Name: vfork_argsetup
|
||||||
@ -144,7 +157,7 @@ static inline void vfork_stackargsetup(FAR struct task_tcb_s *parent,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static inline void vfork_argsetup(FAR struct task_tcb_s *parent,
|
static inline void vfork_argsetup(FAR struct tcb_s *parent,
|
||||||
FAR struct task_tcb_s *child)
|
FAR struct task_tcb_s *child)
|
||||||
{
|
{
|
||||||
/* Clone the task name */
|
/* Clone the task name */
|
||||||
|
Loading…
Reference in New Issue
Block a user