Annotation of embedaddon/sudo/compat/dlopen.c, revision 1.1.1.3
1.1 misho 1: /*
1.1.1.3 ! misho 2: * Copyright (c) 2010, 2012-2013 Todd C. Miller <Todd.Miller@courtesan.com>
1.1 misho 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:
1.1.1.3 ! misho 19: #ifndef HAVE_DLOPEN
! 20:
1.1 misho 21: #include <sys/types.h>
22:
23: #include <stdio.h>
24: #ifdef STDC_HEADERS
25: # include <stdlib.h>
26: # include <stddef.h>
27: #else
28: # ifdef HAVE_STDLIB_H
29: # include <stdlib.h>
30: # endif
31: #endif /* STDC_HEADERS */
32: #ifdef HAVE_STRING_H
33: # include <string.h>
34: #endif /* HAVE_STRING_H */
35: #ifdef HAVE_STRINGS_H
36: # include <strings.h>
37: #endif /* HAVE_STRINGS_H */
38: #include <errno.h>
39:
40: #include "compat/dlfcn.h"
41: #include "missing.h"
42:
43: #ifdef HAVE_SHL_LOAD
44: /*
45: * Emulate dlopen() using shl_load().
46: */
47: #include <dl.h>
48:
49: #ifndef DYNAMIC_PATH
50: # define DYNAMIC_PATH 0
51: #endif
52:
53: void *
54: sudo_dlopen(const char *path, int mode)
55: {
1.1.1.3 ! misho 56: int flags = DYNAMIC_PATH | BIND_VERBOSE;
1.1 misho 57:
58: if (mode == 0)
59: mode = RTLD_LAZY; /* default behavior */
60:
61: /* We don't support RTLD_GLOBAL or RTLD_LOCAL yet. */
62: if (ISSET(mode, RTLD_LAZY))
63: flags |= BIND_DEFERRED;
64: if (ISSET(mode, RTLD_NOW))
65: flags |= BIND_IMMEDIATE;
66:
67: return (void *)shl_load(path, flags, 0L);
68: }
69:
70: int
71: sudo_dlclose(void *handle)
72: {
73: return shl_unload((shl_t)handle);
74: }
75:
76: void *
77: sudo_dlsym(void *vhandle, const char *symbol)
78: {
79: shl_t handle = vhandle;
80: void *value = NULL;
81:
1.1.1.2 misho 82: /*
83: * Note that the behavior of of RTLD_NEXT and RTLD_SELF
84: * differs from most implementations when called from
85: * a shared library.
86: */
87: if (vhandle == RTLD_NEXT) {
88: /* Iterate over all shared libs looking for symbol. */
89: struct shl_descriptor *desc;
90: int idx = 0;
91: while (shl_get(idx++, &desc) == 0) {
92: if (shl_findsym(&desc->handle, symbol, TYPE_UNDEFINED, &value) == 0)
93: break;
94: }
95: } else {
96: if (vhandle == RTLD_DEFAULT)
97: handle = NULL;
98: else if (vhandle == RTLD_SELF)
99: handle = PROG_HANDLE;
100: (void)shl_findsym(&handle, symbol, TYPE_UNDEFINED, &value);
101: }
1.1 misho 102:
103: return value;
104: }
105:
106: char *
107: sudo_dlerror(void)
108: {
109: return strerror(errno);
110: }
111:
112: #else /* !HAVE_SHL_LOAD */
113:
114: /*
115: * Emulate dlopen() using a static list of symbols compiled into sudo.
116: */
117:
118: struct sudo_preload_table {
119: const char *name;
120: void *address;
121: };
122: extern struct sudo_preload_table sudo_preload_table[];
123:
124: void *
125: sudo_dlopen(const char *path, int mode)
126: {
127: return (void *)path;
128: }
129:
130: int
131: sudo_dlclose(void *handle)
132: {
133: return 0;
134: }
135:
136: void *
137: sudo_dlsym(void *handle, const char *symbol)
138: {
139: struct sudo_preload_table *sym;
140:
1.1.1.2 misho 141: if (symbol != RTLD_NEXT && symbol != RTLD_DEFAULT && symbol != RTLD_SELF) {
142: for (sym = sudo_preload_table; sym->name != NULL; sym++) {
143: if (strcmp(symbol, sym->name) == 0)
144: return sym->address;
145: }
1.1 misho 146: }
147: return NULL;
148: }
149:
150: char *
151: sudo_dlerror(void)
152: {
153: return strerror(errno);
154: }
155: #endif /* HAVE_SHL_LOAD */
1.1.1.3 ! misho 156: #endif /* HAVE_DLOPEN */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>