]> granicus.if.org Git - postgresql/blob - src/backend/port/dynloader/darwin.c
pgindent run for 8.3.
[postgresql] / src / backend / port / dynloader / darwin.c
1 /*
2  * Dynamic loading support for Darwin
3  *
4  * If dlopen() is available (Darwin 10.3 and later), we just use it.
5  * Otherwise we emulate it with the older, now deprecated, NSLinkModule API.
6  *
7  * $PostgreSQL: pgsql/src/backend/port/dynloader/darwin.c,v 1.12 2007/11/15 21:14:37 momjian Exp $
8  */
9 #include "postgres.h"
10
11 #ifdef HAVE_DLOPEN
12 #include <dlfcn.h>
13 #else
14 #include <mach-o/dyld.h>
15 #endif
16
17 #include "dynloader.h"
18
19
20 #ifdef HAVE_DLOPEN
21
22 void *
23 pg_dlopen(char *filename)
24 {
25         return dlopen(filename, RTLD_NOW | RTLD_GLOBAL);
26 }
27
28 void
29 pg_dlclose(void *handle)
30 {
31         dlclose(handle);
32 }
33
34 PGFunction
35 pg_dlsym(void *handle, char *funcname)
36 {
37         /* Do not prepend an underscore: see dlopen(3) */
38         return dlsym(handle, funcname);
39 }
40
41 char *
42 pg_dlerror(void)
43 {
44         return dlerror();
45 }
46 #else                                                   /* !HAVE_DLOPEN */
47
48 /*
49  * These routines were taken from the Apache source, but were made
50  * available with a PostgreSQL-compatible license.      Kudos Wilfredo
51  * Sánchez <wsanchez@apple.com>.
52  */
53
54 static NSObjectFileImageReturnCode cofiff_result = NSObjectFileImageFailure;
55
56 void *
57 pg_dlopen(char *filename)
58 {
59         NSObjectFileImage image;
60
61         cofiff_result = NSCreateObjectFileImageFromFile(filename, &image);
62         if (cofiff_result != NSObjectFileImageSuccess)
63                 return NULL;
64         return NSLinkModule(image, filename,
65                                                 NSLINKMODULE_OPTION_BINDNOW |
66                                                 NSLINKMODULE_OPTION_RETURN_ON_ERROR);
67 }
68
69 void
70 pg_dlclose(void *handle)
71 {
72         NSUnLinkModule(handle, FALSE);
73 }
74
75 PGFunction
76 pg_dlsym(void *handle, char *funcname)
77 {
78         NSSymbol        symbol;
79         char       *symname = (char *) malloc(strlen(funcname) + 2);
80
81         sprintf(symname, "_%s", funcname);
82         if (NSIsSymbolNameDefined(symname))
83         {
84                 symbol = NSLookupAndBindSymbol(symname);
85                 free(symname);
86                 return (PGFunction) NSAddressOfSymbol(symbol);
87         }
88         else
89         {
90                 free(symname);
91                 return NULL;
92         }
93 }
94
95 char *
96 pg_dlerror(void)
97 {
98         NSLinkEditErrors c;
99         int                     errorNumber;
100         const char *fileName;
101         const char *errorString = NULL;
102
103         switch (cofiff_result)
104         {
105                 case NSObjectFileImageSuccess:
106                         /* must have failed in NSLinkModule */
107                         NSLinkEditError(&c, &errorNumber, &fileName, &errorString);
108                         if (errorString == NULL || *errorString == '\0')
109                                 errorString = "unknown link-edit failure";
110                         break;
111                 case NSObjectFileImageFailure:
112                         errorString = "failed to open object file";
113                         break;
114                 case NSObjectFileImageInappropriateFile:
115                         errorString = "inappropriate object file";
116                         break;
117                 case NSObjectFileImageArch:
118                         errorString = "object file is for wrong architecture";
119                         break;
120                 case NSObjectFileImageFormat:
121                         errorString = "object file has wrong format";
122                         break;
123                 case NSObjectFileImageAccess:
124                         errorString = "insufficient permissions for object file";
125                         break;
126                 default:
127                         errorString = "unknown failure to open object file";
128                         break;
129         }
130
131         return (char *) errorString;
132 }
133
134 #endif   /* HAVE_DLOPEN */