diff options
author | midipix <writeonce@midipix.org> | 2025-06-21 17:19:36 +0000 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2025-06-21 17:19:36 +0000 |
commit | a0915299ee6c3ca770398f6fa1e59df063d6a892 (patch) | |
tree | 7e46aa46ce6d0849375eedfafb1a6e7b86854737 /src | |
parent | abbfe7adc44e7259841788ec8f5b1a69132cbcec (diff) | |
download | sltdl-a0915299ee6c3ca770398f6fa1e59df063d6a892.tar.bz2 sltdl-a0915299ee6c3ca770398f6fa1e59df063d6a892.tar.xz |
lt_dlpreload_modctl(): initial implementation.
Diffstat (limited to 'src')
-rw-r--r-- | src/core/lt_path.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/core/lt_path.c b/src/core/lt_path.c index 3fb0385..cd95e0e 100644 --- a/src/core/lt_path.c +++ b/src/core/lt_path.c @@ -605,3 +605,83 @@ const struct lt_dlentry * lt_dlloader_find(const char * ldrname) (void)ldrname; return 0; } + +static int lt_dlpreload_remove_locked(const struct lt_symdef * symtbl) +{ + struct lt_modctx * pmod; + + for (pmod=lt_modv_head; pmod ; pmod=pmod->mnext) { + if (pmod->symtbl == symtbl) { + if (pmod->mrefs > 0) { + pmod->mrefs--; + return 0; + } + + return SLTDL_ERR_MODULE_REF_COUNT; + } + } + + return SLTDL_ERR_MODULE_PTR_INVALID; +} + +static void lt_dlpreload_reset_locked(void) +{ + struct lt_modctx * pmod; + + for (pmod=lt_modv_head; pmod ; pmod=pmod->mnext) + if (pmod->symtbl && (pmod->mrefs > 0)) + pmod->mrefs = 0; +} + +static int lt_dlpreload_modctl_locked( + const struct lt_symdef * symtbl, + enum sltdl_modctl op) +{ + struct lt_modctx * modctx; + switch (op) { + case SLTDL_MODCTL_PRELOAD_ADD: + return lt_dlopen_locked(symtbl,0,0,1) + ? 0 : -1; + + case SLTDL_MODCTL_PRELOAD_REMOVE: + return lt_dlpreload_remove_locked(symtbl) + ? 0 : -1; + + case SLTDL_MODCTL_PRELOAD_DEFAULT: + if (!(modctx = lt_dlopen_locked(symtbl,0,0,(-1)))) + return -1; + + modctx->mrefs = -1; + return 0; + + case SLTDL_MODCTL_PRELOAD_RESET: + lt_dlpreload_reset_locked(); + break; + + default: + break; + } + + return 0; +} + +static int lt_dlpreload_modctl_impl( + const struct lt_symdef * symtbl, + enum sltdl_modctl op) +{ + int ret; + + lt_slock(); + + ret = lt_dlpreload_modctl_locked( + symtbl,op); + + return lt_sunlock((-1)*!!ret,ret); +} + +int lt_dlpreload_modctl( + const struct lt_symdef * symtbl, + enum sltdl_modctl op) +{ + return lt_dlpreload_modctl_impl(symtbl,op); +} |