我在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
有什么想法吗?
答案 0 :(得分: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);
}
答案 1 :(得分:0)
当你在普通的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};
BTW:不要忘记fclose
您的文件或tmp.c
可能为零。
BTW2:多亏了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);
}