aboutsummaryrefslogtreecommitdiff
path: root/util-linux/mdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'util-linux/mdev.c')
-rw-r--r--util-linux/mdev.c47
1 files changed, 35 insertions, 12 deletions
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index 1d741367e..e80b58f2e 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -295,8 +295,8 @@ struct globals {
295/* Prevent infinite loops in /sys symlinks */ 295/* Prevent infinite loops in /sys symlinks */
296#define MAX_SYSFS_DEPTH 3 296#define MAX_SYSFS_DEPTH 3
297 297
298/* We use additional 64+ bytes in make_device() */ 298/* We use additional bytes in make_device() */
299#define SCRATCH_SIZE 80 299#define SCRATCH_SIZE 128
300 300
301#if ENABLE_FEATURE_MDEV_CONF 301#if ENABLE_FEATURE_MDEV_CONF
302 302
@@ -541,7 +541,7 @@ static char *build_alias(char *alias, const char *device_name)
541 541
542/* mknod in /dev based on a path like "/sys/block/hda/hda1" 542/* mknod in /dev based on a path like "/sys/block/hda/hda1"
543 * NB1: path parameter needs to have SCRATCH_SIZE scratch bytes 543 * NB1: path parameter needs to have SCRATCH_SIZE scratch bytes
544 * after NUL, but we promise to not mangle (IOW: to restore if needed) 544 * after NUL, but we promise to not mangle (IOW: to restore NUL if needed)
545 * path string. 545 * path string.
546 * NB2: "mdev -s" may call us many times, do not leak memory/fds! 546 * NB2: "mdev -s" may call us many times, do not leak memory/fds!
547 * 547 *
@@ -551,6 +551,7 @@ static char *build_alias(char *alias, const char *device_name)
551static void make_device(char *device_name, char *path, int operation) 551static void make_device(char *device_name, char *path, int operation)
552{ 552{
553 int major, minor, type, len; 553 int major, minor, type, len;
554 char *path_end = path + strlen(path);
554 555
555 /* Try to read major/minor string. Note that the kernel puts \n after 556 /* Try to read major/minor string. Note that the kernel puts \n after
556 * the data, so we don't need to worry about null terminating the string 557 * the data, so we don't need to worry about null terminating the string
@@ -559,17 +560,15 @@ static void make_device(char *device_name, char *path, int operation)
559 */ 560 */
560 major = -1; 561 major = -1;
561 if (operation == OP_add) { 562 if (operation == OP_add) {
562 char *dev_maj_min = path + strlen(path); 563 strcpy(path_end, "/dev");
563 564 len = open_read_close(path, path_end + 1, SCRATCH_SIZE - 1);
564 strcpy(dev_maj_min, "/dev"); 565 *path_end = '\0';
565 len = open_read_close(path, dev_maj_min + 1, 64);
566 *dev_maj_min = '\0';
567 if (len < 1) { 566 if (len < 1) {
568 if (!ENABLE_FEATURE_MDEV_EXEC) 567 if (!ENABLE_FEATURE_MDEV_EXEC)
569 return; 568 return;
570 /* no "dev" file, but we can still run scripts 569 /* no "dev" file, but we can still run scripts
571 * based on device name */ 570 * based on device name */
572 } else if (sscanf(++dev_maj_min, "%u:%u", &major, &minor) == 2) { 571 } else if (sscanf(path_end + 1, "%u:%u", &major, &minor) == 2) {
573 dbg1("dev %u,%u", major, minor); 572 dbg1("dev %u,%u", major, minor);
574 } else { 573 } else {
575 major = -1; 574 major = -1;
@@ -577,9 +576,33 @@ static void make_device(char *device_name, char *path, int operation)
577 } 576 }
578 /* else: for delete, -1 still deletes the node, but < -1 suppresses that */ 577 /* else: for delete, -1 still deletes the node, but < -1 suppresses that */
579 578
580 /* Determine device name, type, major and minor */ 579 /* Determine device name */
581 if (!device_name) 580 if (!device_name) {
582 device_name = (char*) bb_basename(path); 581 /*
582 * There was no $DEVNAME envvar (for example, mdev -s never has).
583 * But it is very useful: it contains the *path*, not only basename,
584 * Thankfully, uevent file has it.
585 * Example of .../sound/card0/controlC0/uevent file on Linux-3.7.7:
586 * MAJOR=116
587 * MINOR=7
588 * DEVNAME=snd/controlC0
589 */
590 strcpy(path_end, "/uevent");
591 len = open_read_close(path, path_end + 1, SCRATCH_SIZE - 1);
592 if (len < 0)
593 len = 0;
594 *path_end = '\0';
595 path_end[1 + len] = '\0';
596 device_name = strstr(path_end + 1, "\nDEVNAME=");
597 if (device_name) {
598 device_name += sizeof("\nDEVNAME=")-1;
599 strchrnul(device_name, '\n')[0] = '\0';
600 } else {
601 /* Fall back to just basename */
602 device_name = (char*) bb_basename(path);
603 }
604 }
605 /* Determine device type */
583 /* 606 /*
584 * http://kernel.org/doc/pending/hotplug.txt says that only 607 * http://kernel.org/doc/pending/hotplug.txt says that only
585 * "/sys/block/..." is for block devices. "/sys/bus" etc is not. 608 * "/sys/block/..." is for block devices. "/sys/bus" etc is not.