You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C引导程序中使用fexecve替代system编译运行子C程序

修复方案

核心错误点

  • 编译调用配置错误:open("usr/bin/cc")路径拼写错误缺少开头/,且未传入./math.c -o math等必要编译参数,实际没有生成可执行的math文件
  • 执行目标错误:调用fexecve时传入的fd是math.c源码文件的描述符,并非编译生成的可执行文件math,源码本身不可执行自然调用失败
  • 传参不规范:执行math的argv数组末尾未加NULL作为终止符,不符合系统调用的传参要求
  • 缺失错误排查逻辑:没有对系统调用返回值做校验,也没有打印错误信息,无法快速定位问题

修改后的完整代码

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h> // 新增wait相关头文件

int main(void){
    printf("system_bootstrap pid:%d\n", getpid());
    char *program = 
            "#include <stdio.h>\n"
            "#include <stdlib.h>\n"
            "#include <unistd.h>\n"
            "int result;\n"
            "int main(int argc, char *argv[]){\n"
                    "printf(\"main_add pid: %d\\n\", getpid());\n"
                    "int a = 0;\n"
                    "int b = 0;\n"
                    "char* op;\n"
                    "op = argv[1];\n"
                    "a = atoi(argv[2]);\n"
                    "b = atoi(argv[3]);\n"
                    "int choice = 0;\n"
                    "if(*op == '+')\n"
                            "choice = 1;\n"
                    "else if(*op == '-')\n"
                            "choice = 2;\n"
                    "else if(*op == '*')\n"
                            "choice = 3;\n"
                    "else if(*op == '/')\n"
                            "choice = 4;\n"
                    "switch(choice){\n"
                            "case 1:\n"
                                    "result = a + b;\n"
                                    "printf(\"%d + %d = %d \\n\", a, b, result);\n"
                                    "break;\n"
                            "case 2:\n"
                                    "result = a - b;\n"
                                    "printf(\"%d - %d = %d \\n\", a, b, result);\n"
                                    "break;\n"
                            "case 3:\n"
                                    "result = a * b;\n"
                                    "printf(\"%d * %d = %d \\n\", a, b, result);\n"
                                    "break;\n"
                            "case 4:\n"
                                    "result = a / b;\n"
                                    "printf(\"%d / %d = %d \\n\", a, b, result);\n"
                                    "break;\n"
                            "default:\n"
                                    "printf(\"Invalid choice.\\n\");\n"
                                    "break;\n"
                    }\n"
            "return 0;\n"
            "}\n";
    
    int fd = creat("./math.c", S_IRUSR | S_IWUSR);
    printf("fd for math.c file:%d\n", fd);
    write(fd, program, strlen(program));
    close(fd); // 写入完成后关闭math.c的文件描述符,释放资源

    // 第一次fork:子进程执行编译
    pid_t cc_pid = fork();
    if (cc_pid == 0) {
        int cc_fd = open("/usr/bin/cc", O_RDONLY);
        if (cc_fd < 0) {
            perror("open cc failed");
            exit(1);
        }
        // 传入完整编译参数,末尾以NULL结尾
        char *cc_argv[] = {"cc", "./math.c", "-o", "math", NULL};
        char *cc_env[] = {NULL};
        fexecve(cc_fd, cc_argv, cc_env);
        // fexecve成功则不会走到这里,走到就是失败
        perror("compile fexecve failed");
        exit(1);
    }
    // 父进程等待编译完成
    wait(NULL);

    // 第二次fork:子进程执行生成的math程序
    printf("executing the math program ...\n");
    pid_t math_pid = fork();
    if (math_pid == 0) {
        int math_fd = open("./math", O_RDONLY);
        if (math_fd < 0) {
            perror("open math failed");
            exit(1);
        }
        // 参数末尾加NULL终止符
        char *math_argv[] = {"./math", "+", "6", "1", NULL};
        char *math_env[] = {NULL};
        fexecve(math_fd, math_argv, math_env);
        perror("run math fexecve failed");
        exit(1);
    }
    // 父进程等待执行完成
    wait(NULL);

    return 0;
}

验证说明

修改后编译运行system_math_bs.c,会正常输出计算结果6 + 1 = 7,和原system实现的效果一致。如果需要修改计算参数,直接修改math_argv数组里的对应值即可。

内容的提问来源于stack exchange,提问作者cruella devil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 10:24:04