[PATCH] allow multiple symlinks

Here is a patch to allow the creation of multiple symlinks.
The names must be separated by a space character.


REPLACE, KERNEL="ttyUSB0", NAME="visor", SYMLINK="first-%n second-%n third-%n"

results in:

Dec  9 05:28:51 pim udev[12019]: create_node: mknod(udev-root/visor, 020666, 188, 0)
Dec  9 05:28:51 pim udev[12019]: create_node: symlink 'udev-root/first-0' to node 'visor' requested
Dec  9 05:28:51 pim udev[12019]: create_node: symlink(./visor, udev-root/first-0)
Dec  9 05:28:51 pim udev[12019]: create_node: symlink 'udev-root/second-0' to node 'visor' requested
Dec  9 05:28:51 pim udev[12019]: create_node: symlink(./visor, udev-root/second-0)
Dec  9 05:28:51 pim udev[12019]: create_node: symlink 'udev-root/third-0' to node 'visor' requested
Dec  9 05:28:51 pim udev[12019]: create_node: symlink(./visor, udev-root/third-0)
This commit is contained in:
kay.sievers@vrfy.org 2003-12-10 00:47:00 -08:00 committed by Greg KH
parent 10a479f5e6
commit 4763256c65
3 changed files with 67 additions and 40 deletions

View file

@ -215,6 +215,15 @@ EOF
expected => "1/2/c/d/symlink" , expected => "1/2/c/d/symlink" ,
conf => <<EOF conf => <<EOF
LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/c/d/symlink" 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 EOF
}, },
); );

View file

@ -102,6 +102,8 @@ static int create_node(struct udevice *dev)
{ {
char filename[255]; char filename[255];
char linktarget[255]; char linktarget[255];
char *linkname;
char *symlinks;
int retval = 0; int retval = 0;
uid_t uid = 0; uid_t uid = 0;
gid_t gid = 0; gid_t gid = 0;
@ -186,26 +188,31 @@ static int create_node(struct udevice *dev)
filename, uid, gid, strerror(errno)); filename, uid, gid, strerror(errno));
} }
/* create symlink if requested */ /* create symlink if requested */
if (*dev->symlink) { if (*dev->symlink) {
symlinks = dev->symlink;
while (1) {
linkname = strsep(&symlinks, " ");
if (linkname == NULL)
break;
strncpy(filename, udev_root, sizeof(filename)); strncpy(filename, udev_root, sizeof(filename));
strncat(filename, dev->symlink, sizeof(filename)); strncat(filename, linkname, sizeof(filename));
dbg("symlink '%s' to node '%s' requested", filename, dev->name); dbg("symlink '%s' to node '%s' requested", filename, dev->name);
if (strrchr(dev->symlink, '/')) if (strrchr(linkname, '/'))
create_path(filename); create_path(filename);
/* optimize relative link */ /* optimize relative link */
linktarget[0] = '\0'; linktarget[0] = '\0';
i = 0; i = 0;
tail = 0; tail = 0;
while ((dev->name[i] == dev->symlink[i]) && dev->name[i]) { while ((dev->name[i] == linkname[i]) && dev->name[i]) {
if (dev->name[i] == '/') if (dev->name[i] == '/')
tail = i+1; tail = i+1;
i++; i++;
} }
while (dev->symlink[i]) { while (linkname[i]) {
if (dev->symlink[i] == '/') if (linkname[i] == '/')
strcat(linktarget, "../"); strcat(linktarget, "../");
i++; i++;
} }
@ -220,6 +227,7 @@ static int create_node(struct udevice *dev)
dbg("symlink(%s, %s) failed with error '%s'", dbg("symlink(%s, %s) failed with error '%s'",
linktarget, filename, strerror(errno)); linktarget, filename, strerror(errno));
} }
}
return retval; return retval;
} }

View file

@ -66,6 +66,8 @@ static int delete_path(char *path)
static int delete_node(struct udevice *dev) static int delete_node(struct udevice *dev)
{ {
char filename[255]; char filename[255];
char *symlinks;
char *linkname;
int retval; int retval;
strncpy(filename, udev_root, sizeof(filename)); strncpy(filename, udev_root, sizeof(filename));
@ -84,8 +86,15 @@ static int delete_node(struct udevice *dev)
delete_path(filename); delete_path(filename);
if (*dev->symlink) { if (*dev->symlink) {
symlinks = dev->symlink;
while (1) {
linkname = strsep(&symlinks, " ");
if (linkname == NULL)
break;
strncpy(filename, udev_root, sizeof(filename)); strncpy(filename, udev_root, sizeof(filename));
strncat(filename, dev->symlink, sizeof(filename)); strncat(filename, linkname, sizeof(filename));
dbg("unlinking symlink '%s'", filename); dbg("unlinking symlink '%s'", filename);
retval = unlink(filename); retval = unlink(filename);
if (retval) { if (retval) {
@ -97,6 +106,7 @@ static int delete_node(struct udevice *dev)
delete_path(filename); delete_path(filename);
} }
} }
}
return retval; return retval;
} }