1

我正在用 C 创建一个Quinine,我需要在其中创建一个新的 c 文件,然后编译并执行它。

我做了一个简单的片段来理解为什么它不起作用。

我的猜测是execv在 fprintf 完成写入之前启动命令,但我进入睡眠状态并且它也没有工作。

(我为这个最丑陋的代码道歉,但这不是目标)

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main()
{
    char *cmd[100]= {"sh", "-c", "\"gcc tmp.c && ./a.out\""};

    fprintf(fopen("tmp.c", "w"), "#include <stdio.h>\nint main(){puts(\"Hello World\");}");
    execv("/bin/sh", cmd);
    return (0);
}

输出

sh: gcc tmp.c && ./a.out: No such file or directory

任何的想法 ?

4

2 回答 2

2

您的参数数组cmd未以 NULL 指针终止。此外,它还有报价问题。

您还应该在execv()调用之前关闭文件。您在文件中看不到任何内容的原因是 fprintf() 缓冲。虽然所有打开的文件都在进程退出时关闭,但您在此之前正在执行。

int main(void)
{

   char *cmd[]= {"sh", "-c", "gcc tmp.c && ./a.out", (char*)0};

    FILE *fp = fopen("tmp.c", "w");
    if (!fp) {
       perror("fopen");
       exit(1);
    }

    fprintf(fp, "#include <stdio.h>\nint main(){puts(\"Hello World\");}");
    fclose(fp);
    execv("/bin/sh", cmd);
    perror("execv");
    return (0);
}
于 2016-11-04T21:36:16.847 回答
0

当您在普通外壳中调用外壳时,您会:

sh -c "gcc tmp.c && ./a.out"

sh -c gcc tmp.c && ./a.out正如您的评论所说,在我的外壳中工作,但不适用于您的外壳)

因此,这意味着您必须传递没有被引用的参数,execv否则它们会被解释为单个参数,就像您这样做:

sh -c \""gcc tmp.c && ./a.out\""

建议修复:

char *cmd[100]= {"sh", "-c", "gcc tmp.c && ./a.out", NULL};

顺便说一句:不要忘记fclose您的文件或tmp.c可能为零。BTW2:感谢 usr,NULL缺少 a:已编辑。

完全固定的代码提案:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
    char *cmd[100]= {"sh", "-c", "gcc tmp.c && ./a.out", NULL};
    FILE *outfile = fopen("tmp.c", "w");
    if (!outfile) {printf("cannot open output file\n");exit(1);}

    fprintf(outfile, "#include <stdio.h>\nint main(){puts(\"Hello World\");}");
    fclose(outfile);  // required else file remains open
    execv("/bin/sh", cmd);
    return (0);
}
于 2016-11-04T21:23:18.933 回答