#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static const char *baked_args[] = {
FUSELAGE_BUNDLE_ARGS
NULL
};
static int baked_argc(void) {
int n = 0;
while (baked_args[n] != NULL) n++;
return n;
}
static const char *substitute_self_path(const char *arg, const char *self_path) {
static const char token[] = "/proc/self/exe";
const size_t token_len = sizeof(token) - 1;
int count = 0;
for (const char *p = strstr(arg, token); p != NULL; p = strstr(p + token_len, token)) {
count++;
}
if (count == 0) {
return arg;
}
const size_t self_len = strlen(self_path);
char *out = malloc(strlen(arg) + (size_t)count * self_len + 1);
if (out == NULL) {
fprintf(stderr, "fuselage stub: out of memory\n");
exit(1);
}
char *dst = out;
const char *src = arg;
for (const char *p = strstr(src, token); p != NULL; p = strstr(src, token)) {
size_t prefix = (size_t)(p - src);
memcpy(dst, src, prefix);
dst += prefix;
memcpy(dst, self_path, self_len);
dst += self_len;
src = p + token_len;
}
strcpy(dst, src); return out;
}
int main(int argc, char *argv[]) {
char self_path[4096];
ssize_t len = readlink("/proc/self/exe", self_path, sizeof(self_path) - 1);
if (len < 0) {
fprintf(stderr, "fuselage stub: readlink /proc/self/exe: %s\n", strerror(errno));
return 1;
}
self_path[len] = '\0';
int n_baked = baked_argc();
int baked_has_dashdash = 0;
for (int j = 0; j < n_baked; j++) {
if (strcmp(baked_args[j], "--") == 0) {
baked_has_dashdash = 1;
break;
}
}
int n_user = argc - 1;
int total = 1 + n_baked + (baked_has_dashdash ? 0 : 1) + n_user + 1;
const char **new_argv = malloc(total * sizeof(char *));
if (new_argv == NULL) {
fprintf(stderr, "fuselage stub: out of memory\n");
return 1;
}
int i = 0;
new_argv[i++] = "fuselage";
for (int j = 0; j < n_baked; j++) {
new_argv[i++] = substitute_self_path(baked_args[j], self_path);
}
if (!baked_has_dashdash) {
new_argv[i++] = "--";
}
for (int j = 1; j < argc; j++) {
new_argv[i++] = argv[j];
}
new_argv[i] = NULL;
execvp("fuselage", (char *const *)new_argv);
fprintf(stderr, "fuselage stub: exec fuselage: %s\n", strerror(errno));
return 127;
}