changeset 13747:66edd2f65616

2950 sync hald-runner with upstream Reviewed by: Andrew Stormont <Andrew.Stormont@nexenta.com> Reviewed by: Garrett D'Amore <garrett@damore.org> Approved by: Richard Lowe <richlowe@richlowe.net>
author Milan Jurik <milan.jurik@xylab.cz>
date Sun, 08 Jul 2012 13:53:30 -0500
parents ad469755a3d5
children f6cfe4fa2687
files usr/src/cmd/hal/hald-runner/main.c usr/src/cmd/hal/hald-runner/runner.c usr/src/cmd/hal/hald-runner/runner.h
diffstat 3 files changed, 89 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/hal/hald-runner/main.c	Thu Jun 28 07:28:22 2012 +0100
+++ b/usr/src/cmd/hal/hald-runner/main.c	Sun Jul 08 13:53:30 2012 -0500
@@ -4,6 +4,7 @@
  * main.c - Main dbus interface of the hald runner
  *
  * Copyright (C) 2006 Sjoerd Simons, <sjoerd@luon.net>
+ * Copyright (C) 2007 Codethink Ltd. Author Rob Taylor <rob.taylor@codethink.co.uk>
  *
  * Licensed under the Academic Free License version 2.1
  *
@@ -31,24 +32,46 @@
 #include "utils.h"
 #include "runner.h"
 
+#ifndef __GNUC__
+#define __attribute__(x)
+#endif
+
 static gboolean
-parse_first_part(run_request *r, DBusMessage *msg, DBusMessageIter *iter)
+parse_udi (run_request *r, DBusMessage *msg, DBusMessageIter *iter)
 {
-	DBusMessageIter sub_iter;
 	char *tmpstr;
 
-	/* First should be the device UDI */
+	/* Should be the device UDI */
 	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING) 
 		goto malformed;
 	dbus_message_iter_get_basic(iter, &tmpstr);
 	r->udi = g_strdup(tmpstr);
 
-	/* Then the environment array */
-	if (!dbus_message_iter_next(iter) || dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+	if (!dbus_message_iter_next(iter))
+		goto malformed;
+
+	return TRUE;
+
+malformed:
+	return FALSE;
+}
+
+static gboolean
+parse_environment(run_request *r, DBusMessage *msg, DBusMessageIter *iter)
+{
+	DBusMessageIter sub_iter;
+	char *tmpstr;
+
+	/* The environment array */
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
 		goto malformed;
 	dbus_message_iter_recurse(iter, &sub_iter);
 	/* Add default path for the programs we start */
+#if defined(__FreeBSD__)
+	tmpstr = g_strdup_printf("PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/X11R6/sbin:/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin:%s", getenv("PATH"));
+#else
 	tmpstr = g_strdup_printf("PATH=/sbin:/usr/sbin:/bin:/usr/bin:%s", getenv("PATH"));
+#endif
 	r->environment = get_string_array(&sub_iter, tmpstr);
 
 	/* Then argv */
@@ -74,7 +97,10 @@
 	r = new_run_request();
 	g_assert(dbus_message_iter_init(msg, &iter));
 
-	if (!parse_first_part(r, msg, &iter)) 
+	if (!parse_udi(r, msg, &iter))
+		goto malformed;
+
+	if (!parse_environment(r, msg, &iter))
 		goto malformed;
 
 	/* Next a string of what should be written to stdin */
@@ -106,25 +132,36 @@
 }
 
 static void
