Quine 创建并执行文件

Quine create and execute file

我正在用 C 创建一个 Quine,我需要在其中创建一个新的 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

有什么想法吗?

当您以正常 shell 方式呼叫您的 shell 时,您会:

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

sh -c gcc tmp.c && ./a.out 在我的 shell 中有效,但正如您的评论所述,在您的中无效)

所以这意味着您必须将引用的参数传递给 execv,否则它们将被解释为单个参数,就像您这样做一样:

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

建议的修复:

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

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

完全固定代码提案:

#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);
}

您的参数数组 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);
}