#include "util.h"
#include <dlfcn.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char **argv) {
int rc;
if (argc != 3) {
fprintf(stderr, "usage: %s <mount-dir> <path-to-libtest.so>\n",
argc > 0 ? argv[0] : "<program>");
return 1;
}
char const *mount_dir = argv[1];
char const *libtest_path = argv[2];
void *handle;
handle = dlopen(libtest_path, RTLD_NOW);
if (handle == NULL) {
fprintf(stderr, "failed to dlopen %s: %s\n", libtest_path, dlerror());
return 1;
}
void *_dlclose __attribute__((cleanup(close_so))) = handle;
rc = chroot(mount_dir);
if (rc < 0) {
fprintf(stderr, "failed to chroot: %s\n", strerror(errno));
return 1;
}
void *(*lookup_private)(void);
lookup_private = dlsym(handle, "lookup_private");
if (lookup_private == NULL) {
fprintf(stderr, "failed to dlsym `lookup_private`: %s\n", dlerror());
return 1;
}
int (*await_input)(void);
await_input = dlsym(handle, "await_input");
if (await_input == NULL) {
fprintf(stderr, "failed to dlsym `await_input`: %s\n", dlerror());
return 1;
}
void *private_addr = lookup_private();
pid_t pid = getpid();
rc = write(STDOUT_FILENO, &pid, sizeof(pid));
if (rc < 0) {
fprintf(stderr, "failed to write pid to stdout: %s\n", strerror(errno));
return 1;
}
rc = write(STDOUT_FILENO, &private_addr, sizeof(private_addr));
if (rc < 0) {
fprintf(stderr, "failed to write address to stdout: %s\n", strerror(errno));
return 1;
}
return await_input();
}