1 /*-------------------------------------------------------------------------
2  *
3  * dlopen.c
4  *	  dynamic loader for platforms without dlopen()
5  *
6  * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *	  src/port/dlopen.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 
16 #include "c.h"
17 
18 #if defined(__hpux)
19 
20 /* System includes */
21 #include <a.out.h>
22 #include <dl.h>
23 
24 void *
dlopen(const char * file,int mode)25 dlopen(const char *file, int mode)
26 {
27 	int			flags = 0;
28 
29 	if (mode & RTLD_NOW)
30 		flags |= BIND_IMMEDIATE;
31 #ifdef NOT_USED
32 	if (mode & RTLD_LAZY)
33 		flags |= BIND_DEFERRED;
34 #endif
35 
36 	return shl_load(file, flags | BIND_VERBOSE, 0L);
37 }
38 
39 void *
dlsym(void * handle,const char * symbol)40 dlsym(void *handle, const char *symbol)
41 {
42 	void	   *value;
43 
44 	if (shl_findsym((shl_t *) & handle, symbol, TYPE_PROCEDURE, &value) == -1)
45 		return NULL;
46 	return value;
47 }
48 
49 int
dlclose(void * handle)50 dlclose(void *handle)
51 {
52 	return shl_unload((shl_t) handle);
53 }
54 
55 char *
dlerror(void)56 dlerror(void)
57 {
58 	static char errmsg[] = "shl_load failed";
59 
60 	if (errno)
61 		return strerror(errno);
62 
63 	return errmsg;
64 }
65 
66 #elif defined(WIN32)
67 
68 static char last_dyn_error[512];
69 
70 static void
set_dl_error(void)71 set_dl_error(void)
72 {
73 	DWORD		err = GetLastError();
74 
75 	if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS |
76 					  FORMAT_MESSAGE_FROM_SYSTEM,
77 					  NULL,
78 					  err,
79 					  MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
80 					  last_dyn_error,
81 					  sizeof(last_dyn_error) - 1,
82 					  NULL) == 0)
83 	{
84 		snprintf(last_dyn_error, sizeof(last_dyn_error) - 1,
85 				 "unknown error %lu", err);
86 	}
87 }
88 
89 char *
dlerror(void)90 dlerror(void)
91 {
92 	if (last_dyn_error[0])
93 		return last_dyn_error;
94 	else
95 		return NULL;
96 }
97 
98 int
dlclose(void * handle)99 dlclose(void *handle)
100 {
101 	if (!FreeLibrary((HMODULE) handle))
102 	{
103 		set_dl_error();
104 		return 1;
105 	}
106 	last_dyn_error[0] = 0;
107 	return 0;
108 }
109 
110 void *
dlsym(void * handle,const char * symbol)111 dlsym(void *handle, const char *symbol)
112 {
113 	void	   *ptr;
114 
115 	ptr = GetProcAddress((HMODULE) handle, symbol);
116 	if (!ptr)
117 	{
118 		set_dl_error();
119 		return NULL;
120 	}
121 	last_dyn_error[0] = 0;
122 	return ptr;
123 }
124 
125 void *
dlopen(const char * file,int mode)126 dlopen(const char *file, int mode)
127 {
128 	HMODULE		h;
129 	int			prevmode;
130 
131 	/* Disable popup error messages when loading DLLs */
132 	prevmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
133 	h = LoadLibrary(file);
134 	SetErrorMode(prevmode);
135 
136 	if (!h)
137 	{
138 		set_dl_error();
139 		return NULL;
140 	}
141 	last_dyn_error[0] = 0;
142 	return (void *) h;
143 }
144 
145 #endif
146