/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- * * Kill a child process when the current directory is deleted * * Copyright (C) 2011 Colin Walters * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * Author: Colin Walters */ #include #include #include #include struct TmpdirLifecyleData { GMainLoop *loop; GPid pid; gboolean exited; }; static void on_dir_changed (GFileMonitor *mon, GFile *file, GFile *other, GFileMonitorEvent event, gpointer user_data) { struct TmpdirLifecyleData *data = user_data; if (event == G_FILE_MONITOR_EVENT_DELETED) g_main_loop_quit (data->loop); } static void on_child_exited (GPid pid, int status, gpointer user_data) { struct TmpdirLifecyleData *data = user_data; data->exited = TRUE; g_main_loop_quit (data->loop); } int main (int argc, char **argv) { GFileMonitor *monitor; GFile *curdir; GError *error = NULL; GPtrArray *new_argv; int i; struct TmpdirLifecyleData data; g_type_init (); memset (&data, 0, sizeof (data)); data.loop = g_main_loop_new (NULL, TRUE); curdir = g_file_new_for_path ("."); monitor = g_file_monitor_directory (curdir, 0, NULL, &error); if (!monitor) exit (1); g_signal_connect (monitor, "changed", G_CALLBACK (on_dir_changed), &data); new_argv = g_ptr_array_new (); for (i = 1; i < argc; i++) g_ptr_array_add (new_argv, argv[i]); g_ptr_array_add (new_argv, NULL); if (!g_spawn_async (NULL, (char**)new_argv->pdata, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &data.pid, &error)) { g_printerr ("%s\n", error->message); return 1; } g_child_watch_add (data.pid, on_child_exited, &data); g_main_loop_run (data.loop); if (!data.exited) kill (data.pid, SIGTERM); return 0; }