summaryrefslogtreecommitdiffstats
path: root/package/hotplug2/patches/100-env_memleak.patch
blob: 28a3e2510f85b970501c07903ae6681c0b55aa17 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
--- a/action.c
+++ b/action.c
@@ -31,6 +31,30 @@ static void action_dumb(const struct set
 }
 
 /**
+ * Creates a "key=value" string from the given key and value
+ *
+ * @1 Key
+ * @2 Value
+ *
+ * Returns: Newly allocated string in "key=value" form
+ *
+ */
+static char* alloc_env(const char *key, const char *value) {
+	size_t keylen, vallen;
+	char *combined;
+
+	keylen = strlen(key);
+	vallen = strlen(value) + 1;
+
+	combined = xmalloc(keylen + vallen + 1);
+	memcpy(combined, key, keylen);
+	combined[keylen] = '=';
+	memcpy(&combined[keylen + 1], value, vallen);
+
+	return combined;
+}
+
+/**
  * Choose what action should be taken according to passed settings.
  *
  * @1 Hotplug settings
@@ -41,16 +65,25 @@ static void action_dumb(const struct set
  */
 void action_perform(struct settings_t *settings, struct uevent_t *event) {
 	int i;
+	char **env;
+
+	env = xmalloc(sizeof(char *) * event->env_vars_c);
+
+	for (i = 0; i < event->env_vars_c; i++) {
+		env[i] = alloc_env(event->env_vars[i].key, event->env_vars[i].value);
+		putenv(env[i]);
+	}
 
-	for (i = 0; i < event->env_vars_c; i++)
-		setenv(event->env_vars[i].key, event->env_vars[i].value, 1);
-	
 	if (settings->dumb == 0) {
 		ruleset_execute(&settings->rules, event, settings);
 	} else {
 		action_dumb(settings, event);
 	}
 
-	for (i = 0; i < event->env_vars_c; i++)
+	for (i = 0; i < event->env_vars_c; i++) {
 		unsetenv(event->env_vars[i].key);
+		free(env[i]);
+	}
+
+	free(env);
 }