g_spawn_async_with_pipes () の終了ステータス続き
以前 g_spawn_async_with_pipes() で終了ステータスを取得する方法を書きましたが、ステータス取得した後に waitpid(2) のマクロを使わないとよろしくなかったので追加。
ソースは以下の通りで、glibcが提供するヘッダを include します。waitpid(2) の man に書かれているマクロは、 sys/wait.h にあります。今回は、 WEXITSTATUS() マクロだけを使って、終了ステータスから整数に変換しています。このマクロを使用しないと、8bit左にシフトした値がstatusに入ります。
#include <glib.h> #include <sys/types.h> #include <sys/wait.h> void spawn_cb (GPid pid, gint status, GMainLoop *loop) { g_print ("Exit %d\n", WEXITSTATUS (status)); g_spawn_close_pid (pid); g_main_loop_quit (loop); } int main (int argc, char* argv[]) { gchar *args[] = {"false"}; GPid child_pid; GMainLoop *loop; g_type_init(); g_spawn_async_with_pipes (NULL, args, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &child_pid, NULL, NULL, NULL, NULL); loop = g_main_loop_new (NULL, TRUE); g_child_watch_add (child_pid, spawn_cb, loop); g_main_loop_run (loop); return 0; }
g_child_watch_add() の第2引数が GChildWatchFunc 型の関数で、これは、
void (*GChildWatchFunc) (GPid pid, gint status, gpointer user_data);
のような引数と返り値を持ちます。第2引数が終了ステータスで第3引数に g_child_watch_add()の第3引数が入ります。今回は GMainLoop 型のポインタを入れているので、 g_main_loop_quit() の引数で使用すると、 g_main_loop_run() で待ち状態になっているイベントループが終了します。
この第2引数の終了ステータスは、 waitpid(2) の終了ステータスと同じように扱う必要があるそうです。本来なら、 WIFEXITED() で正常終了を確かめた後に WEXITSTATUS() を使うと良いみたいです。