-handle_start(DBusConnection *con, DBusMessage *msg)
+handle_start(DBusConnection *con, DBusMessage *msg, gboolean is_singleton)
 {
 	DBusMessage *reply;
 	DBusMessageIter iter;
 	run_request *r;
 	GPid pid;
-	dbus_int64_t pid64;
 
 	r = new_run_request();
+	r->is_singleton = is_singleton;
+
 	g_assert(dbus_message_iter_init(msg, &iter));
 
-	if (!dbus_message_iter_init(msg, &iter) || !parse_first_part(r, msg, &iter))
+	if (!dbus_message_iter_init(msg, &iter))
+		goto malformed;
+
+	if (!is_singleton && !parse_udi(r, msg, &iter)) {
+		fprintf(stderr, "error parsing udi");
 		goto malformed;
+	}
+
+	if (!parse_environment(r, msg, &iter)) {
+		fprintf(stderr, "error parsing environment");
+		goto malformed;
+	}
 
 	if (run_request_run(r, con, NULL, &pid)) {
-		pid64 = pid;
+		gint64 ppid = pid;
 		reply = dbus_message_new_method_return(msg);
 		dbus_message_append_args (reply, 
-					  DBUS_TYPE_INT64, &pid64,
+					  DBUS_TYPE_INT64, &ppid,
 					  DBUS_TYPE_INVALID);
 					  
 	} else {
@@ -177,11 +214,18 @@
 		handle_run(con, msg);
 		return DBUS_HANDLER_RESULT_HANDLED;
 	} else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "Start")) {
-		handle_start(con, msg);
+		handle_start(con, msg, FALSE);
+		return DBUS_HANDLER_RESULT_HANDLED;
+	} else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "StartSingleton")) {
+		handle_start(con, msg, TRUE);
 		return DBUS_HANDLER_RESULT_HANDLED;
 	} else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "Kill")) {
 		handle_kill(con, msg);
 		return DBUS_HANDLER_RESULT_HANDLED;
+	} else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "Shutdown")) {
+		run_kill_all ();
+		exit (0);
+		return DBUS_HANDLER_RESULT_HANDLED;
 	} else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "KillAll")) {
 		run_kill_all();
 		/* alwasy successfull */
--- a/usr/src/cmd/hal/hald-runner/runner.c	Thu Jun 28 07:28:22 2012 +0100
+++ b/usr/src/cmd/hal/hald-runner/runner.c	Sun Jul 08 13:53:30 2012 -0500
@@ -4,6 +4,7 @@
  * runner.c - Process running code
  *
  * Copyright (C) 2006 Sjoerd Simons, <sjoerd@luon.net>
+ * Copyright (C) 2007 Codethink Ltd. Author Rob Taylor <rob.taylor@codethink.co.uk>
  *
  * Licensed under the Academic Free License version 2.1
  *
@@ -48,6 +49,7 @@
 #define HALD_RUN_KILLED 0x4
 
 GHashTable *udi_hash = NULL;
+GList *singletons = NULL;
 
 typedef struct {
 	run_request *r;
@@ -128,15 +130,19 @@
 }
 
 static void
-remove_from_hash_table(run_data *rd)
+remove_run_data(run_data *rd)
 {
 	GList *list;
 
-	/* Remove to the hashtable */
-	list = (GList *)g_hash_table_lookup(udi_hash, rd->r->udi);
-	list = g_list_remove(list, rd);
-	/* The hash table will take care to not leak the dupped string */
-	g_hash_table_insert(udi_hash, g_strdup(rd->r->udi), list);
+	if (rd->r->is_singleton) {
+		singletons = g_list_remove(singletons, rd);
+	} else {
+		/* Remove to the hashtable */
+		list = (GList *)g_hash_table_lookup(udi_hash, rd->r->udi);
+		list = g_list_remove(list, rd);
+		/* The hash table will take care to not leak the dupped string */
+		g_hash_table_insert(udi_hash, g_strdup(rd->r->udi), list);
+	}
 }
 
 static void
@@ -145,7 +151,8 @@
 	run_data *rd = (run_data *)data;
 	char **error = NULL;
 
-	printf("%s exited\n", rd->r->argv[0]);
+	printf("pid %d: rc=%d signaled=%d: %s\n", 
+               pid, WEXITSTATUS(status), WIFSIGNALED(status), rd->r->argv[0]);
 	rd->watch = 0;
 	if (rd->sent_kill == TRUE) {
 		/* We send it a kill, so ignore */
@@ -170,18 +177,17 @@
 	free_string_array(error);
 
 out:
-	remove_from_hash_table(rd);
+	remove_run_data (rd);
 		
 	/* emit a signal that this PID exited */
 	if(rd->con != NULL && rd->emit_pid_exited) {
 		DBusMessage *signal;
-		dbus_int64_t pid64;
+		gint64 ppid = rd->pid;
 		signal = dbus_message_new_signal ("/org/freedesktop/HalRunner",
 						  "org.freedesktop.HalRunner",
 						  "StartedProcessExited");
-		pid64 = rd->pid;
 		dbus_message_append_args (signal, 
-					  DBUS_TYPE_INT64, &pid64,
+					  DBUS_TYPE_INT64, &(ppid),
 					  DBUS_TYPE_INVALID);
 		dbus_connection_send(rd->con, signal, NULL);
 	}
@@ -202,7 +208,7 @@
 	rd->sent_kill = TRUE;
 
 	send_reply(rd->con, rd->msg, HALD_RUN_TIMEOUT, 0, NULL);
-	remove_from_hash_table(rd);
+	remove_run_data (rd);
 	return FALSE;
 }
 
@@ -246,7 +252,7 @@
 	char *program_dir = NULL;
 	GList *list;
 
-	printf("Run started %s (%d) (%d) \n!", r->argv[0], r->timeout,
+	printf("Run started %s (%u) (%d) \n!", r->argv[0], r->timeout,
 		r->error_on_stderr);
 	if (r->input != NULL) {
 		stdin_p = &stdin_v; 
@@ -277,7 +283,7 @@
 
 	if (r->input) {
 		if (write(stdin_v, r->input, strlen(r->input)) != (ssize_t) strlen(r->input))
-			printf("Warning: Error while wite r->input (%s) to stdin_v.\n", r->input);
+			printf("Warning: Error while writing r->input (%s) to stdin_v.\n", r->input);
 		close(stdin_v);
 	}
 
@@ -302,12 +308,16 @@
 	else
 		rd->timeout = 0;
 
-	/* Add to the hashtable */
-	list = (GList *)g_hash_table_lookup(udi_hash, r->udi);
-	list = g_list_prepend(list, rd);
+	if (r->is_singleton) {
+		singletons = g_list_prepend(singletons, rd);
+	} else {
+		/* Add to the hashtable */
+		list = (GList *)g_hash_table_lookup(udi_hash, r->udi);
+		list = g_list_prepend(list, rd);
 
-	/* The hash table will take care to not leak the dupped string */
-	g_hash_table_insert(udi_hash, g_strdup(r->udi), list);
+		/* The hash table will take care to not leak the dupped string */
+		g_hash_table_insert(udi_hash, g_strdup(r->udi), list);
+	}
 
 	/* send back PID if requested.. and only emit StartedProcessExited in this case */
 	if (out_pid != NULL) {
@@ -365,6 +375,7 @@
 run_kill_all()
 {
 	g_hash_table_foreach_remove(udi_hash, hash_kill_udi, NULL);
+	g_list_foreach(singletons, kill_rd, NULL);
 }
 
 void
--- a/usr/src/cmd/hal/hald-runner/runner.h	Thu Jun 28 07:28:22 2012 +0100
+++ b/usr/src/cmd/hal/hald-runner/runner.h	Sun Jul 08 13:53:30 2012 -0500
@@ -36,6 +36,7 @@
 	gchar **argv;
 	gchar *input;
 	gboolean error_on_stderr;
+	gboolean is_singleton;
 	guint32 timeout;
 } run_request;
 
@@ -49,9 +50,9 @@
 void run_kill_udi(gchar *udi);
 
 /* Kill all running request*/
-void run_kill_all();
+void run_kill_all(void);
 
 /* initialise the actual runner data */
-void run_init();
+void run_init(void);
 
 #endif /*  RUNNER_H */