/*  selectwm - X11 window manager selector
 *
 *  Copyright (C) 1999-2003  Luc Dufresne - luc@ordiluc.net
 *                           26, rue des Comices
 *                           59650 Villeneuve d'Ascq
 *                           FRANCE
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  See the file COPYING
 */

#include "define.h"

#include <gtk/gtk.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>

#include "misc.h"
#include "options.h"
#include "miscui.h"

static void chld_handler (int signum) {
	int status, pid;

	while ((pid = waitpid (-1, &status, WNOHANG)) != 0) {
		if (errno == ECHILD) break;
//		printf ("chld %d\n", pid);
	}
}

void no_zombies () {
	struct sigaction sact;

	sact.sa_handler = chld_handler;
	sigemptyset (&sact.sa_mask );
	sact.sa_flags = SA_NOCLDSTOP;
	if (sigaction (SIGCHLD, &sact, NULL) < 0) {
		g_warning ("sigaction failed\n");
		exit (1);
	}
}

static void cannot_exec (const gchar *cmd, gchar *desc) {
	GString *buf;

	buf = g_string_new ("");
	g_string_printf (buf, _("Cannot start \"%s\" (%s)"), cmd, desc);
	g_warning ("%s\n", buf->str);
	messagebox (buf->str, GTK_MESSAGE_ERROR);
	g_string_free (buf, TRUE);
}

void exec_wm (config *selectwm_config) {
	gint error;
	gchar *desc, *cmd;
	GtkTreeIter iter;
	GtkTreeModel *model;

	pid_t pid;
	gint status;

	if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (selectwm_config->treeview)), &model, &iter)) {
		gtk_tree_model_get (model, &iter,C_CMD, &cmd, C_DESC, &desc , -1);
		
		if (!selectwm_config->restart_selectwm) {
			write_config (selectwm_config);
			sigaction (SIGCHLD, NULL, NULL);
			execlp (cmd, cmd, NULL);
			no_zombies ();
			cannot_exec (cmd, desc);
		} else {
			write_config (selectwm_config);
			gtk_widget_hide (selectwm_config->window);
			while (gtk_events_pending ()) gtk_main_iteration ();

			error = 0;
			pid = fork ();
			if (pid > 0) {
				while (pid != waitpid (pid, &status, 0)) {
					if (errno == ECHILD) break;
				}
				if (WEXITSTATUS (status) == 128) error = 1;
			} else if (pid == 0) {
				execlp (cmd, cmd, NULL);
				_exit (128);
			} else {
				error = 1;
			}

			gtk_widget_show (selectwm_config->window);
			if (error) cannot_exec (cmd, desc);
		}
		g_free (cmd);
		g_free (desc);
	}
}



syntax highlighted by Code2HTML, v. 0.9.1