summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/udev-test.pl9
-rw-r--r--udev-add.c66
-rw-r--r--udev-remove.c32
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);
+ }
}
}