]> Zhao Yanbai Git Server - minix.git/commitdiff
Allow test43 to deal with broken symlinks
authorErik van der Kouwe <erik@minix3.org>
Thu, 7 Jan 2010 09:52:23 +0000 (09:52 +0000)
committerErik van der Kouwe <erik@minix3.org>
Thu, 7 Jan 2010 09:52:23 +0000 (09:52 +0000)
lib/other/realpath.c
test/test43.c

index a2c25c1f0e0662fa59001fc77f099d4786d7e8b3..f331bd3d19fce1301e92bc04f46fb0bbe3886551 100644 (file)
@@ -91,7 +91,8 @@ static char *process_path_component(const char *component,
        if (S_ISLNK(stat_buffer.st_mode))
        {
                /* resolve symbolic link */
-               readlink_buffer_length = readlink(resolved_name, readlink_buffer, 
+               readlink_buffer_length = readlink(resolved_name, 
+                       readlink_buffer, 
                        sizeof(readlink_buffer) - 1);
                if (readlink_buffer_length < 0)
                        return NULL;
@@ -100,7 +101,8 @@ static char *process_path_component(const char *component,
                
                /* recurse to resolve path in link */
                remove_last_path_component(resolved_name);
-               if (!realpath_recurse(readlink_buffer, resolved_name, max_depth - 1))
+               if (!realpath_recurse(readlink_buffer, resolved_name, 
+                       max_depth - 1))
                        return NULL;
 
                /* stat symlink target */
index 6e9ade4868fb498bcc6629f2a57b021cc330cb85..8ff3534eb37fc17d9c46fa36661300d26be42c2a 100644 (file)
@@ -71,22 +71,56 @@ static char *remove_last_path_component(char *path)
        return path;
 }
 
+static int check_path_components(const char *path)
+{
+       char buffer[PATH_MAX + 1], *bufferpos;
+       struct stat statbuf;
+
+       assert(strlen(path) < sizeof(buffer));
+
+       bufferpos = buffer;
+       while (*path)
+       {
+               /* copy next path segment */
+               do 
+               {
+                       *(bufferpos++) = *(path++);
+               } while (*path && *path != '/');
+               *bufferpos = 0;
+
+               /* 
+                * is this a valid path segment? if not, return errno.
+                * one exception: the last path component need not exist
+                */
+               if (stat(buffer, &statbuf) < 0 &&
+                       (*path || errno != ENOENT))
+                       return errno;
+       }
+
+       return 0;
+}
+
 static void check_realpath(const char *path, int expected_errno)
 {
        char buffer[PATH_MAX + 1], *resolved_path;
+       int expected_errno2;
        struct stat statbuf[2];
 
        assert(path);
+
+       /* any errors in the path that realpath should report? */
+       expected_errno2 = check_path_components(path);
        
        /* run realpath */
        subtest = path;
+       errno = 0;
        resolved_path = realpath(path, buffer);
 
        /* do we get errors when expected? */
-       if (expected_errno)
+       if (expected_errno || expected_errno2)
        {
-               if (errno != expected_errno) ERR;
                if (resolved_path) ERR;
+               if (errno != expected_errno && errno != expected_errno2) ERR;
                subtest = NULL;
                return;
        }
@@ -100,11 +134,17 @@ static void check_realpath(const char *path, int expected_errno)
        }
        errno = 0;
 
-       /* do the paths point to the same file? */
-       if (stat(path,          &statbuf[0]) < 0) { ERR; return; }
-       if (stat(resolved_path, &statbuf[1]) < 0) { ERR; return; }
-       if (statbuf[0].st_dev != statbuf[1].st_dev) ERR;
-       if (statbuf[0].st_ino != statbuf[1].st_ino) ERR;
+       /* do the paths point to the same file? (only check if exists) */
+       if (stat(path,          &statbuf[0]) < 0) 
+       {
+               if (errno != ENOENT) { ERR; return; }
+       }
+       else
+       {
+               if (stat(resolved_path, &statbuf[1]) < 0) { ERR; return; }
+               if (statbuf[0].st_dev != statbuf[1].st_dev) ERR;
+               if (statbuf[0].st_ino != statbuf[1].st_ino) ERR;
+       }
 
        /* is the path absolute? */
        if (resolved_path[0] != '/') ERR;
@@ -186,7 +226,7 @@ static void check_realpath_recurse(const char *path, int depth)
        /* loop through subdirectories (including . and ..) */
        if (!(dir = opendir(path))) 
        {
-               if (errno != ENOTDIR)
+               if (errno != ENOENT && errno != ENOTDIR)
                        ERR;
                return;
        }