summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/dietlibc/libdl/dlclose.c
blob: 6fafedcf5e99bb7d3614314f6c4d2ecb059120bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <sys/mman.h>

#include "_dl_int.h"

static void dec_referenced_libs(struct _dl_handle*dh) {
  Elf_Dyn* dyn_tab=dh->dynamic;
  int i;
  for(i=0;dyn_tab[i].d_tag;i++) {
    if (dyn_tab[i].d_tag==DT_NEEDED) {
      char *lib_name=dh->dyn_str_tab+dyn_tab[i].d_un.d_val;
#ifdef DEBUG
      pf(__FUNCTION__); pf(": lib: "); pf(lib_name); pf("\n");
#endif
      dlclose(_dl_find_lib(lib_name));
    }
  }
}

int dlclose(void*handle) {
  _dl_error_location="dlclose";
  if (handle) {
    struct _dl_handle*dh=handle;
    if (--(dh->lnk_count)) return 0;	/* not yet unreferenced */

#ifdef DEBUG
    pf(__FUNCTION__); pf(": "); pf(dh->name); pf("\n");
#endif
    if (dh->fini) dh->fini();
    dec_referenced_libs(dh);
#ifdef __DIET_LD_SO__
    if (_dl_sys_munmap(dh->mem_base,dh->mem_size)<0) return -1;
#else
    if (munmap(dh->mem_base,dh->mem_size)==-1) return -1;
#endif
    _dl_free_handle(handle);
  }
  return 0;
}