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
|
||||
* symlink results in a new path that needs to be re-resolved entirely. */
|
||||
if (path[0] == '/') {
|
||||
printf("XXX: dangling symlink needs re-resolving\n");
|
||||
unlock_vnode(dirp);
|
||||
unlock_vmnt(dir_vmp);
|
||||
put_vnode(dirp);
|
||||
|
@ -391,15 +390,19 @@ printf("XXX: dangling symlink needs re-resolving\n");
|
|||
/* Try to create the inode the dangling symlink was
|
||||
* pointing to. We have to use dirp as starting point
|
||||
* 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 */
|
||||
fp->fp_wd = dirp;
|
||||
vp = new_node(resolve, oflags, bits);
|
||||
fp->fp_wd = old_wd; /* Restore */
|
||||
|
||||
if (vp != NULL) {
|
||||
unlock_vnode(dirp);
|
||||
unlock_vmnt(dir_vmp);
|
||||
put_vnode(dirp);
|
||||
*(resolve->l_vnode) = vp;
|
||||
return(vp);
|
||||
|
|
|
@ -19,7 +19,7 @@ OBJ= test1 test2 test3 test4 test5 test6 test7 test8 test9 \
|
|||
test54 test56 test58 t60a t60b
|
||||
|
||||
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
|
||||
GCCFPUOBJ= test51-gcc test52-gcc
|
||||
OTHEROBJ= test57 test59
|
||||
|
@ -133,3 +133,4 @@ test59: test59.c
|
|||
test60: test60.c
|
||||
t60a: t60a.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 \
|
||||
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\
|
||||
60 \
|
||||
60 61 \
|
||||
sh1.sh sh2.sh"
|
||||
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