4
0
mirror of https://github.com/RT-Thread/rt-thread.git synced 2025-01-19 23:03:32 +08:00
Shell e5cf86267b
[smart] fixup of script execution (#9009)
This patch fixup the script execution capabilities on argv passing
and adds support for arguments larger than 4k.

According to POSIX, the script parameter is quiet different
from the current implementation. Especially on the way it inserts
the path of executables. At the end, when you execute a script
from `$PATH`, it always fails.

For the script, interpreter will be invoked with the following
arguments: `{interpreter [optional-arg] pathname arg...}`
where pathname is the pathname of the file specified as the first
argument of execve(), and arg...  is the series of words pointed
to by the argv argument of execve(), starting at argv[1].  Note that
there is no way to get the argv[0] that was passed to the
execve() call.

The changes include:

- Separating argument, environment variable, and auxiliary vector
  processing into a new lwp_args.c file.
- Fixing bugs in script argument processing and supporting arguments
  larger than 4k.
- Updating lwp_execve to use the new argscopy function and removing
  the old lwp_argscopy function.
- Making various modifications to lwp_load and elf_aux_fill to work
  with the new argument processing.
- Removing unnecessary code related to dynamic loading and interpreter
  scripts.

Signed-off-by: Shell <smokewood@qq.com>
2024-05-31 17:32:19 +08:00

190 lines
7.8 KiB
C

/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-07-25 Shell first version
* 2023-11-25 Shell Add pgrp, session lock API
*/
#ifndef __LWP_INTERNAL_H__
#define __LWP_INTERNAL_H__
#include "lwp.h"
#include "lwp_arch.h"
#include "lwp_user_mm.h"
#include "lwp_mm.h"
#include <rtthread.h>
#include "libc_musl.h"
struct rt_lwp;
#define LWP_MTX_FLAGS_INTR 0x1 /* interruptible waiting */
#define LWP_MTX_FALGS_NESTED 0x2 /* allow nested */
rt_err_t lwp_mutex_take_safe(rt_mutex_t mtx, rt_int32_t timeout, int flags);
rt_err_t lwp_mutex_release_safe(rt_mutex_t mtx);
rt_inline rt_bool_t lwp_in_user_space(const char *addr)
{
return (addr >= (char *)USER_VADDR_START && addr < (char *)USER_VADDR_TOP);
}
#ifdef RT_USING_SMP
#define LOCAL_IRQ_MASK() rt_hw_local_irq_disable()
#define LOCAL_IRQ_UNMASK(level) rt_hw_local_irq_enable(level)
#else
#define LOCAL_IRQ_MASK() rt_hw_interrupt_disable()
#define LOCAL_IRQ_UNMASK(level) rt_hw_interrupt_enable(level)
#endif
#ifndef LWP_USING_CPUS_LOCK
rt_err_t lwp_sess_critical_enter(struct rt_session *sess, int flags);
rt_err_t lwp_sess_critical_exit(struct rt_session *sess);
rt_err_t lwp_pgrp_critical_enter(struct rt_processgroup *pgrp, int flags);
rt_err_t lwp_pgrp_critical_exit(struct rt_processgroup *pgrp);
rt_err_t lwp_critical_enter(struct rt_lwp *lwp, int flags);
rt_err_t lwp_critical_exit(struct rt_lwp *lwp);
#define LWP_ASSERT_LOCKED(proc) RT_ASSERT(rt_mutex_get_owner(&(proc)->lwp_lock) == rt_thread_self())
#define PGRP_ASSERT_LOCKED(pgrp) RT_ASSERT(rt_mutex_get_owner(&(pgrp)->mutex) == rt_thread_self())
#define LWP_LOCK(lwp) \
do \
{ \
RT_DEBUG_SCHEDULER_AVAILABLE(1); \
if (lwp_critical_enter(lwp, 0) != RT_EOK) \
{ \
RT_ASSERT(0); \
} \
} while (0)
#define LWP_LOCK_NESTED(lwp) \
do \
{ \
RT_DEBUG_SCHEDULER_AVAILABLE(1); \
if (lwp_critical_enter(lwp, LWP_MTX_FALGS_NESTED) != RT_EOK) \
{ \
RT_ASSERT(0); \
} \
} while (0)
#define LWP_UNLOCK(lwp) \
do { \
if (lwp_critical_exit(lwp) != RT_EOK) \
{ \
RT_ASSERT(0); \
} \
} while (0)
#define PGRP_LOCK(pgrp) \
do \
{ \
RT_DEBUG_SCHEDULER_AVAILABLE(1); \
if (lwp_pgrp_critical_enter(pgrp, 0) != RT_EOK) \
{ \
RT_ASSERT(0); \
} \
} while (0)
#define PGRP_LOCK_NESTED(pgrp) \
do \
{ \
RT_DEBUG_SCHEDULER_AVAILABLE(1); \
if (lwp_pgrp_critical_enter(pgrp, LWP_MTX_FALGS_NESTED) != RT_EOK) \
{ \
RT_ASSERT(0); \
} \
} while (0)
#define PGRP_UNLOCK(pgrp) \
do \
{ \
if (lwp_pgrp_critical_exit(pgrp) != RT_EOK) \
{ \
RT_ASSERT(0); \
} \
} while (0)
#define SESS_LOCK(sess) \
do \
{ \
RT_DEBUG_SCHEDULER_AVAILABLE(1); \
if (lwp_sess_critical_enter(sess, 0) != RT_EOK) \
{ \
RT_ASSERT(0); \
} \
} while (0)
#define SESS_LOCK_NESTED(sess) \
do \
{ \
RT_DEBUG_SCHEDULER_AVAILABLE(1); \
if (lwp_sess_critical_enter(sess, LWP_MTX_FALGS_NESTED) != RT_EOK) \
{ \
RT_ASSERT(0); \
} \
} while (0)
#define SESS_UNLOCK(sess) \
do \
{ \
if (lwp_sess_critical_exit(sess) != RT_EOK) \
{ \
RT_ASSERT(0); \
} \
} while (0)
#else
#define LWP_LOCK(lwp) rt_base_t level = rt_hw_interrupt_disable()
#define LWP_UNLOCK(lwp) rt_hw_interrupt_enable(level)
#define PGRP_LOCK(pgrp) rt_base_t level = rt_hw_interrupt_disable()
#define PGRP_UNLOCK(pgrp) rt_hw_interrupt_enable(level)
#define SESS_LOCK(sess) rt_base_t level = rt_hw_interrupt_disable()
#define SESS_UNLOCK(sess) rt_hw_interrupt_enable(level)
#endif /* LWP_USING_CPUS_LOCK */
/* cpus lock */
#ifdef LWP_OVERRIDE_CPUS_LOCK
#undef rt_hw_interrupt_disable
#undef rt_hw_interrupt_enable
#define rt_hw_interrupt_disable() ({ \
rt_base_t irq = rt_hw_interrupt_is_disabled(); \
if (irq) \
{ \
LOG_W("Nested interrupt disable"); \
rt_backtrace(); \
irq = 0xabadcafe; \
} else { \
irq = rt_cpus_lock(); \
} \
irq; \
})
#define rt_hw_interrupt_enable(level) do { \
if (level != 0xabadcafe) \
rt_cpus_unlock(level); \
} while (0)
#endif /* LWP_OVERRIDE_CPUS_LOCK */
/**
* Brief: Return code with safety check
* There tend to be chances where a return value is returned without correctly init
*/
#ifndef LWP_DEBUG
#define LWP_DEF_RETURN_CODE(name) rt_err_t name;RT_UNUSED(name)
#define LWP_RETURN(name) return name
#else
#define _LWP_UNINITIALIZED_RC 0xbeefcafe
#define LWP_DEF_RETURN_CODE(name) rt_err_t name = _LWP_UNINITIALIZED_RC
#define LWP_RETURN(name) {RT_ASSERT(name != _LWP_UNINITIALIZED_RC);return name;}
#endif /* LWP_DEBUG */
#endif /* __LWP_INTERNAL_H__ */