Fix dangling symlink resolving for AVFS and add test61
This commit is contained in:
parent
21168577a5
commit
706873142e
4 changed files with 97 additions and 6 deletions
|
@ -326,7 +326,6 @@ PRIVATE struct vnode *new_node(struct lookup *resolve, int oflags, mode_t bits)
|
||||||
/* The combination of a symlink with absolute path followed by a danglink
|
/* The combination of a symlink with absolute path followed by a danglink
|
||||||
* symlink results in a new path that needs to be re-resolved entirely. */
|
* symlink results in a new path that needs to be re-resolved entirely. */
|
||||||
if (path[0] == '/') {
|
if (path[0] == '/') {
|
||||||
printf("XXX: dangling symlink needs re-resolving\n");
|
|
||||||
unlock_vnode(dirp);
|
unlock_vnode(dirp);
|
||||||
unlock_vmnt(dir_vmp);
|
unlock_vmnt(dir_vmp);
|
||||||
put_vnode(dirp);
|
put_vnode(dirp);
|
||||||
|
@ -391,15 +390,19 @@ printf("XXX: dangling symlink needs re-resolving\n");
|
||||||
/* Try to create the inode the dangling symlink was
|
/* Try to create the inode the dangling symlink was
|
||||||
* pointing to. We have to use dirp as starting point
|
* pointing to. We have to use dirp as starting point
|
||||||
* as there might be multiple successive symlinks
|
* as there might be multiple successive symlinks
|
||||||
* crossing multiple mountpoints. */
|
* crossing multiple mountpoints.
|
||||||
|
* Unlock vnodes and vmnts as we're going to recurse.
|
||||||
|
*/
|
||||||
|
unlock_vnode(dirp);
|
||||||
|
unlock_vnode(vp);
|
||||||
|
unlock_vmnt(dir_vmp);
|
||||||
|
|
||||||
old_wd = fp->fp_wd; /* Save orig. working dirp */
|
old_wd = fp->fp_wd; /* Save orig. working dirp */
|
||||||
fp->fp_wd = dirp;
|
fp->fp_wd = dirp;
|
||||||
vp = new_node(resolve, oflags, bits);
|
vp = new_node(resolve, oflags, bits);
|
||||||
fp->fp_wd = old_wd; /* Restore */
|
fp->fp_wd = old_wd; /* Restore */
|
||||||
|
|
||||||
if (vp != NULL) {
|
if (vp != NULL) {
|
||||||
unlock_vnode(dirp);
|
|
||||||
unlock_vmnt(dir_vmp);
|
|
||||||
put_vnode(dirp);
|
put_vnode(dirp);
|
||||||
*(resolve->l_vnode) = vp;
|
*(resolve->l_vnode) = vp;
|
||||||
return(vp);
|
return(vp);
|
||||||
|
|
|
@ -19,7 +19,7 @@ OBJ= test1 test2 test3 test4 test5 test6 test7 test8 test9 \
|
||||||
test54 test56 test58 t60a t60b
|
test54 test56 test58 t60a t60b
|
||||||
|
|
||||||
BIGOBJ= test20 test24
|
BIGOBJ= test20 test24
|
||||||
ROOTOBJ= test11 test33 test43 test44 test46 test60
|
ROOTOBJ= test11 test33 test43 test44 test46 test60 test61
|
||||||
GCCOBJ= test45-gcc test48 test49-gcc test55
|
GCCOBJ= test45-gcc test48 test49-gcc test55
|
||||||
GCCFPUOBJ= test51-gcc test52-gcc
|
GCCFPUOBJ= test51-gcc test52-gcc
|
||||||
OTHEROBJ= test57 test59
|
OTHEROBJ= test57 test59
|
||||||
|
@ -133,3 +133,4 @@ test59: test59.c
|
||||||
test60: test60.c
|
test60: test60.c
|
||||||
t60a: t60a.c
|
t60a: t60a.c
|
||||||
t60b: t60b.c
|
t60b: t60b.c
|
||||||
|
test61: test61.c
|
||||||
|
|
2
test/run
2
test/run
|
@ -15,7 +15,7 @@ tests=" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
|
||||||
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
|
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
|
||||||
41 42 43 44 45 45-gcc 46 47 48 49 49-gcc 50 \
|
41 42 43 44 45 45-gcc 46 47 48 49 49-gcc 50 \
|
||||||
51 51-gcc 52 52-gcc 53 54 55 56 57 58 59\
|
51 51-gcc 52 52-gcc 53 54 55 56 57 58 59\
|
||||||
60 \
|
60 61 \
|
||||||
sh1.sh sh2.sh"
|
sh1.sh sh2.sh"
|
||||||
tests_no=`expr 0`
|
tests_no=`expr 0`
|
||||||
|
|
||||||
|
|
87
test/test61.c
Normal file
87
test/test61.c
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define MAX_ERROR 5
|
||||||
|
#include "common.c"
|
||||||
|
|
||||||
|
void dangling_slink(int sub_test, char const slink_to[PATH_MAX]);
|
||||||
|
|
||||||
|
void dangling_slink(int sub_test, char const slink_to[PATH_MAX])
|
||||||
|
{
|
||||||
|
pid_t child;
|
||||||
|
|
||||||
|
subtest = sub_test;
|
||||||
|
|
||||||
|
child = fork();
|
||||||
|
if (child == (pid_t) -1) {
|
||||||
|
e(1);
|
||||||
|
return;
|
||||||
|
} else if (child == (pid_t) 0) {
|
||||||
|
/* I'm the child. Create a dangling symlink with an absolute path */
|
||||||
|
int fd;
|
||||||
|
char buf[4];
|
||||||
|
|
||||||
|
|
||||||
|
/* We don't want to actually write to '/', so instead we pretend */
|
||||||
|
if (chroot(".") != 0) e(2);
|
||||||
|
|
||||||
|
/* Create file 'slink_to' with contents "bar" */
|
||||||
|
if ((fd = open(slink_to, O_CREAT|O_WRONLY)) == -1) e(3);
|
||||||
|
if (write(fd, "bar", strlen("bar")) != strlen("bar")) e(4);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
if (symlink(slink_to, "a") == -1) e(5); /* Create the symlink */
|
||||||
|
if (rename(slink_to, "c") == -1) e(6); /* Make it a dangling symlink */
|
||||||
|
|
||||||
|
/* Write "foo" to symlink; this should recreate file 'slink_to' with
|
||||||
|
* contents "foo" */
|
||||||
|
if ((fd = open("a", O_CREAT|O_WRONLY)) == -1) e(7);
|
||||||
|
if (write(fd, "foo", strlen("foo")) != strlen("foo")) e(8);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
/* Verify 'a' and 'slink_to' contain "foo" */
|
||||||
|
memset(buf, '\0', sizeof(buf));
|
||||||
|
if ((fd = open("a", O_RDONLY)) == -1) e(9);
|
||||||
|
if (read(fd, buf, 3) != 3) e(10);
|
||||||
|
if (strncmp(buf, "foo", strlen("foo"))) e(11);
|
||||||
|
close(fd);
|
||||||
|
memset(buf, '\0', sizeof(buf));
|
||||||
|
if ((fd = open(slink_to, O_RDONLY)) == -1) e(12);
|
||||||
|
if (read(fd, buf, 3) != 3) e(13);
|
||||||
|
if (strncmp(buf, "foo", strlen("foo"))) e(14);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
/* Verify 'c' contains 'bar' */
|
||||||
|
memset(buf, '\0', sizeof(buf));
|
||||||
|
if ((fd = open("c", O_RDONLY)) == -1) e(15);
|
||||||
|
if (read(fd, buf, 3) != 3) e(16);
|
||||||
|
if (strncmp(buf, "bar", strlen("bar"))) e(17);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
/* Cleanup created files */
|
||||||
|
if (unlink(slink_to) == -1) e(18);
|
||||||
|
if (unlink("a") == -1) e(19);
|
||||||
|
if (unlink("c") == -1) e(20);
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
} else {
|
||||||
|
int status;
|
||||||
|
if (wait(&status) == -1) e(7);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
start(61);
|
||||||
|
dangling_slink(1, "/abs"); /* Create dangling symlink with absolute path */
|
||||||
|
dangling_slink(2, "rel"); /* Create dangling symlink with relative path */
|
||||||
|
quit();
|
||||||
|
return(-1); /* Unreachable */
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue