[BACK]Return to wait-call_usermodehelper CVS log [TXT][DIR] Up to [Development] / linux-2.4-xfs / split-patches

File: [Development] / linux-2.4-xfs / split-patches / wait-call_usermodehelper (download)

Revision 1.1, Wed Apr 28 05:29:46 2004 UTC (13 years, 5 months ago) by nathans
Branch: MAIN

Update 2.4 split patches.

Index: 2.4.x-xfs/include/linux/kmod.h
===================================================================
--- 2.4.x-xfs.orig/include/linux/kmod.h	Tue Apr 20 09:18:05 2004
+++ 2.4.x-xfs/include/linux/kmod.h	Wed Apr 28 15:06:45 2004
@@ -30,6 +30,7 @@
 
 extern int exec_usermodehelper(char *program_path, char *argv[], char *envp[]);
 extern int call_usermodehelper(char *path, char *argv[], char *envp[]);
+extern int __call_usermodehelper(char *path, char *argv[], char *envp[], int wait);
 
 #ifdef CONFIG_HOTPLUG
 extern char hotplug_path [];
Index: 2.4.x-xfs/kernel/kmod.c
===================================================================
--- 2.4.x-xfs.orig/kernel/kmod.c	Tue Apr 20 09:18:23 2004
+++ 2.4.x-xfs/kernel/kmod.c	Wed Apr 28 15:06:45 2004
@@ -14,6 +14,9 @@
 
 	Unblock all signals when we exec a usermode process.
 	Shuu Yamaguchi <shuu@wondernetworkresources.com> December 2000
+
+	Add wait flag to call_usermodehelper. Based on a patch from Rusty Russell.
+	Marcel Holtmann <marcel@holtmann.org> Jan 2003
 */
 
 #define __KERNEL_SYSCALLS__
@@ -173,7 +176,7 @@
  * If module auto-loading support is disabled then this function
  * becomes a no-operation.
  */
-int request_module(const char * module_name)
+int request_module(const char *module_name)
 {
 	pid_t pid;
 	int waitpid_result;
@@ -271,7 +274,8 @@
 	char *path;
 	char **argv;
 	char **envp;
-	pid_t retval;
+	int wait;
+	int retval;
 };
 
 /*
@@ -287,26 +291,58 @@
 		retval = exec_usermodehelper(sub_info->path, sub_info->argv, sub_info->envp);
 
 	/* Exec failed? */
-	sub_info->retval = (pid_t)retval;
+	sub_info->retval = retval;
 	do_exit(0);
 }
 
-/*
- * This is run by keventd.
+/* 
+ * Keventd can't block, but this (a child) can.
  */
-static void __call_usermodehelper(void *data)
+static int wait_for_helper(void *data)
 {
 	struct subprocess_info *sub_info = data;
 	pid_t pid;
 
-	/*
-	 * CLONE_VFORK: wait until the usermode helper has execve'd successfully
-	 * We need the data structures to stay around until that is done.
-	 */
-	pid = kernel_thread(____call_usermodehelper, sub_info, CLONE_VFORK | SIGCHLD);
+	pid = kernel_thread(____call_usermodehelper, sub_info,
+			    CLONE_VFORK | SIGCHLD);
 	if (pid < 0)
 		sub_info->retval = pid;
+	else
+		sys_wait4(pid, (unsigned int *)&sub_info->retval, 0, NULL);
+
 	complete(sub_info->complete);
+	return 0;
+}
+
+/*
+ * This is run by keventd.
+ */
+static void __call_usermodehelper_data(void *data)
+{
+	struct subprocess_info *sub_info = data;
+	pid_t pid;
+
+	/* CLONE_VFORK: wait until the usermode helper has execve'd
+	 * successfully We need the data structures to stay around
+	 * until that is done.  */
+	if (sub_info->wait)
+		pid = kernel_thread(wait_for_helper, sub_info,
+				    CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
+	else
+		pid = kernel_thread(____call_usermodehelper, sub_info,
+				    CLONE_VFORK | SIGCHLD);
+
+	if (pid < 0) {
+		sub_info->retval = pid;
+		complete(sub_info->complete);
+	} else if (!sub_info->wait)
+		complete(sub_info->complete);
+}
+
+
+int call_usermodehelper(char *path, char *argv[], char *envp[])
+{
+	return __call_usermodehelper(path, argv, envp, 0);
 }
 
 /**
@@ -314,15 +350,17 @@
  * @path: pathname for the application
  * @argv: null-terminated argument list
  * @envp: null-terminated environment list
+ * @wait: wait for the application to finish and return status.
  *
- * Runs a user-space application.  The application is started asynchronously.  It
- * runs as a child of keventd.  It runs with full root capabilities.  keventd silently
- * reaps the child when it exits.
+ * Runs a user-space application.  The application is started
+ * asynchronously if wait is not set, and runs as a child of keventd.
+ * (ie. it runs with full root capabilities).
  *
- * Must be called from process context.  Returns zero on success, else a negative
- * error code.
+ * Must be called from process context.  Returns a negative error code
+ * if program was not execed successfully, or (exitcode << 8 + signal)
+ * of the application (0 if wait is not set).
  */
-int call_usermodehelper(char *path, char **argv, char **envp)
+int __call_usermodehelper(char *path, char *argv[], char *envp[], int wait)
 {
 	DECLARE_COMPLETION(work);
 	struct subprocess_info sub_info = {
@@ -330,10 +368,11 @@
 		path:		path,
 		argv:		argv,
 		envp:		envp,
+		wait:		wait,
 		retval:		0,
 	};
 	struct tq_struct tqs = {
-		routine:	__call_usermodehelper,
+		routine:	__call_usermodehelper_data,
 		data:		&sub_info,
 	};
 
@@ -342,7 +381,7 @@
 
 	if (current_is_keventd()) {
 		/* We can't wait on keventd! */
-		__call_usermodehelper(&sub_info);
+		__call_usermodehelper_data(&sub_info);
 	} else {
 		schedule_task(&tqs);
 		wait_for_completion(&work);
@@ -369,8 +408,8 @@
 
 EXPORT_SYMBOL(exec_usermodehelper);
 EXPORT_SYMBOL(call_usermodehelper);
+EXPORT_SYMBOL(__call_usermodehelper);
 
 #ifdef CONFIG_KMOD
 EXPORT_SYMBOL(request_module);
 #endif
-