1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
/*
Copyright (c) Contributors to the Apptainer project, established as
Apptainer a Series of LF Projects LLC.
For website terms of use, trademark policy, privacy policy and other
project policies see https://lfprojects.org/policies
This software is licensed under a 3-clause BSD license. Please
consult LICENSE.md file distributed with the sources of this project
regarding your rights to use or distribute this software.
*/
/*
LD_PRELOAD wrapper to add an offset into a file read by fuse2fs.
Set OFFSETPRELOAD_FILE to the path of the file and OFFSETPRELOAD_OFFSET
to the value of the offset.
This is not general purpose, it is specific to fuse2fs.
*/
#define _GNU_SOURCE
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
static int offsetfd = -3;
static long offsetval;
ssize_t pread64(int fd, void *buf, size_t count, off_t offset) {
static off_t (*original_pread64)(int, void *, size_t, off_t) = NULL;
if (original_pread64 == NULL) {
original_pread64 = dlsym(RTLD_NEXT, "pread64");
}
if (offsetfd == fd) {
offset += offsetval;
}
return (*original_pread64)(fd, buf, count, offset);
}
ssize_t pwrite64(int fd, const void *buf, size_t count, off_t offset) {
static off_t (*original_pwrite64)(int, const void *, size_t, off_t) = NULL;
if (original_pwrite64 == NULL) {
original_pwrite64 = dlsym(RTLD_NEXT, "pwrite64");
}
if (offsetfd == fd) {
offset += offsetval;
}
return (*original_pwrite64)(fd, buf, count, offset);
}
static int ___open64(int (*original_open64)(const char *, int, int, int), const char *path, int flags1, int flags2, int flags3) {
static char *offsetpath = NULL;
if (offsetfd == -3) {
offsetfd = -2;
offsetpath = getenv("OFFSETPRELOAD_FILE");
char *valenv = getenv("OFFSETPRELOAD_OFFSET");
if (valenv != NULL) {
offsetval = atol(valenv);
}
}
int fd = (*original_open64)(path, flags1, flags2, flags3);
if (fd >= 0) {
if ((offsetpath != NULL) && (strcmp(offsetpath, path) == 0)) {
offsetfd = fd;
}
}
return fd;
}
// This is the version used by some compilations of fuse2fs
int __open64_2(const char *path, int flags1, int flags2, int flags3) {
static int (*original_open64_2)(const char*, int, int, int) = NULL;
if (original_open64_2 == NULL) {
original_open64_2 = dlsym(RTLD_NEXT, "__open64_2");
}
return ___open64(original_open64_2, path, flags1, flags2, flags3);
}
// This is more parameters than the real open64, but use that many because
// we want to use a common function with __open64_2
int open64(const char *path, int flags1, int flags2, int flags3) {
static int (*original_open64)(const char*, int, int, int) = NULL;
if (original_open64 == NULL) {
original_open64 = dlsym(RTLD_NEXT, "open64");
}
return ___open64(original_open64, path, flags1, flags2, flags3);
}
|