summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2008-04-22 03:01:29 +0200
committerKay Sievers <kay.sievers@vrfy.org>2008-04-22 03:01:29 +0200
commit7b2aad3343f8523db35ff2edfcfa9fcb816b7264 (patch)
tree0d37a3cd428284797857ba445c7af10ed9f00921
parentca0ac81f36f343047847168665c19d2080a64a6e (diff)
udevadm: trigger - add --env= option
-rw-r--r--udevadm.89
-rw-r--r--udevadm.xml11
-rw-r--r--udevtrigger.c37
3 files changed, 43 insertions, 14 deletions
diff --git a/udevadm.8 b/udevadm.8
index 0db30126bd..9cd91e209a 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 121c1401d6..8537d2ad40 100644
--- a/udevadm.xml
+++ b/udevadm.xml
@@ -180,7 +180,7 @@
</listitem>
</varlistentry>
<varlistentry>
- <term><option>--attr-nomatch<replaceable>attribute=value</replaceable></option></term>
+ <term><option>--attr-nomatch=<replaceable>attribute=value</replaceable></option></term>
<listitem>
<para>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 @@
</listitem>
</varlistentry>
<varlistentry>
- <term><option>--socket<replaceable>path</replaceable></option></term>
+ <term><option>--socket=<replaceable>path</replaceable></option></term>
<listitem>
<para>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.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--env=<replaceable>KEY</replaceable>=<replaceable>value</replaceable></option></term>
+ <listitem>
+ <para>Pass an additional environemt key to the event. This works only with the
+ --socket option.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect2>
diff --git a/udevtrigger.c b/udevtrigger.c
index 72464c8381..d4b10d06ab 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=<socket path> pass events to socket instead of triggering kernel events\n"
+ " --env=<KEY>=<value> pass an additional key (works only with --socket=)\n"
" --subsystem-match=<subsystem> trigger devices from a matching subystem\n"
" --subsystem-nomatch=<subsystem> exclude devices from a matching subystem\n"
" --attr-match=<file[=<value>]> 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);
}
}