UNIX fork

何を今頃になって子プロセスについて詳しく調べる。
UNIX 系なら fork という C 言語の関数で使えますね。

[unix fork] というワードで検索すれば山程サンプルコードが見つかる。
みんな waitpid という関数を呼んでいます。

技術的雑談-プロセスの生成と後始末(Linux C++編) – Tsubasa’s HomePage

上記が綺麗にまとめてくれている、筆者の勝手な感想だけど。
つまり子プロセスは必ずゾンビプロセスになるので回収しなきゃいけないのねん。

あれ、Gio.Subprocess も g_subprocess_wait 呼出しが必要だったりする?
devhelp をよく見ると

GSubprocess will quickly reap all child processes as they exit, avoiding “zombie processes” remaining around for long periods of time.
g_subprocess_wait() can be used to wait for this to happen, but it will happen even without the call being explicitly made.

と書いているので必須ではないみたい。
待つ必要がある時だけ呼び出せばいいのね。

とにかく Node.js の
require(‘child_process’).exec;
と同等に動くサンプルソースを書いてみる、関数ポインタを使えばいいかな。
今回も動作が解りやすいように GUI アプリを立ち上げてみる。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

void child_process_cb(char* command) {
    execl(command, NULL);
    printf("This string is not displayed\n");
}

void nodejs_exec(char *command, void (*callback)(char*)){

    pid_t pid;
    int status;

    pid = fork();
    if (pid == 0) {
        printf("__child__\n");
        callback(command);
        exit(-1);
    }

    printf("__start__\n");

    waitpid(pid, &status, 0);
    /* printf ("PID: %d status: %d\n", pid, status); */
}

int main(){
    nodejs_exec("/usr/bin/eog", &child_process_cb);
    return 0;
}

と eog を終了するまで待機するのが解ります。
子プロセスの stdout を得たい場合は下記のようにすればいい。
面倒臭い!

printf – execvp fork : wait for stdout – Stack Overflow

GSubprocess がドンダケ簡単なのかを思い知っただけだった。
てかやはり非同期はメインループをぐるぐる回すのが一番解りやすいや。