Files
komp_ac/packaging/musl/postgresql-launcher.c

93 lines
2.8 KiB
C

#define _GNU_SOURCE
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static void fail(const char *message)
{
fprintf(stderr, "embedded PostgreSQL launcher: %s\n", message);
exit(127);
}
static void join_path(char *destination, size_t capacity, const char *left, const char *right)
{
int length = snprintf(destination, capacity, "%s/%s", left, right);
if (length < 0 || (size_t) length >= capacity)
fail("installation path is too long");
}
int main(int argc, char **argv)
{
char executable[PATH_MAX];
ssize_t executable_length = readlink("/proc/self/exe", executable, sizeof(executable) - 1);
if (executable_length < 0) {
perror("embedded PostgreSQL launcher: /proc/self/exe");
return 127;
}
executable[executable_length] = '\0';
char *tool = strrchr(executable, '/');
if (tool == NULL || tool[1] == '\0')
fail("cannot determine the requested PostgreSQL tool");
tool++;
char root[PATH_MAX];
if ((size_t) executable_length >= sizeof(root))
fail("installation path is too long");
memcpy(root, executable, (size_t) executable_length + 1);
char *bin_separator = strrchr(root, '/');
if (bin_separator == NULL)
fail("cannot determine the PostgreSQL installation directory");
*bin_separator = '\0';
char *root_separator = strrchr(root, '/');
if (root_separator == NULL)
fail("cannot determine the PostgreSQL installation directory");
*root_separator = '\0';
char loader[PATH_MAX];
char library_path[PATH_MAX];
char real_tool[PATH_MAX];
join_path(loader, sizeof(loader), root, "lib/ld-musl-x86_64.so.1");
join_path(library_path, sizeof(library_path), root, "lib");
char real_tool_relative[PATH_MAX];
int relative_length = snprintf(
real_tool_relative,
sizeof(real_tool_relative),
"libexec/%s",
tool
);
if (relative_length < 0 || (size_t) relative_length >= sizeof(real_tool_relative))
fail("tool path is too long");
join_path(real_tool, sizeof(real_tool), root, real_tool_relative);
char **loader_argv = calloc((size_t) argc + 6, sizeof(char *));
if (loader_argv == NULL) {
perror("embedded PostgreSQL launcher: calloc");
return 127;
}
loader_argv[0] = loader;
loader_argv[1] = "--library-path";
loader_argv[2] = library_path;
loader_argv[3] = "--argv0";
loader_argv[4] = executable;
loader_argv[5] = real_tool;
for (int index = 1; index < argc; index++)
loader_argv[index + 5] = argv[index];
execv(loader, loader_argv);
fprintf(
stderr,
"embedded PostgreSQL launcher: cannot execute %s: %s\n",
real_tool,
strerror(errno)
);
return 127;
}