From: Kay Sievers Date: Tue, 22 Apr 2008 01:01:29 +0000 (+0200) Subject: udevadm: trigger - add --env= option X-Git-Tag: 174~1719 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=7b2aad3343f8523db35ff2edfcfa9fcb816b7264;ds=sidebyside udevadm: trigger - add --env= option --- diff --git a/udevadm.8 b/udevadm.8 index 0db30126b..9cd91e209 100644 --- a/udevadm.8 +++ b/udevadm.8 @@ -134,17 +134,22 @@ Do not trigger events for devices which belong to a matching subsystem\. This op Trigger events for devices with a matching sysfs attribute\. If a value is specified along with the attribute name, the content of the attribute is matched against the given value using shell style pattern matching\. If no value is specified, the existence of the sysfs attribute is checked\. This option can be specified multiple times\. .RE .PP -\fB\-\-attr\-nomatch\fR\fB\fIattribute=value\fR\fR +\fB\-\-attr\-nomatch=\fR\fB\fIattribute=value\fR\fR .RS 4 Do not trigger events for devices with a matching sysfs attribute\. If a value is specified along with the attribute name, the content of the attribute is matched against the given value using shell style pattern matching\. If no value is specified, the existence of the sysfs attribute is checked\. This option can be specified multiple times\. .RE .PP -\fB\-\-socket\fR\fB\fIpath\fR\fR +\fB\-\-socket=\fR\fB\fIpath\fR\fR .RS 4 Pass the synthesized events to the specified socket, instead of triggering a global kernel event\. All available event values will be send in the same format the kernel sends an uevent, or \fBRUN+="socket:\fR\fB\fIpath\fR\fR\fB"\fR sends a message\. If the first character of the specified path is an @ character, an abstract namespace socket is used, instead of an existing socket file\. .RE +.PP +\fB\-\-env=\fR\fB\fIKEY\fR\fR\fB=\fR\fB\fIvalue\fR\fR +.RS 4 +Pass an additional environemt key to the event\. This works only with the \-\-socket option\. +.RE .SS "udevadm settle [options]" .PP Watches the udev event queue, and exits if all current events are handled\. diff --git a/udevadm.xml b/udevadm.xml index 121c1401d..8537d2ad4 100644 --- a/udevadm.xml +++ b/udevadm.xml @@ -180,7 +180,7 @@ - + Do not trigger events for devices with a matching sysfs attribute. If a value is specified along with the attribute name, the content of the attribute is matched against @@ -189,7 +189,7 @@ - + Pass the synthesized events to the specified socket, instead of triggering a global kernel event. All available event values will be send in the same format @@ -198,6 +198,13 @@ an abstract namespace socket is used, instead of an existing socket file. + + + + Pass an additional environemt key to the event. This works only with the + --socket option. + + diff --git a/udevtrigger.c b/udevtrigger.c index 72464c838..d4b10d06a 100644 --- a/udevtrigger.c +++ b/udevtrigger.c @@ -120,7 +120,7 @@ static void trigger_uevent(const char *devpath, const char *action) close(fd); } -static int pass_to_socket(const char *devpath, const char *action) +static int pass_to_socket(const char *devpath, const char *action, const char *env) { struct udevice udev; struct name_entry *name_loop; @@ -143,6 +143,12 @@ static int pass_to_socket(const char *devpath, const char *action) bufpos = snprintf(buf, sizeof(buf)-1, "%s@%s", action, devpath); bufpos++; + /* add cookie */ + if (env != NULL) { + bufpos += snprintf(&buf[bufpos], sizeof(buf)-1, "%s", env); + bufpos++; + } + /* add standard keys */ bufpos += snprintf(&buf[bufpos], sizeof(buf)-1, "DEVPATH=%s", devpath); bufpos++; @@ -230,7 +236,7 @@ static int pass_to_socket(const char *devpath, const char *action) return err; } -static void exec_list(const char *action) +static void exec_list(const char *action, const char *env) { struct name_entry *loop_device; struct name_entry *tmp_device; @@ -239,7 +245,7 @@ static void exec_list(const char *action) if (delay_device(loop_device->name)) continue; if (sock >= 0) - pass_to_socket(loop_device->name, action); + pass_to_socket(loop_device->name, action, env); else trigger_uevent(loop_device->name, action); list_del(&loop_device->node); @@ -249,7 +255,7 @@ static void exec_list(const char *action) /* trigger remaining delayed devices */ list_for_each_entry_safe(loop_device, tmp_device, &device_list, node) { if (sock >= 0) - pass_to_socket(loop_device->name, action); + pass_to_socket(loop_device->name, action, env); else trigger_uevent(loop_device->name, action); list_del(&loop_device->node); @@ -558,6 +564,7 @@ int udevtrigger(int argc, char *argv[], char *envp[]) const char *sockpath = NULL; int option; const char *action = "add"; + const char *env = NULL; static const struct option options[] = { { "verbose", 0, NULL, 'v' }, { "dry-run", 0, NULL, 'n' }, @@ -569,6 +576,7 @@ int udevtrigger(int argc, char *argv[], char *envp[]) { "subsystem-nomatch", 1, NULL, 'S' }, { "attr-match", 1, NULL, 'a' }, { "attr-nomatch", 1, NULL, 'A' }, + { "env", 1, NULL, 'e' }, {} }; @@ -578,7 +586,7 @@ int udevtrigger(int argc, char *argv[], char *envp[]) sysfs_init(); while (1) { - option = getopt_long(argc, argv, "vnFo:hc:s:S:a:A:", options, NULL); + option = getopt_long(argc, argv, "vnFo:hce::s:S:a:A:", options, NULL); if (option == -1) break; @@ -598,6 +606,10 @@ int udevtrigger(int argc, char *argv[], char *envp[]) case 'c': action = optarg; break; + case 'e': + if (strchr(optarg, '=') != NULL) + env = optarg; + break; case 's': name_list_add(&filter_subsystem_match_list, optarg, 0); break; @@ -616,6 +628,8 @@ int udevtrigger(int argc, char *argv[], char *envp[]) " --dry-run do not actually trigger the events\n" " --retry-failed trigger only the events which have been\n" " marked as failed during a previous run\n" + " --socket= pass events to socket instead of triggering kernel events\n" + " --env== pass an additional key (works only with --socket=)\n" " --subsystem-match= trigger devices from a matching subystem\n" " --subsystem-nomatch= exclude devices from a matching subystem\n" " --attr-match=]> trigger devices with a matching sysfs\n" @@ -649,11 +663,14 @@ int udevtrigger(int argc, char *argv[], char *envp[]) strlcpy(&saddr.sun_path[1], sockpath, sizeof(saddr.sun_path)-1); saddrlen = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(&saddr.sun_path[1]); } + } else if (env != NULL) { + fprintf(stderr, "error: --env= only valid with --socket= option\n"); + goto exit; } if (failed) { scan_failed(); - exec_list(action); + exec_list(action, env); } else { char base[PATH_SIZE]; struct stat statbuf; @@ -663,12 +680,12 @@ int udevtrigger(int argc, char *argv[], char *envp[]) strlcat(base, "/subsystem", sizeof(base)); if (stat(base, &statbuf) == 0) { scan_subsystem("subsystem", SCAN_SUBSYSTEM); - exec_list(action); + exec_list(action, env); scan_subsystem("subsystem", SCAN_DEVICES); - exec_list(action); + exec_list(action, env); } else { scan_subsystem("bus", SCAN_SUBSYSTEM); - exec_list(action); + exec_list(action, env); scan_subsystem("bus", SCAN_DEVICES); scan_class(); @@ -677,7 +694,7 @@ int udevtrigger(int argc, char *argv[], char *envp[]) strlcat(base, "/class/block", sizeof(base)); if (stat(base, &statbuf) != 0) scan_block(); - exec_list(action); + exec_list(action, env); } }