geany  1.38
About: Geany is a text editor (using GTK2) with basic features of an integrated development environment (syntax highlighting, code folding, symbol name auto-completion, ...). F: office T: editor programming GTK+ IDE
  Fossies Dox: geany-1.38.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

prefix.c
Go to the documentation of this file.
1/*
2 * BinReloc - a library for creating relocatable executables
3 * Written by: Mike Hearn <mike@theoretic.com>
4 * Hongli Lai <h.lai@chello.nl>
5 * http://autopackage.org/
6 *
7 * This source code is public domain. You can relicense this code
8 * under whatever license you want.
9 *
10 * NOTE: if you're using C++ and are getting "undefined reference
11 * to br_*", try renaming prefix.c to prefix.cpp
12 */
13
14#ifdef HAVE_CONFIG_H
15# include "config.h"
16#endif
17
18/*
19 * enrico - all the code below is only compiled and used if ENABLE_BINRELOC is set in config.h,
20 * this only happens if configure option --enable-binreloc was used
21 */
22#ifdef ENABLE_BINRELOC
23
24
25
26#include <stdlib.h>
27#include <stdio.h>
28#include <limits.h>
29#include <string.h>
30#include <glib.h>
31#include "prefix.h"
32
33
34#undef NULL
35#define NULL ((void *) 0)
36
37#ifdef __GNUC__
38 #define br_return_val_if_fail(expr,val) if (!(expr)) {fprintf (stderr, "** BinReloc (%s): assertion %s failed\n", __PRETTY_FUNCTION__, #expr); return val;}
39#else
40 #define br_return_val_if_fail(expr, val) if (!(expr)) return val
41#endif /* __GNUC__ */
42
43
44#include <sys/types.h>
45#include <sys/stat.h>
46#include <sys/param.h>
47#include <unistd.h>
48
49
50static char *br_last_value = (char*)NULL;
51
52
53static void
54br_free_last_value (void)
55{
56 if (br_last_value)
57 free (br_last_value);
58}
59
60
61/**
62 * br_thread_local_store:
63 * str: A dynamically allocated string.
64 * Returns: str. This return value must not be freed.
65 *
66 * Store str in a thread-local variable and return str. The next
67 * you run this function, that variable is freed too.
68 * This function is created so you don't have to worry about freeing
69 * strings.
70 *
71 * Example:
72 * char *foo;
73 * foo = thread_local_store (strdup ("hello")); --> foo == "hello"
74 * foo = thread_local_store (strdup ("world")); --> foo == "world"; "hello" is now freed.
75 */
76const char *
77br_thread_local_store (char *str)
78{
79 static int initialized = 0;
80
81
82 if (!initialized)
83 {
84 atexit (br_free_last_value);
85 initialized = 1;
86 }
87
88 if (br_last_value)
89 free (br_last_value);
90 br_last_value = str;
91
92 return (const char *) str;
93}
94
95
96/**
97 * br_locate:
98 * symbol: A symbol that belongs to the app/library you want to locate.
99 * Returns: A newly allocated string containing the full path of the
100 * app/library that func belongs to, or NULL on error. This
101 * string should be freed when not when no longer needed.
102 *
103 * Finds out to which application or library symbol belongs, then locate
104 * the full path of that application or library.
105 * Note that symbol cannot be a pointer to a function. That will not work.
106 *
107 * Example:
108 * --> main.c
109 * #include "prefix.h"
110 * #include "libfoo.h"
111 *
112 * int main (int argc, char *argv[]) {
113 * printf ("Full path of this app: %s\n", br_locate (&argc));
114 * libfoo_start ();
115 * return 0;
116 * }
117 *
118 * --> libfoo.c starts here
119 * #include "prefix.h"
120 *
121 * void libfoo_start () {
122 * --> "" is a symbol that belongs to libfoo (because it's called
123 * --> from libfoo_start()); that's why this works.
124 * printf ("libfoo is located in: %s\n", br_locate (""));
125 * }
126 */
127char *
128br_locate (void *symbol)
129{
130 char line[5000];
131 FILE *f;
132 char *path;
133
134 br_return_val_if_fail (symbol != NULL, NULL);
135
136 f = fopen ("/proc/self/maps", "r");
137 if (!f)
138 return NULL;
139
140 while (!feof (f))
141 {
142 unsigned long start, end;
143
144 if (!fgets (line, sizeof (line), f))
145 continue;
146 if (!strstr (line, " r-xp ") || !strchr (line, '/'))
147 continue;
148
149 sscanf (line, "%lx-%lx ", &start, &end);
150 if (symbol >= (void *) start && symbol < (void *) end)
151 {
152 char *tmp;
153 gsize len;
154
155 /* Extract the filename; it is always an absolute path */
156 path = strchr (line, '/');
157
158 /* Get rid of the newline */
159 tmp = strrchr (path, '\n');
160 if (tmp) *tmp = 0;
161
162 /* Get rid of "(deleted)" */
163 len = strlen (path);
164 if (len > 10 && strcmp (path + len - 10, " (deleted)") == 0)
165 {
166 tmp = path + len - 10;
167 *tmp = 0;
168 }
169
170 fclose(f);
171 return strdup (path);
172 }
173 }
174
175 fclose (f);
176 return NULL;
177}
178
179
180/**
181 * br_extract_prefix:
182 * path: The full path of an executable or library.
183 * Returns: The prefix, or NULL on error. This string should be freed when no longer needed.
184 *
185 * Extracts the prefix from path. This function assumes that your executable
186 * or library is installed in an LSB-compatible directory structure.
187 *
188 * Example:
189 * br_extract_prefix ("/usr/bin/gnome-panel"); --> Returns "/usr"
190 * br_extract_prefix ("/usr/local/lib/libfoo.so"); --> Returns "/usr/local"
191 * br_extract_prefix ("/usr/local/libfoo.so"); --> Returns "/usr"
192 */
193char *
194br_extract_prefix (const char *path)
195{
196 char *end, *tmp, *result;
197
198 br_return_val_if_fail (path != (char*)NULL, (char*)NULL);
199
200 if (!*path) return strdup ("/");
201 end = strrchr (path, '/');
202 if (!end) return strdup (path);
203
204 tmp = g_strndup ((char *) path, end - path);
205 if (!*tmp)
206 {
207 g_free (tmp);
208 return strdup ("/");
209 }
210 end = strrchr (tmp, '/');
211 if (!end) return tmp;
212
213 result = g_strndup (tmp, end - tmp);
214 g_free (tmp);
215
216 if (!*result)
217 {
218 g_free (result);
219 result = strdup ("/");
220 }
221
222 return result;
223}
224
225
226/**
227 * br_locate_prefix:
228 * symbol: A symbol that belongs to the app/library you want to locate.
229 * Returns: A prefix. This string should be freed when no longer needed.
230 *
231 * Locates the full path of the app/library that symbol belongs to, and return
232 * the prefix of that path, or NULL on error.
233 * Note that symbol cannot be a pointer to a function. That will not work.
234 *
235 * Example:
236 * --> This application is located in /usr/bin/foo
237 * br_locate_prefix (&argc); --> returns: "/usr"
238 */
239char *
240br_locate_prefix (void *symbol)
241{
242 char *path, *prefix;
243
244 br_return_val_if_fail (symbol != NULL, NULL);
245
246 path = br_locate (symbol);
247 if (!path) return NULL;
248
249 prefix = br_extract_prefix (path);
250 free (path);
251 return prefix;
252}
253
254
255/**
256 * br_prepend_prefix:
257 * symbol: A symbol that belongs to the app/library you want to locate.
258 * path: The path that you want to prepend the prefix to.
259 * Returns: The new path, or NULL on error. This string should be freed when no
260 * longer needed.
261 *
262 * Gets the prefix of the app/library that symbol belongs to. Prepend that prefix to path.
263 * Note that symbol cannot be a pointer to a function. That will not work.
264 *
265 * Example:
266 * --> The application is /usr/bin/foo
267 * br_prepend_prefix (&argc, "/share/foo/data.png"); --> Returns "/usr/share/foo/data.png"
268 */
269char *
270br_prepend_prefix (void *symbol, char *path)
271{
272 char *tmp, *newpath;
273
274 br_return_val_if_fail (symbol != NULL, NULL);
275 br_return_val_if_fail (path != NULL, NULL);
276
277 tmp = br_locate_prefix (symbol);
278 if (!tmp) return NULL;
279
280 if (strcmp (tmp, "/") == 0)
281 newpath = strdup (path);
282 else
283 newpath = g_strconcat (tmp, path, NULL);
284
285 free (tmp);
286 return newpath;
287}
288
289
290#else /* ENABLE_BINRELOC */
291
293
294#endif /* ENABLE_BINRELOC */
vString * line
Definition: geany_cobol.c:133
int iso_c_forbids_an_empty_source_file
Definition: prefix.c:292
#define NULL
Definition: rbtree.h:150
char * strstr(const char *str, const char *substr)
Definition: routines.c:304