diff options
Diffstat (limited to 'src/backend/port/dynloader/nextstep.c')
-rw-r--r-- | src/backend/port/dynloader/nextstep.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/src/backend/port/dynloader/nextstep.c b/src/backend/port/dynloader/nextstep.c new file mode 100644 index 00000000000..66cbba9e8ca --- /dev/null +++ b/src/backend/port/dynloader/nextstep.c @@ -0,0 +1,81 @@ +#include <mach-o/rld.h> +#include <streams/streams.h> +#include <stdlib.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; + + sprintf(symbuf, "_%s", symbol); + if (!rld_lookup(errorStream, symbuf, &symref)) + TransferError(errorStream); + CloseError(errorStream); + return (void *) symref; +} + +char * +next_dlerror(void) +{ + return lastError; +} |