aboutsummaryrefslogtreecommitdiff
path: root/src/backend/port/dynloader/nextstep.c
blob: 09b317daf97ea07df2b29d184fcb6df1045d938a (plain)
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
#include "postgres.h"

#include "mach-o/rld.h"
#include "streams/streams.h"

static char *lastError = NULL;

static NXStream *
OpenError()
{
	return NXOpenMemory(NULL, 0, NX_WRITEONLY);
}

static void
CloseError(NXStream * s)
{
	if (s)
		NXCloseMemory(s, NX_FREEBUFFER);
}

static void
TransferError(NXStream * s)
{
	char	   *buffer;
	int			len,
				maxlen;

	if (lastError)
		free(lastError);
	NXGetMemoryBuffer(s, &buffer, &len, &maxlen);
	lastError = malloc(len + 1);
	strcpy(lastError, buffer);
}

void *
next_dlopen(char *name)
{
	int			rld_success;
	NXStream   *errorStream;
	char	   *result = NULL;
	char	  **p;

	errorStream = OpenError();
	p = calloc(2, sizeof(void *));
	p[0] = name;
	rld_success = rld_load(errorStream, NULL, p, NULL);
	free(p);

	if (!rld_success)
	{
		TransferError(errorStream);
		result = (char *) 1;
	}
	CloseError(errorStream);
	return result;
}

int
next_dlclose(void *handle)
{
	return 0;
}

void *
next_dlsym(void *handle, char *symbol)
{
	NXStream   *errorStream = OpenError();
	char		symbuf[1024];
	unsigned long symref = 0;

	snprintf(symbuf, sizeof(symbuf), "_%s", symbol);
	if (!rld_lookup(errorStream, symbuf, &symref))
		TransferError(errorStream);
	CloseError(errorStream);
	return (void *) symref;
}

char *
next_dlerror(void)
{
	return lastError;
}