~vcs-imports/mammoth-replicator/trunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*-------------------------------------------------------------------------
 *
 * linux.c
 *	  Dynamic Loader for Postgres for Linux, generated from those for
 *	  Ultrix.
 *
 *	  You need to install the dld library on your Linux system!
 *
 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  $PostgreSQL: pgsql/src/backend/port/dynloader/linux.c,v 1.30 2004-12-31 22:00:32 pgsql Exp $
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#ifdef HAVE_DLD_H
#include <dld.h>
#endif

#include "dynloader.h"
#include "miscadmin.h"


#ifndef HAVE_DLOPEN

void *
pg_dlopen(char *filename)
{
#ifndef HAVE_DLD_H
	elog(ERROR, "dynamic load not supported");
	return NULL;
#else
	static int	dl_initialized = 0;

	/*
	 * initializes the dynamic loader with the executable's pathname.
	 * (only needs to do this the first time pg_dlopen is called.)
	 */
	if (!dl_initialized)
	{
		if (dld_init(dld_find_executable(my_exec_path)))
			return NULL;

		/*
		 * if there are undefined symbols, we want dl to search from the
		 * following libraries also.
		 */
		dl_initialized = 1;
	}

	/*
	 * link the file, then check for undefined symbols!
	 */
	if (dld_link(filename))
		return NULL;

	/*
	 * If undefined symbols: try to link with the C and math libraries!
	 * This could be smarter, if the dynamic linker was able to handle
	 * shared libs!
	 */
	if (dld_undefined_sym_count > 0)
	{
		if (dld_link("/usr/lib/libc.a"))
		{
			elog(WARNING, "could not link C library");
			return NULL;
		}
		if (dld_undefined_sym_count > 0)
		{
			if (dld_link("/usr/lib/libm.a"))
			{
				elog(WARNING, "could not link math library");
				return NULL;
			}
			if (dld_undefined_sym_count > 0)
			{
				int			count = dld_undefined_sym_count;
				char	  **list = dld_list_undefined_sym();

				/* list the undefined symbols, if any */
				do
				{
					elog(WARNING, "\"%s\" is undefined", *list);
					list++;
					count--;
				} while (count > 0);

				dld_unlink_by_file(filename, 1);
				return NULL;
			}
		}
	}

	return (void *) strdup(filename);
#endif
}

PGFunction
pg_dlsym(void *handle, char *funcname)
{
#ifndef HAVE_DLD_H
	return NULL;
#else
	return (PGFunction) dld_get_func((funcname));
#endif
}

void
pg_dlclose(void *handle)
{
#ifndef HAVE_DLD_H
#else
	dld_unlink_by_file(handle, 1);
	free(handle);
#endif
}

char *
pg_dlerror(void)
{
#ifndef HAVE_DLD_H
	return "dynaloader unspported";
#else
	return dld_strerror(dld_errno);
#endif
}

#endif   /* !HAVE_DLOPEN */