适用于我的 linux/glibc。这是一个工作示例:
#!/bin/sh -eu
cat > main.c <<EOF
#include <spawn.h>
#include <sys/wait.h>
int main(int C, char **V)
{
pid_t pid;
if(0!=posix_spawnp(&pid,V[1],NULL,NULL,V+1,NULL))
return 1;
wait(0);
}
EOF
gcc main.c
cat > libspawn.c <<EOF
#define _GNU_SOURCE
#include <spawn.h>
#include <dlfcn.h>
#include <stdio.h>
typedef int spawnp_signature(pid_t *pid, const char *file,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp,
char *const argv[], char *const envp[]);
spawnp_signature posix_spwanp;
int posix_spawnp(pid_t *pid, const char *file,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp,
char *const argv[], char *const envp[])
{
fprintf(stderr, "OVERRIDE\n");
spawnp_signature *real = dlsym(RTLD_NEXT,__func__);
return real(pid,file,file_actions,attrp,argv,envp);
}
EOF
gcc -shared -fpic -o libspawn.so libspawn.c -ldl
./a.out echo hello world
LD_PRELOAD=$PWD/libspawn.so ./a.out echo hello world
第二个输出按预期打印了单词OVERRIDE。
编辑:
在使您的示例可编译后,它也适用于我。可能某些未经检查的调用在您的计算机上失败,或者您忘记链接 dl 库。
#!/bin/sh -eu
cat > main.c <<EOF
#include <spawn.h>
#include <sys/wait.h>
int main(int C, char **V)
{
pid_t pid;
if(0!=posix_spawnp(&pid,V[1],NULL,NULL,V+1,NULL))
return 1;
wait(0);
}
EOF
gcc main.c
cat > libspawn.c <<EOF
#define _GNU_SOURCE
#include <spawn.h>
#include <dlfcn.h>
#include <stdio.h>
typedef int spawnp_signature(pid_t *pid, const char *file,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp,
char *const argv[], char *const envp[]);
spawnp_signature posix_spwanp;
int posix_spawnp(pid_t *pid, const char *file,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp,
char *const argv[], char *const envp[])
{
fprintf(stderr, "OVERRIDE\n");
spawnp_signature *real = dlsym(RTLD_NEXT,__func__);
return real(pid,file,file_actions,attrp,argv,envp);
}
EOF
cat >libspawn.c <<EOF
#define _GNU_SOURCE
#include <spawn.h>
#include <dlfcn.h>
#include <stdio.h>
typedef int (*orig_posix_spawnp_t)(pid_t *pid, const char *file,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp,
char *const argv[], char *const envp[]);
typedef FILE *(*orig_fopen_t)(char const*, char const*);
int posix_spawnp(pid_t * pid, const char * file, const posix_spawn_file_actions_t * file_actions, const posix_spawnattr_t * attrp, char * const argv[], char * const envp[])
{
orig_fopen_t orig_fopen = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen");
FILE * fp = orig_fopen("/tmp/DiagnosticsAgent.log", "a");
fprintf(fp, "*** posix_spawnp(..., {");
int i;
for (i = 0; argv[i] != 0; ++ i)
fprintf(fp, "%s, ", argv[i]);
fprintf(fp, "}, ...)\n");
fclose(fp);
void * handle = dlopen("libpthread.so.0", RTLD_LAZY);
if(!handle) { perror(0); return -1; }
orig_posix_spawnp_t orig_posix_spawnp = (orig_posix_spawnp_t)dlsym(handle, "posix_spawnp");
fprintf(stderr,"OVERRIDE\t");
return orig_posix_spawnp(pid, file, file_actions, attrp, argv, envp);
}
EOF
gcc -shared -fpic -o libspawn.so libspawn.c -ldl
./a.out echo hello world
LD_PRELOAD=$PWD/libspawn.so ./a.out echo hello world