chiark / gitweb /
[PATCH] support arguments in callout exec
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>
Fri, 21 Nov 2003 14:48:01 +0000 (06:48 -0800)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 04:06:25 +0000 (21:06 -0700)
here is argument support for CALLOUT exec:

CALLOUT, PROGRAM="/bin/echo -n xxx", BUS="usb", ID="xxx", NAME="webcam%n"

results in:

Nov 20 02:35:20 pim udev[30422]: get_major_minor: found major = 81, minor = 0
Nov 20 02:35:20 pim udev[30422]: exec_callout: callout to /bin/echo -n xxx
Nov 20 02:35:20 pim udev[30422]: exec_callout: callout returned 'xxx'
Nov 20 02:35:20 pim udev[30422]: get_attr: kernel number appended: 0

The feature is really nice, but the maximum argument count is hard coded to 8.

namedev.c

index 7c87610..bed328f 100644 (file)
--- a/namedev.c
+++ b/namedev.c
@@ -45,6 +45,7 @@
 #define TYPE_TOPOLOGY  "TOPOLOGY"
 #define TYPE_REPLACE   "REPLACE"
 #define TYPE_CALLOUT   "CALLOUT"
 #define TYPE_TOPOLOGY  "TOPOLOGY"
 #define TYPE_REPLACE   "REPLACE"
 #define TYPE_CALLOUT   "CALLOUT"
+#define CALLOUT_MAXARG 8
 
 static LIST_HEAD(config_device_list);
 
 
 static LIST_HEAD(config_device_list);
 
@@ -479,6 +480,9 @@ static int exec_callout(struct config_device *dev, char *value, int len)
        pid_t pid;
        int value_set = 0;
        char buffer[256];
        pid_t pid;
        int value_set = 0;
        char buffer[256];
+       char *arg;
+       char *args[CALLOUT_MAXARG];
+       int i;
 
        dbg("callout to '%s'", dev->exec_program);
        retval = pipe(fds);
 
        dbg("callout to '%s'", dev->exec_program);
        retval = pipe(fds);
@@ -496,7 +500,22 @@ static int exec_callout(struct config_device *dev, char *value, int len)
                /* child */
                close(STDOUT_FILENO);
                dup(fds[1]);    /* dup write side of pipe to STDOUT */
                /* child */
                close(STDOUT_FILENO);
                dup(fds[1]);    /* dup write side of pipe to STDOUT */
-               retval = execve(dev->exec_program, main_argv, main_envp);
+               if (strchr(dev->exec_program, ' ')) {
+                       /* callout with arguments */
+                       arg = dev->exec_program;
+                       for (i=0; i < CALLOUT_MAXARG-1; i++) {
+                               args[i] = strsep(&arg, " ");
+                               if (args[i] == NULL)
+                                       break;
+                       }
+                       if (args[i]) {
+                               dbg("to many args - %d", i);
+                               args[i] = NULL;
+                       }
+                       retval = execve(args[0], args, main_envp);
+               } else {
+                       retval = execve(dev->exec_program, main_argv, main_envp);
+               }
                if (retval != 0) {
                        dbg("child execve failed");
                        exit(1);
                if (retval != 0) {
                        dbg("child execve failed");
                        exit(1);
@@ -523,6 +542,7 @@ static int exec_callout(struct config_device *dev, char *value, int len)
                                strncpy(value, buffer, len);
                        }
                }
                                strncpy(value, buffer, len);
                        }
                }
+               dbg("callout returned '%s'", value);
                close(fds[0]);
                res = wait(&status);
                if (res < 0) {
                close(fds[0]);
                res = wait(&status);
                if (res < 0) {