mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-03-23 13:13:21 +08:00
[libc][libdl] Extract name extraction to shared function and fix edge cases
Address code review feedback: 1. Extract path stripping logic into shared dlmodule_extract_name() function to avoid code duplication between dlopen() and _dlmodule_set_name(). 2. Fix edge case handling for filenames starting with dot (e.g., .hidden). 3. Add proper documentation for the new function. This ensures consistent module name extraction across all code paths. Co-authored-by: BernardXiong <1241087+BernardXiong@users.noreply.github.com>
This commit is contained in:
@@ -33,16 +33,28 @@ static struct rt_module_symtab *_rt_module_symtab_end = RT_NULL;
|
||||
#pragma section="RTMSymTab"
|
||||
#endif
|
||||
|
||||
/* set the name of module */
|
||||
static void _dlmodule_set_name(struct rt_dlmodule *module, const char *path)
|
||||
/**
|
||||
* @brief Extract module name from a file path by stripping directory and extension.
|
||||
*
|
||||
* @param path the file path (e.g., "/mnt/sdcard/apps/clock.so")
|
||||
* @param name buffer to store the extracted module name
|
||||
* @param name_size size of the name buffer
|
||||
*
|
||||
* @note This function extracts the base name without path and extension.
|
||||
* For example: "/mnt/sdcard/apps/clock.so" -> "clock"
|
||||
* For hidden files like ".hidden", the entire filename is used.
|
||||
*/
|
||||
void dlmodule_extract_name(const char *path, char *name, int name_size)
|
||||
{
|
||||
int size;
|
||||
struct rt_object *object;
|
||||
const char *first, *end, *ptr;
|
||||
const char *first, *end, *ptr, *last_dot;
|
||||
|
||||
object = &(module->parent);
|
||||
ptr = first = (char *)path;
|
||||
end = path + rt_strlen(path);
|
||||
RT_ASSERT(path != RT_NULL);
|
||||
RT_ASSERT(name != RT_NULL);
|
||||
RT_ASSERT(name_size > 0);
|
||||
|
||||
ptr = first = path;
|
||||
end = path + rt_strlen(path);
|
||||
|
||||
/* find the start of filename (after last '/') */
|
||||
while (*ptr != '\0')
|
||||
@@ -52,25 +64,44 @@ static void _dlmodule_set_name(struct rt_dlmodule *module, const char *path)
|
||||
ptr++;
|
||||
}
|
||||
|
||||
/* find extension in filename portion only (after last '/') */
|
||||
/* find last extension in filename portion only (after last '/') */
|
||||
last_dot = RT_NULL;
|
||||
ptr = first;
|
||||
while (*ptr != '\0')
|
||||
{
|
||||
if (*ptr == '.')
|
||||
end = ptr;
|
||||
last_dot = ptr;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
/* determine end position for module name */
|
||||
if (last_dot != RT_NULL && last_dot != first)
|
||||
{
|
||||
/* extension found and filename doesn't start with dot */
|
||||
end = last_dot;
|
||||
}
|
||||
/* else: no extension or filename starts with dot, use entire filename */
|
||||
|
||||
size = end - first;
|
||||
if (size <= 0)
|
||||
{
|
||||
/* no extension found, use entire filename */
|
||||
/* edge case: empty filename or only dot(s) */
|
||||
size = rt_strlen(first);
|
||||
}
|
||||
if (size >= RT_NAME_MAX) size = RT_NAME_MAX - 1;
|
||||
if (size >= name_size)
|
||||
size = name_size - 1;
|
||||
|
||||
rt_strncpy(object->name, first, size);
|
||||
object->name[size] = '\0';
|
||||
rt_strncpy(name, first, size);
|
||||
name[size] = '\0';
|
||||
}
|
||||
|
||||
/* set the name of module */
|
||||
static void _dlmodule_set_name(struct rt_dlmodule *module, const char *path)
|
||||
{
|
||||
struct rt_object *object;
|
||||
|
||||
object = &(module->parent);
|
||||
dlmodule_extract_name(path, object->name, RT_NAME_MAX);
|
||||
}
|
||||
|
||||
#define RT_MODULE_ARG_MAX 8
|
||||
|
||||
@@ -82,6 +82,8 @@ void dlmodule_exit(int ret_code);
|
||||
|
||||
struct rt_dlmodule *dlmodule_find(const char *name);
|
||||
|
||||
void dlmodule_extract_name(const char *path, char *name, int name_size);
|
||||
|
||||
rt_ubase_t dlmodule_symbol_find(const char *sym_str);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -56,41 +56,7 @@ void* dlopen(const char *filename, int flags)
|
||||
* This matches the logic in _dlmodule_set_name() so that dlmodule_find()
|
||||
* can properly locate already-loaded modules by their stored name.
|
||||
*/
|
||||
{
|
||||
const char *first, *end, *ptr;
|
||||
int size;
|
||||
|
||||
ptr = first = fullpath;
|
||||
end = fullpath + strlen(fullpath);
|
||||
|
||||
while (*ptr != '\0')
|
||||
{
|
||||
if (*ptr == '/')
|
||||
first = ptr + 1;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
/* find extension in filename portion only (after last '/') */
|
||||
ptr = first;
|
||||
while (*ptr != '\0')
|
||||
{
|
||||
if (*ptr == '.')
|
||||
end = ptr;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
size = end - first;
|
||||
if (size <= 0)
|
||||
{
|
||||
/* no extension found, use entire filename */
|
||||
size = strlen(first);
|
||||
}
|
||||
if (size >= RT_NAME_MAX)
|
||||
size = RT_NAME_MAX - 1;
|
||||
|
||||
rt_strncpy(module_name, first, size);
|
||||
module_name[size] = '\0';
|
||||
}
|
||||
dlmodule_extract_name(fullpath, module_name, RT_NAME_MAX);
|
||||
|
||||
rt_enter_critical();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user