even more path changes
[debian/sudo] / compat / dlopen.c
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
80     (void)shl_findsym(&handle, symbol, TYPE_UNDEFINED, &value);
81
82     return value;
83 }
84
85 char *
86 sudo_dlerror(void)
87 {
88     return strerror(errno);
89 }
90
91 #else /* !HAVE_SHL_LOAD */
92
93 /*
94  * Emulate dlopen() using a static list of symbols compiled into sudo.
95  */
96
97 struct sudo_preload_table {
98     const char *name;
99     void *address;
100 };
101 extern struct sudo_preload_table sudo_preload_table[];
102
103 void *
104 sudo_dlopen(const char *path, int mode)
105 {
106     return (void *)path;
107 }
108
109 int
110 sudo_dlclose(void *handle)
111 {
112     return 0;
113 }
114
115 void *
116 sudo_dlsym(void *handle, const char *symbol)
117 {
118     struct sudo_preload_table *sym;
119
120     for (sym = sudo_preload_table; sym->name != NULL; sym++) {
121         if (strcmp(symbol, sym->name) == 0)
122             return sym->address;
123     }
124     return NULL;
125 }
126
127 char *
128 sudo_dlerror(void)
129 {
130     return strerror(errno);
131 }
132
133 #endif /* HAVE_SHL_LOAD */