Annotation of embedaddon/sudo/compat/dlopen.c, revision 1.1.1.2
1.1 misho 1: /*
2: * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
3: *
4: * Permission to use, copy, modify, and distribute this software for any
5: * purpose with or without fee is hereby granted, provided that the above
6: * copyright notice and this permission notice appear in all copies.
7: *
8: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15: */
16:
17: #include <config.h>
18:
19: #include <sys/types.h>
20:
21: #include <stdio.h>
22: #ifdef STDC_HEADERS
23: # include <stdlib.h>
24: # include <stddef.h>
25: #else
26: # ifdef HAVE_STDLIB_H
27: # include <stdlib.h>
28: # endif
29: #endif /* STDC_HEADERS */
30: #ifdef HAVE_STRING_H
31: # include <string.h>
32: #endif /* HAVE_STRING_H */
33: #ifdef HAVE_STRINGS_H
34: # include <strings.h>
35: #endif /* HAVE_STRINGS_H */
36: #include <errno.h>
37:
38: #include "compat/dlfcn.h"
39: #include "missing.h"
40:
41: #ifdef HAVE_SHL_LOAD
42: /*
43: * Emulate dlopen() using shl_load().
44: */
45: #include <dl.h>
46:
47: #ifndef DYNAMIC_PATH
48: # define DYNAMIC_PATH 0
49: #endif
50:
51: void *
52: sudo_dlopen(const char *path, int mode)
53: {
54: int flags = DYNAMIC_PATH;
55:
56: if (mode == 0)
57: mode = RTLD_LAZY; /* default behavior */
58:
59: /* We don't support RTLD_GLOBAL or RTLD_LOCAL yet. */
60: if (ISSET(mode, RTLD_LAZY))
61: flags |= BIND_DEFERRED;
62: if (ISSET(mode, RTLD_NOW))
63: flags |= BIND_IMMEDIATE;
64:
65: return (void *)shl_load(path, flags, 0L);
66: }
67:
68: int
69: sudo_dlclose(void *handle)
70: {
71: return shl_unload((shl_t)handle);
72: }
73:
74: void *
75: sudo_dlsym(void *vhandle, const char *symbol)
76: {
77: shl_t handle = vhandle;
78: void *value = NULL;
79:
1.1.1.2 ! misho 80: /*
! 81: * Note that the behavior of of RTLD_NEXT and RTLD_SELF
! 82: * differs from most implementations when called from
! 83: * a shared library.
! 84: */
! 85: if (vhandle == RTLD_NEXT) {
! 86: /* Iterate over all shared libs looking for symbol. */
! 87: struct shl_descriptor *desc;
! 88: int idx = 0;
! 89: while (shl_get(idx++, &desc) == 0) {
! 90: if (shl_findsym(&desc->handle, symbol, TYPE_UNDEFINED, &value) == 0)
! 91: break;
! 92: }
! 93: } else {
! 94: if (vhandle == RTLD_DEFAULT)
! 95: handle = NULL;
! 96: else if (vhandle == RTLD_SELF)
! 97: handle = PROG_HANDLE;
! 98: (void)shl_findsym(&handle, symbol, TYPE_UNDEFINED, &value);
! 99: }
1.1 misho 100:
101: return value;
102: }
103:
104: char *
105: sudo_dlerror(void)
106: {
107: return strerror(errno);
108: }
109:
110: #else /* !HAVE_SHL_LOAD */
111:
112: /*
113: * Emulate dlopen() using a static list of symbols compiled into sudo.
114: */
115:
116: struct sudo_preload_table {
117: const char *name;
118: void *address;
119: };
120: extern struct sudo_preload_table sudo_preload_table[];
121:
122: void *
123: sudo_dlopen(const char *path, int mode)
124: {
125: return (void *)path;
126: }
127:
128: int
129: sudo_dlclose(void *handle)
130: {
131: return 0;
132: }
133:
134: void *
135: sudo_dlsym(void *handle, const char *symbol)
136: {
137: struct sudo_preload_table *sym;
138:
1.1.1.2 ! misho 139: if (symbol != RTLD_NEXT && symbol != RTLD_DEFAULT && symbol != RTLD_SELF) {
! 140: for (sym = sudo_preload_table; sym->name != NULL; sym++) {
! 141: if (strcmp(symbol, sym->name) == 0)
! 142: return sym->address;
! 143: }
1.1 misho 144: }
145: return NULL;
146: }
147:
148: char *
149: sudo_dlerror(void)
150: {
151: return strerror(errno);
152: }
153:
154: #endif /* HAVE_SHL_LOAD */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>