diff -d -urpN busybox.1/util-linux/mdev.c busybox.2/util-linux/mdev.c --- busybox.1/util-linux/mdev.c 2008-05-31 20:24:36.000000000 +0200 +++ busybox.2/util-linux/mdev.c 2008-06-04 10:32:43.000000000 +0200 @@ -14,10 +14,12 @@ struct globals { int root_major, root_minor; + const char *seqfile; }; #define G (*(struct globals*)&bb_common_bufsiz1) #define root_major (G.root_major) #define root_minor (G.root_minor) +#define seqfile (G.seqfile ) #define MAX_SYSFS_DEPTH 3 /* prevent infinite loops in /sys symlinks */ @@ -386,10 +388,10 @@ static void load_firmware(const char *co } int mdev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int mdev_main(int argc, char **argv) +int mdev_main(int argc ATTRIBUTE_UNUSED, char **argv) { - char *action; - char *env_path; + int opt; + int timeout = 1000; RESERVE_CONFIG_BUFFER(temp, PATH_MAX + SCRATCH_SIZE); #ifdef YOU_WANT_TO_DEBUG_HOTPLUG_EVENTS @@ -401,9 +403,15 @@ int mdev_main(int argc, char **argv) xmove_fd(xopen(LOGFILE, O_WRONLY|O_APPEND), STDERR_FILENO); #endif +/* TODO: force validity of fds 0,1,2 as in init? */ + xchdir("/dev"); - if (argc == 2 && !strcmp(argv[1], "-s")) { + opt_complementary = "t+"; /* -t MSEC */ + opt = getopt32(argv, "sf:t:", &seqfile, &timeout); + /* NB: path in -f FNAME is relative to /dev: /dev/FNAME */ + + if (opt & 1) { /* Scan: * mdev -s */ @@ -422,8 +430,13 @@ int mdev_main(int argc, char **argv) fileAction, dirAction, temp, 0); } else { + char *seq = seq; /* for compiler */ + char *action; + char *env_path; + char seqbuf[sizeof(int)*3 + 2]; + /* Hotplug: - * env ACTION=... DEVPATH=... mdev + * env ACTION=... DEVPATH=... [SEQNUM=...] mdev * ACTION can be "add" or "remove" * DEVPATH is like "/block/sda" or "/class/input/mice" */ @@ -432,6 +445,22 @@ int mdev_main(int argc, char **argv) if (!action || !env_path) bb_show_usage(); + if (seqfile) { + seq = getenv("SEQNUM"); + if (seq) { + timeout >>= 5; /* unsigned /= 32 */ + do { + int len = open_read_close(seqfile, seqbuf, sizeof(seqbuf-1)); + if (len < 0) + break; + seqbuf[len] = '\0'; + if (strcmp(seq, seqbuf) == 0) + break; + usleep(32*1000); + } while (--timeout >= 0); + } + } + snprintf(temp, PATH_MAX, "/sys%s", env_path); if (!strcmp(action, "remove")) make_device(temp, 1); @@ -444,6 +473,10 @@ int mdev_main(int argc, char **argv) load_firmware(fw, temp); } } + + if (seqfile && seq) { + xopen_xwrite_close(seqfile, utoa(xatou(seq) + 1)); + } } if (ENABLE_FEATURE_CLEAN_UP)