既然gcc生成的是一个临时文件,那么直接把C代码也写到临时文件算了
我感觉这样更好
sh-5.1$ cat main.c
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
#include <linux/limits.h>
int write_code(const char *code) {
int fd = open("/tmp", O_TMPFILE | O_RDWR, 0644);
write(fd, code, strlen(code));
return fd;
}
void compile(int fd) {
int o_fd = open("/tmp", O_TMPFILE | O_RDWR, 0755);
pid_t pid = fork();
if(!pid) {
const char *argv[] = {"gcc", "-g", "-Wall", "-x", "c", "-o", "/dev/stdout", "/dev/stdin", NULL};
dup2(fd, STDIN_FILENO); close(fd);
dup2(o_fd, STDOUT_FILENO); close(o_fd);
exit(execvp(argv[0], (void *)argv));
}
waitpid(pid, NULL, 0);
dup2(o_fd, fd); close(o_fd);
}
void run(int fd) {
char path[PATH_MAX];
snprintf(path, PATH_MAX, "/proc/self/fd/%d", fd);
int new_fd = open(path, O_RDONLY); // fexecve 要求 fd 是 O_RDONLY
dup2(new_fd, fd);
pid_t pid = fork();
if(!pid) {
//const char *argv[] = {NULL};
const char *argv[] = {"fexecve", "+", "1234", "5678", "sum", NULL};
const char *envp[] = {NULL};
exit(fexecve(fd, (void *)argv, (void *)envp));
}
waitpid(pid, NULL, 0);
}
int main(void) {
char code[] =
"#include <stdio.h>\n"
"\n"
"int main(int argc, char *argv[]) {\n"
" for(size_t i = 0; i < argc; ++i) {\n"
" puts(argv[i]);\n"
" }\n"
" return 0;\n"
"}";
int fd = write_code(code);
compile(fd); run(fd); close(fd);
return 0;
}
sh-5.1$ gcc -g -Wall -o main main.c
sh-5.1$ ./main
fexecve
+
1234
5678
sum
sh-5.1$
|