popen で開始されたプロセスを kill する

popen() を使用しないでください 、あなたが望むことをする独自のラッパーを書きます。

fork() まではかなり簡単です 、次に stdin を置き換えます &stdout dup2() を使用して 、そして exec() を呼び出します

そうすれば、親は正確な子 PID を持ち、kill() を使用できます

popen() を実装する方法に関するサンプル コードについては、Google で「popen2() 実装」を検索してください。 やっています。わずか十数行の長さです。 dzone.com から取得した例を以下に示します:

#define READ 0
#define WRITE 1

pid_t
popen2(const char *command, int *infp, int *outfp)
{
    int p_stdin[2], p_stdout[2];
    pid_t pid;

    if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0)
        return -1;

    pid = fork();

    if (pid < 0)
        return pid;
    else if (pid == 0)
    {
        close(p_stdin[WRITE]);
        dup2(p_stdin[READ], READ);
        close(p_stdout[READ]);
        dup2(p_stdout[WRITE], WRITE);

        execl("/bin/sh", "sh", "-c", command, NULL);
        perror("execl");
        exit(1);
    }

    if (infp == NULL)
        close(p_stdin[WRITE]);
    else
        *infp = p_stdin[WRITE];

    if (outfp == NULL)
        close(p_stdout[READ]);
    else
        *outfp = p_stdout[READ];

    return pid;
}

注意:popen2() が必要なようですが、私のディストリビューションにはこのメソッドが付属していないようです。


これは popen2 の改良版です (クレジットは Sergey L. によるものです)。 slacy によって投稿されたバージョンは popen2 で作成されたプロセスの PID を返しませんが、sh に割り当てられた PID を返します .

pid_t popen2(const char **command, int *infp, int *outfp)
{
    int p_stdin[2], p_stdout[2];
    pid_t pid;

    if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0)
        return -1;

    pid = fork();

    if (pid < 0)
        return pid;
    else if (pid == 0)
    {
        close(p_stdin[WRITE]);
        dup2(p_stdin[READ], READ);
        close(p_stdout[READ]);
        dup2(p_stdout[WRITE], WRITE);

        execvp(*command, command);
        perror("execvp");
        exit(1);
    }

    if (infp == NULL)
        close(p_stdin[WRITE]);
    else
        *infp = p_stdin[WRITE];

    if (outfp == NULL)
        close(p_stdout[READ]);
    else
        *outfp = p_stdout[READ];

    return pid;
}

新しいバージョンは

で呼び出されます
char *command[] = {"program", "arg1", "arg2", ..., NULL};

popen は実際にスレッドを開始するのではなく、プロセスを fork します。定義を見ると、そのプロセスの PID を取得して強制終了する簡単な方法があるようには見えません。プロセス ツリーを調べるなどの難しい方法もあるかもしれませんが、pipe、fork、exec 関数を使用して popen の動作を模倣した方がよいと思います。次に、 fork() から取得した PID を使用して、子プロセスを強制終了できます。