diff options
-rw-r--r-- | test/udev-test.pl | 9 | ||||
-rw-r--r-- | udev-add.c | 66 | ||||
-rw-r--r-- | udev-remove.c | 32 |
3 files changed, 67 insertions, 40 deletions
diff --git a/test/udev-test.pl b/test/udev-test.pl index 190b7ce4d6..39d8450c34 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -217,6 +217,15 @@ EOF LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/c/d/symlink" EOF }, + { + desc => "multiple symlinks", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + expected => "second-0" , + conf => <<EOF +REPLACE, KERNEL="ttyUSB0", NAME="visor", SYMLINK="first-%n second-%n third-%n" +EOF + }, ); # set env diff --git a/udev-add.c b/udev-add.c index 17b69eadab..e64a845c7e 100644 --- a/udev-add.c +++ b/udev-add.c @@ -102,6 +102,8 @@ static int create_node(struct udevice *dev) { char filename[255]; char linktarget[255]; + char *linkname; + char *symlinks; int retval = 0; uid_t uid = 0; gid_t gid = 0; @@ -186,39 +188,45 @@ static int create_node(struct udevice *dev) filename, uid, gid, strerror(errno)); } - /* create symlink if requested */ if (*dev->symlink) { - strncpy(filename, udev_root, sizeof(filename)); - strncat(filename, dev->symlink, sizeof(filename)); - dbg("symlink '%s' to node '%s' requested", filename, dev->name); - if (strrchr(dev->symlink, '/')) - create_path(filename); - - /* optimize relative link */ - linktarget[0] = '\0'; - i = 0; - tail = 0; - while ((dev->name[i] == dev->symlink[i]) && dev->name[i]) { - if (dev->name[i] == '/') - tail = i+1; - i++; - } - while (dev->symlink[i]) { - if (dev->symlink[i] == '/') - strcat(linktarget, "../"); - i++; - } + symlinks = dev->symlink; + while (1) { + linkname = strsep(&symlinks, " "); + if (linkname == NULL) + break; + + strncpy(filename, udev_root, sizeof(filename)); + strncat(filename, linkname, sizeof(filename)); + dbg("symlink '%s' to node '%s' requested", filename, dev->name); + if (strrchr(linkname, '/')) + create_path(filename); + + /* optimize relative link */ + linktarget[0] = '\0'; + i = 0; + tail = 0; + while ((dev->name[i] == linkname[i]) && dev->name[i]) { + if (dev->name[i] == '/') + tail = i+1; + i++; + } + while (linkname[i]) { + if (linkname[i] == '/') + strcat(linktarget, "../"); + i++; + } - if (*linktarget == '\0') - strcpy(linktarget, "./"); - strcat(linktarget, &dev->name[tail]); + if (*linktarget == '\0') + strcpy(linktarget, "./"); + strcat(linktarget, &dev->name[tail]); - dbg("symlink(%s, %s)", linktarget, filename); - retval = symlink(linktarget, filename); - if (retval) - dbg("symlink(%s, %s) failed with error '%s'", - linktarget, filename, strerror(errno)); + dbg("symlink(%s, %s)", linktarget, filename); + retval = symlink(linktarget, filename); + if (retval) + dbg("symlink(%s, %s) failed with error '%s'", + linktarget, filename, strerror(errno)); + } } return retval; diff --git a/udev-remove.c b/udev-remove.c index 02c84371a4..0886c23343 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -66,6 +66,8 @@ static int delete_path(char *path) static int delete_node(struct udevice *dev) { char filename[255]; + char *symlinks; + char *linkname; int retval; strncpy(filename, udev_root, sizeof(filename)); @@ -84,17 +86,25 @@ static int delete_node(struct udevice *dev) delete_path(filename); if (*dev->symlink) { - strncpy(filename, udev_root, sizeof(filename)); - strncat(filename, dev->symlink, sizeof(filename)); - dbg("unlinking symlink '%s'", filename); - retval = unlink(filename); - if (retval) { - dbg("unlink(%s) failed with error '%s'", - filename, strerror(errno)); - return retval; - } - if (strchr(dev->symlink, '/')) { - delete_path(filename); + symlinks = dev->symlink; + while (1) { + linkname = strsep(&symlinks, " "); + if (linkname == NULL) + break; + + strncpy(filename, udev_root, sizeof(filename)); + strncat(filename, linkname, sizeof(filename)); + + dbg("unlinking symlink '%s'", filename); + retval = unlink(filename); + if (retval) { + dbg("unlink(%s) failed with error '%s'", + filename, strerror(errno)); + return retval; + } + if (strchr(dev->symlink, '/')) { + delete_path(filename); + } } } |