1

私はC でQuineを作成しています。新しい C ファイルを作成し、コンパイルして実行する必要があります。

なぜ機能しないのかを理解するために、簡単なスニペットを作成しました。

私の推測では、execvfprintf の書き込みが完了する前にコマンドを開始すると思いますが、私はスリープ状態にしましたが、それも機能していませんでした。

(この醜いコードについては申し訳ありませんが、それが目的ではありません)

#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 のおかげで、aNULLがありませんでした: 編集済みです。

完全に修正されたコードの提案:

#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 に答える