aboutsummaryrefslogtreecommitdiff
path: root/preload.c
blob: 1665515366c763f2f3be4285ac02b697956b2fb0 (plain)
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
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

static const char *munge(const char *n) {
    static const char *e = NULL;
    static size_t elen;
    if (!e) {
        e = getenv("WIX");
        if (!e)
            return n;
        elen = strlen(e);
    }

    const char *last_slash = strrchr(n, '/');
    if (!last_slash)
        return n;
    if (last_slash - n > elen && !strncmp(last_slash - elen, e, elen))
        return last_slash - elen;
    return n;
}

#define dofunc(rettype,sym,proto,proto2)        \
        rettype sym proto {                     \
            rettype (*real) proto;              \
            real = dlsym(RTLD_NEXT, #sym);      \
            fname = munge(fname);               \
            return real proto2;                 \
        }

dofunc(int,open,(const char *fname,int flags,mode_t mode),(fname,flags,mode))
dofunc(int,open64,(const char *fname,int flags,mode_t mode),(fname,flags,mode))
dofunc(int,__open,(const char *fname,int flags,mode_t mode),(fname,flags,mode))
dofunc(int,__open64,(const char *fname,int flags,mode_t mode),(fname,flags,mode))
dofunc(int,stat,(const char *fname,struct stat *sbuf),(fname,sbuf))
dofunc(int,lstat,(const char *fname,struct stat *sbuf),(fname,sbuf))
dofunc(int,access,(const char *fname,int mode),(fname,mode))