diff options
author | Kay Sievers <kay.sievers@vrfy.org> | 2007-08-14 09:15:12 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-10-12 17:51:01 -0400 |
commit | 7eff2e7a8b65c25920207324e56611150eb1cd9a (patch) | |
tree | 02a0eeba9d25d996233e30c18f258dfae0ae2139 /include/linux | |
parent | 8380770c842faef3001e44662953d64ad9a93663 (diff) |
Driver core: change add_uevent_var to use a struct
This changes the uevent buffer functions to use a struct instead of a
long list of parameters. It does no longer require the caller to do the
proper buffer termination and size accounting, which is currently wrong
in some places. It fixes a known bug where parts of the uevent
environment are overwritten because of wrong index calculations.
Many thanks to Mathieu Desnoyers for finding bugs and improving the
error handling.
Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/device.h | 15 | ||||
-rw-r--r-- | include/linux/kobject.h | 23 |
2 files changed, 19 insertions, 19 deletions
diff --git a/include/linux/device.h b/include/linux/device.h index 5d97ca6d8655..2e15822fe409 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -66,8 +66,7 @@ struct bus_type { | |||
66 | struct driver_attribute * drv_attrs; | 66 | struct driver_attribute * drv_attrs; |
67 | 67 | ||
68 | int (*match)(struct device * dev, struct device_driver * drv); | 68 | int (*match)(struct device * dev, struct device_driver * drv); |
69 | int (*uevent)(struct device *dev, char **envp, | 69 | int (*uevent)(struct device *dev, struct kobj_uevent_env *env); |
70 | int num_envp, char *buffer, int buffer_size); | ||
71 | int (*probe)(struct device * dev); | 70 | int (*probe)(struct device * dev); |
72 | int (*remove)(struct device * dev); | 71 | int (*remove)(struct device * dev); |
73 | void (*shutdown)(struct device * dev); | 72 | void (*shutdown)(struct device * dev); |
@@ -187,10 +186,8 @@ struct class { | |||
187 | struct class_device_attribute * class_dev_attrs; | 186 | struct class_device_attribute * class_dev_attrs; |
188 | struct device_attribute * dev_attrs; | 187 | struct device_attribute * dev_attrs; |
189 | 188 | ||
190 | int (*uevent)(struct class_device *dev, char **envp, | 189 | int (*uevent)(struct class_device *dev, struct kobj_uevent_env *env); |
191 | int num_envp, char *buffer, int buffer_size); | 190 | int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env); |
192 | int (*dev_uevent)(struct device *dev, char **envp, int num_envp, | ||
193 | char *buffer, int buffer_size); | ||
194 | 191 | ||
195 | void (*release)(struct class_device *dev); | 192 | void (*release)(struct class_device *dev); |
196 | void (*class_release)(struct class *class); | 193 | void (*class_release)(struct class *class); |
@@ -266,8 +263,7 @@ struct class_device { | |||
266 | struct attribute_group ** groups; /* optional groups */ | 263 | struct attribute_group ** groups; /* optional groups */ |
267 | 264 | ||
268 | void (*release)(struct class_device *dev); | 265 | void (*release)(struct class_device *dev); |
269 | int (*uevent)(struct class_device *dev, char **envp, | 266 | int (*uevent)(struct class_device *dev, struct kobj_uevent_env *env); |
270 | int num_envp, char *buffer, int buffer_size); | ||
271 | char class_id[BUS_ID_SIZE]; /* unique to this class */ | 267 | char class_id[BUS_ID_SIZE]; /* unique to this class */ |
272 | }; | 268 | }; |
273 | 269 | ||
@@ -335,8 +331,7 @@ extern void class_device_destroy(struct class *cls, dev_t devt); | |||
335 | struct device_type { | 331 | struct device_type { |
336 | const char *name; | 332 | const char *name; |
337 | struct attribute_group **groups; | 333 | struct attribute_group **groups; |
338 | int (*uevent)(struct device *dev, char **envp, int num_envp, | 334 | int (*uevent)(struct device *dev, struct kobj_uevent_env *env); |
339 | char *buffer, int buffer_size); | ||
340 | void (*release)(struct device *dev); | 335 | void (*release)(struct device *dev); |
341 | int (*suspend)(struct device * dev, pm_message_t state); | 336 | int (*suspend)(struct device * dev, pm_message_t state); |
342 | int (*resume)(struct device * dev); | 337 | int (*resume)(struct device * dev); |
diff --git a/include/linux/kobject.h b/include/linux/kobject.h index 949706c33622..626bdd3c3dd9 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h | |||
@@ -29,6 +29,8 @@ | |||
29 | 29 | ||
30 | #define KOBJ_NAME_LEN 20 | 30 | #define KOBJ_NAME_LEN 20 |
31 | #define UEVENT_HELPER_PATH_LEN 256 | 31 | #define UEVENT_HELPER_PATH_LEN 256 |
32 | #define UEVENT_NUM_ENVP 32 /* number of env pointers */ | ||
33 | #define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */ | ||
32 | 34 | ||
33 | /* path to the userspace helper executed on an event */ | 35 | /* path to the userspace helper executed on an event */ |
34 | extern char uevent_helper[]; | 36 | extern char uevent_helper[]; |
@@ -111,11 +113,18 @@ struct kobj_type { | |||
111 | struct attribute ** default_attrs; | 113 | struct attribute ** default_attrs; |
112 | }; | 114 | }; |
113 | 115 | ||
116 | struct kobj_uevent_env { | ||
117 | char *envp[UEVENT_NUM_ENVP]; | ||
118 | int envp_idx; | ||
119 | char buf[UEVENT_BUFFER_SIZE]; | ||
120 | int buflen; | ||
121 | }; | ||
122 | |||
114 | struct kset_uevent_ops { | 123 | struct kset_uevent_ops { |
115 | int (*filter)(struct kset *kset, struct kobject *kobj); | 124 | int (*filter)(struct kset *kset, struct kobject *kobj); |
116 | const char *(*name)(struct kset *kset, struct kobject *kobj); | 125 | const char *(*name)(struct kset *kset, struct kobject *kobj); |
117 | int (*uevent)(struct kset *kset, struct kobject *kobj, char **envp, | 126 | int (*uevent)(struct kset *kset, struct kobject *kobj, |
118 | int num_envp, char *buffer, int buffer_size); | 127 | struct kobj_uevent_env *env); |
119 | }; | 128 | }; |
120 | 129 | ||
121 | /* | 130 | /* |
@@ -275,10 +284,8 @@ int kobject_uevent(struct kobject *kobj, enum kobject_action action); | |||
275 | int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, | 284 | int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, |
276 | char *envp[]); | 285 | char *envp[]); |
277 | 286 | ||
278 | int add_uevent_var(char **envp, int num_envp, int *cur_index, | 287 | int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...) |
279 | char *buffer, int buffer_size, int *cur_len, | 288 | __attribute__((format (printf, 2, 3))); |
280 | const char *format, ...) | ||
281 | __attribute__((format (printf, 7, 8))); | ||
282 | #else | 289 | #else |
283 | static inline int kobject_uevent(struct kobject *kobj, enum kobject_action action) | 290 | static inline int kobject_uevent(struct kobject *kobj, enum kobject_action action) |
284 | { return 0; } | 291 | { return 0; } |
@@ -287,9 +294,7 @@ static inline int kobject_uevent_env(struct kobject *kobj, | |||
287 | char *envp[]) | 294 | char *envp[]) |
288 | { return 0; } | 295 | { return 0; } |
289 | 296 | ||
290 | static inline int add_uevent_var(char **envp, int num_envp, int *cur_index, | 297 | static inline int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...) |
291 | char *buffer, int buffer_size, int *cur_len, | ||
292 | const char *format, ...) | ||
293 | { return 0; } | 298 | { return 0; } |
294 | #endif | 299 | #endif |
295 | 300 | ||