Interestingly, you should say:
The key point is that I need everything except the first argv argument. So I can’t just send it to other processes, as I actually use it as an execv argument
This is very similar to what I do when I want to set LD_LIBRARY_PATH and then run the binary using my own copy of ld.so, so that the common shared libraries by default will not be used. The argument for execve is my copy of ld.so, but after running the real binaries, I want argv to look normal (and the environment). Here's how I did it on Linux:
include <stdlib.h> #include <stdio.h> #define PYBINARY "/data1/packages/python272/bin/python" #define LDSO "/data1/packages/python272/lib/ld-linux-x86-64.so.2" #define MYLIBS "/data1/packages/python272/lib" extern char **environ; main(int argc, char **argv, char **envp) { int retcode; char **e; char **myargv; setenv("LD_LIBRARY_PATH",MYLIBS,1); setenv("_",PYBINARY,1); /* copy argv */ int i = 0; myargv = (char **)malloc(sizeof(char *) * 100); for(;argv[i] != NULL; i++) { myargv[i+1] = (char *)malloc(sizeof(char) * (strlen(argv[i]) + 1)); memcpy(myargv[i+1], argv[i], strlen(argv[i])); } myargv[i+1] = NULL; myargv[0] = LDSO; myargv[1] = PYBINARY; e = myargv; while (*e != NULL){ printf("arg: %s\n",*e++); } retcode = execve(LDSO, myargv, environ); perror("exec2: execve() failed"); exit(1); }
If you put this in test.py:
import sys print sys.argv import os print os.environ["_"]
and run it with python -i test.py , you will get the same results as ./mypy -i test.py , so nothing that depends on argv or envp will be broken.
source share