portable server with embedded for musl has different feature
This commit is contained in:
92
packaging/musl/postgresql-launcher.c
Normal file
92
packaging/musl/postgresql-launcher.c
Normal file
@@ -0,0 +1,92 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user