+static void asmlinkage udev_event_sig_handler(int signum)
+{
+ if (signum == SIGALRM)
+ exit(1);
+}
+
+static int udev_event_process(struct uevent_msg *msg)
+{
+ struct sigaction act;
+ struct udevice udev;
+ struct name_entry *name_loop;
+ int i;
+ int retval;
+
+ /* set signal handlers */
+ memset(&act, 0x00, sizeof(act));
+ act.sa_handler = (void (*)(int)) udev_event_sig_handler;
+ sigemptyset (&act.sa_mask);
+ act.sa_flags = 0;
+ sigaction(SIGALRM, &act, NULL);
+
+ /* trigger timeout to prevent hanging processes */
+ alarm(UDEV_ALARM_TIMEOUT);
+
+ /* reconstruct env from message */
+ for (i = 0; msg->envp[i]; i++)
+ putenv(msg->envp[i]);
+
+ udev_init_device(&udev, msg->devpath, msg->subsystem, msg->action);
+ retval = udev_process_event(&rules, &udev);
+
+ /* run programs collected by RUN-key*/
+ if (!retval) {
+ list_for_each_entry(name_loop, &udev.run_list, node) {
+ if (strncmp(name_loop->name, "socket:", strlen("socket:")) == 0)
+ pass_env_to_socket(&name_loop->name[strlen("socket:")], msg->devpath, msg->action);
+ else
+ run_program(name_loop->name, udev.subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO));
+ }
+ }
+
+ udev_cleanup_device(&udev);
+
+ return 0;
+}
+
+/* runs event and removes event from run queue when finished */