11/*
2- * Copyright (c) 2006-2024, RT-Thread Development Team
2+ * Copyright (c) 2006-2025 RT-Thread Development Team
33 *
44 * SPDX-License-Identifier: Apache-2.0
55 *
1313#include "lwp_internal.h"
1414#include "mm_page.h"
1515
16+ /**
17+ * @brief Initializes a string vector structure with default buffer size
18+ *
19+ * @param[out] sv Pointer to the string vector structure to initialize
20+ */
1621static void _strvec_init (struct lwp_string_vector * sv )
1722{
1823 #define DEFAUTL_ARGV_BUFLEN 4
@@ -21,6 +26,11 @@ static void _strvec_init(struct lwp_string_vector *sv)
2126 sv -> string_count = 0 ;
2227}
2328
29+ /**
30+ * @brief Detaches and frees memory from a string vector structure
31+ *
32+ * @param[in,out] sv Pointer to the string vector structure to detach
33+ */
2434static void _strvec_detach (struct lwp_string_vector * sv )
2535{
2636 if (sv -> strvec )
@@ -29,6 +39,17 @@ static void _strvec_detach(struct lwp_string_vector *sv)
2939 }
3040}
3141
42+ /**
43+ * @brief Appends a string to a string vector structure
44+ *
45+ * @param[in,out] sv Pointer to the string vector structure
46+ * @param[in] string String to append to the vector
47+ *
48+ * @return rt_err_t RT_EOK on success, -RT_ENOMEM on memory allocation failure
49+ *
50+ * @note This function dynamically grows the string vector's buffer into 2 times its current size
51+ * if buffer is full.
52+ */
3253static rt_err_t _strvec_append (struct lwp_string_vector * sv , const char * string )
3354{
3455 if (sv -> string_count == sv -> strvec_buflen )
@@ -45,6 +66,19 @@ static rt_err_t _strvec_append(struct lwp_string_vector *sv, const char *string)
4566 return RT_EOK ;
4667}
4768
69+ /**
70+ * @brief Appends an argument or environment variable to the LWP arguments info structure
71+ *
72+ * @param[in,out] ai Pointer to the arguments info structure
73+ * @param[in] str_addr Address of the string to append (user or kernel space)
74+ * @param[in] str_len Length of the string to append
75+ * @param[in] atype Type of argument being appended (LWP_ARGS_TYPE_*)
76+ *
77+ * @return rt_err_t RT_EOK on success, -RT_ENOMEM on memory allocation failure
78+ *
79+ * @note This function handles both kernel-space and user-space strings, dynamically
80+ * growing the string buffer into 2 times its current size if buffer is full.
81+ */
4882static rt_err_t args_append (struct lwp_args_info * ai , const char * str_addr ,
4983 size_t str_len , enum lwp_args_type atype )
5084{
@@ -101,13 +135,19 @@ static rt_err_t args_append(struct lwp_args_info *ai, const char *str_addr,
101135/**
102136 * @brief Override arguments 0 for script interpreter.
103137 *
104- * Manual: interpreter will be invoked with the following arguments:
105- * {interpreter [optional-arg] pathname arg...}
106- * where pathname is the pathname of the file specified as the first
107- * argument of execve(), and arg... is the series of words pointed
108- * to by the argv argument of execve(), starting at argv[1]. Note
109- * that there is no way to get the argv[0] that was passed to the
110- * execve() call.
138+ * @param[in,out] ai Pointer to the target argument info structure to be modified.
139+ * @param[in] ow_ai Pointer to the source argument info structure containing arguments to override
140+ * argv[0] with.
141+ *
142+ * @return rt_err_t RT_EOK on success, -RT_EINVAL for invalid input, -RT_ENOMEM on memory allocation failure
143+ *
144+ * @note Manual: interpreter will be invoked with the following arguments:
145+ * {interpreter [optional-arg] pathname arg...}
146+ * where pathname is the pathname of the file specified as the first
147+ * argument of execve(), and arg... is the series of words pointed
148+ * to by the argv argument of execve(), starting at argv[1]. Note
149+ * that there is no way to get the argv[0] that was passed to the
150+ * execve() call.
111151 */
112152static rt_err_t _args_override_argv0 (struct lwp_args_info * ai , struct lwp_args_info * ow_ai )
113153{
@@ -178,11 +218,28 @@ static rt_err_t _args_override_argv0(struct lwp_args_info *ai, struct lwp_args_i
178218 return error ;
179219}
180220
221+ /**
222+ * @brief Get argument 0.
223+ *
224+ * @param[in] ai Pointer to the argument info structure.
225+ *
226+ * @return const char* Pointer to the arguments 0.
227+ */
181228const char * lwp_args_get_argv_0 (struct lwp_args_info * ai )
182229{
183230 return ai -> str_buf ;
184231}
185232
233+ /**
234+ * @brief implementation for initializing a light-weight process arguments info structure
235+ *
236+ * @param[in,out] ai Pointer to the arguments info structure to initialize
237+ * @param[in] str_buf_size Size of the string buffer to allocate
238+ *
239+ * @return rt_err_t
240+ * - RT_EOK on successful initialization
241+ * - -RT_ENOMEM if memory allocation fails
242+ */
186243static rt_err_t args_init (struct lwp_args_info * ai , size_t str_buf_size )
187244{
188245 void * str_buf ;
@@ -212,11 +269,28 @@ static rt_err_t args_init(struct lwp_args_info *ai, size_t str_buf_size)
212269}
213270
214271#define STR_BUF_DEFAULT_SIZE 2048
272+
273+ /**
274+ * @brief Initialize a light-weight process arguments info structure
275+ *
276+ * @param[in,out] ai Pointer to the arguments info structure to initialize
277+ *
278+ * @return rt_err_t
279+ * - RT_EOK on successful initialization
280+ * - -RT_ENOMEM if memory allocation fails
281+ *
282+ * @see args_init
283+ */
215284rt_err_t lwp_args_init (struct lwp_args_info * ai )
216285{
217286 return args_init (ai , STR_BUF_DEFAULT_SIZE );
218287}
219288
289+ /**
290+ * @brief Detach a light-weight process arguments info structure
291+ *
292+ * @param[in,out] ai Pointer to the arguments info structure to detach
293+ */
220294void lwp_args_detach (struct lwp_args_info * ai )
221295{
222296 _strvec_detach (& ai -> argv );
@@ -225,6 +299,14 @@ void lwp_args_detach(struct lwp_args_info *ai)
225299}
226300
227301#ifdef ARCH_MM_MMU
302+ /**
303+ * @brief Copy a light-weight process arguments info structure to user space
304+ *
305+ * @param[in] lwp Pointer to the light-weight process structure
306+ * @param[in] ai Pointer to the arguments info structure to copy
307+ *
308+ * @return struct process_aux* Pointer to the process auxiliary structure in user space
309+ */
228310struct process_aux * lwp_argscopy (struct rt_lwp * lwp , struct lwp_args_info * ai )
229311{
230312 int size = sizeof (rt_base_t ) * 4 ; /* store argc, argv_NULL, envp_NULL, aux_NULL */
@@ -404,6 +486,18 @@ static struct process_aux *lwp_argscopy(struct rt_lwp *lwp, int argc, char **arg
404486}
405487#endif
406488
489+ /**
490+ * @brief Put arguments or environment variables into LWP arguments info structure
491+ *
492+ * @param[in,out] args Pointer to the lwp_args_info structure to store the arguments
493+ * @param[in] strv_addr Pointer to the string array (argv/envp) to be processed
494+ * @param[in] atype Type of arguments being processed (LWP_ARGS_TYPE_ARG/LWP_ARGS_TYPE_ENVP)
495+ *
496+ * @return rt_err_t
497+ * - RT_EOK on success
498+ * - -EFAULT if user-space string access fails
499+ * - Other errors from args_append() if memory allocation fails
500+ */
407501rt_err_t lwp_args_put (struct lwp_args_info * args , const char * * strv_addr , enum lwp_args_type atype )
408502{
409503 rt_err_t error ;
@@ -450,15 +544,31 @@ rt_err_t lwp_args_put(struct lwp_args_info *args, const char **strv_addr, enum l
450544}
451545
452546/**
453- * @brief Put argument vector to args object
547+ * @brief Put command line arguments into LWP arguments info structure
548+ *
549+ * @param[in,out] args Pointer to the lwp_args_info structure to store the arguments
550+ * @param[in] argv_uaddr Pointer to the string array (argv) to be processed
551+ *
552+ * @return rt_err_t
553+ * - RT_EOK on success
554+ * - -EFAULT if user-space string access fails
555+ * - Other errors from args_append() if memory allocation fails
454556 */
455557rt_err_t lwp_args_put_argv (struct lwp_args_info * args , const char * * argv_uaddr )
456558{
457559 return lwp_args_put (args , argv_uaddr , LWP_ARGS_TYPE_ARG );
458560}
459561
460562/**
461- * @brief Put argument vector to args object
563+ * @brief Put environment variables into LWP arguments info structure
564+ *
565+ * @param[in,out] args Pointer to the lwp_args_info structure to store the arguments
566+ * @param[in] envp_uaddr Pointer to the string array (envp) to be processed
567+ *
568+ * @return rt_err_t
569+ * - RT_EOK on success
570+ * - -EFAULT if user-space string access fails
571+ * - Other errors from args_append() if memory allocation fails
462572 */
463573rt_err_t lwp_args_put_envp (struct lwp_args_info * args , const char * * envp_uaddr )
464574{
@@ -473,6 +583,24 @@ rt_err_t lwp_args_put_envp(struct lwp_args_info *args, const char **envp_uaddr)
473583#define READFILE_STAT_NEXTLINE_REACHED 0
474584#define READFILE_STAT_TRUNCATED 1
475585#define READFILE_STAT_CAN_READMORE (stat ) (stat)
586+
587+ /**
588+ * @brief Read data from a file descriptor with line handling
589+ *
590+ * @param[in] fd File descriptor to read from
591+ * @param[in] maxbytes Maximum bytes to read (buffer size - 1)
592+ * @param[out] buffer Output buffer for the read data (null-terminated)
593+ * @param[out] p_readlen Pointer to store actual bytes read (optional)
594+ *
595+ * @return int Status code:
596+ * - READFILE_STAT_NEXTLINE_REACHED when newline found
597+ * - READFILE_STAT_TRUNCATED when line truncated at word boundary
598+ * - READFILE_STAT_EOF_REACHED when EOF or error occurs
599+ *
600+ * @note Reads data from a file descriptor into a buffer, handling newlines and
601+ * truncating long lines while preserving word boundaries. Manages file
602+ * position for partial reads.
603+ */
476604static int _readfile (int fd , size_t maxbytes , char * buffer , int * p_readlen )
477605{
478606 int readlen ;
@@ -525,13 +653,33 @@ static int _readfile(int fd, size_t maxbytes, char *buffer, int *p_readlen)
525653 return stat ;
526654}
527655
656+ /**
657+ * @brief Find the start of the next word in a string
658+ *
659+ * @param[in] cp Pointer to the string to search
660+ *
661+ * @return char* Pointer to the first non-space character in the string
662+ *
663+ * @note Skips leading whitespace characters and returns a pointer to the first
664+ * non-whitespace character.
665+ */
528666static char * _find_word (char * cp )
529667{
530668 for (; (* cp == ' ' ) || (* cp == '\t' ); cp ++ )
531669 ;
532670 return cp ;
533671}
534672
673+ /**
674+ * @brief Seperate words in a string and get the next word
675+ *
676+ * @param[in] cp Pointer to the string to process
677+ *
678+ * @return char* Pointer to the next word in the string
679+ *
680+ * @note Finds the next whitespace character, seperates words, and returns a
681+ * pointer to the next word.
682+ */
535683static char * _seperate_and_get_nextword (char * cp )
536684{
537685 /* find next whitespace */
@@ -546,6 +694,20 @@ static char *_seperate_and_get_nextword(char *cp)
546694}
547695
548696#define INTERP_BUF_SIZE 128
697+ /**
698+ * @brief Load and process interpreter script for light-weight process
699+ *
700+ * @param[in,out] ai Pointer to the lwp_args_info structure to store script arguments
701+ * @param[in] filename Path to the script file to load
702+ *
703+ * @return rt_err_t Returns RT_EOK (0) on success, negative error code on failure:
704+ * - -1: General error (file open/read failure)
705+ * - Other errors from args_init() or _args_override_argv0()
706+ *
707+ * @note This function reads an interpreter script (e.g., shell script starting with #!),
708+ * extracts the interpreter path and arguments, and prepares them for process execution.
709+ * It handles script verification, argument parsing, and proper cleanup on failure.
710+ */
549711rt_err_t lwp_args_load_script (struct lwp_args_info * ai , const char * filename )
550712{
551713 rt_err_t error = -1 ;
@@ -633,6 +795,20 @@ rt_err_t lwp_args_load_script(struct lwp_args_info *ai, const char *filename)
633795 return error ;
634796}
635797
798+ /**
799+ * @brief Get command line arguments from light-weight process
800+ *
801+ * @param[in] lwp Pointer to the light-weight process structure
802+ *
803+ * @return char** Returns a NULL-terminated array of argument strings on success:
804+ * - The array and each string are allocated in kernel space
805+ * - The caller is responsible for freeing using lwp_free_command_line_args()
806+ * RT_NULL Returns NULL on failure (invalid LWP, memory allocation failure, or copy error)
807+ *
808+ * @note This function retrieves the command line arguments (argv) from a light-weight process (LWP)
809+ * and returns a NULL-terminated array of argument strings. It handles memory allocation and
810+ * proper NULL termination of the argument vector.
811+ */
636812char * * lwp_get_command_line_args (struct rt_lwp * lwp )
637813{
638814 size_t argc = 0 ;
@@ -687,6 +863,13 @@ char **lwp_get_command_line_args(struct rt_lwp *lwp)
687863 return RT_NULL ;
688864}
689865
866+ /**
867+ * @brief Print environment variables of light-weight process
868+ *
869+ * @param[in] lwp Pointer to the light-weight process structure
870+ *
871+ * @return void
872+ */
690873void lwp_print_envp (struct rt_lwp * lwp )
691874{
692875 rt_size_t envp_counts ;
@@ -703,6 +886,17 @@ void lwp_print_envp(struct rt_lwp *lwp)
703886 return ;
704887}
705888
889+ /**
890+ * @brief Get environment variables of light-weight process
891+ *
892+ * @param[in] lwp Pointer to the light-weight process structure
893+ * @param[out] penvp_counts Pointer to store the number of environment variables
894+ *
895+ * @return char** Returns a NULL-terminated array of environment variable strings on success:
896+ * - The array and each string are allocated in kernel space
897+ * - The caller is responsible for freeing using lwp_free_command_line_args()
898+ * RT_NULL Returns NULL on failure (invalid LWP, memory allocation failure, or copy error)
899+ */
706900char * * lwp_get_envp (struct rt_lwp * lwp , rt_size_t * penvp_counts )
707901{
708902 int ret , len ;
@@ -767,6 +961,13 @@ char** lwp_get_envp(struct rt_lwp *lwp, rt_size_t *penvp_counts)
767961 return p_kenvp ;
768962}
769963
964+ /**
965+ * @brief Free memory allocated for command line arguments
966+ *
967+ * @param argv Array of command line arguments to free
968+ *
969+ * @return void
970+ */
770971void lwp_free_command_line_args (char * * argv )
771972{
772973 size_t i ;
0 commit comments