Allow test43 to deal with broken symlinks
This commit is contained in:
parent
38ed5b2685
commit
413a8083b9
2 changed files with 52 additions and 10 deletions
|
@ -91,7 +91,8 @@ static char *process_path_component(const char *component,
|
||||||
if (S_ISLNK(stat_buffer.st_mode))
|
if (S_ISLNK(stat_buffer.st_mode))
|
||||||
{
|
{
|
||||||
/* resolve symbolic link */
|
/* resolve symbolic link */
|
||||||
readlink_buffer_length = readlink(resolved_name, readlink_buffer,
|
readlink_buffer_length = readlink(resolved_name,
|
||||||
|
readlink_buffer,
|
||||||
sizeof(readlink_buffer) - 1);
|
sizeof(readlink_buffer) - 1);
|
||||||
if (readlink_buffer_length < 0)
|
if (readlink_buffer_length < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -100,7 +101,8 @@ static char *process_path_component(const char *component,
|
||||||
|
|
||||||
/* recurse to resolve path in link */
|
/* recurse to resolve path in link */
|
||||||
remove_last_path_component(resolved_name);
|
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;
|
return NULL;
|
||||||
|
|
||||||
/* stat symlink target */
|
/* stat symlink target */
|
||||||
|
|
|
@ -71,22 +71,56 @@ static char *remove_last_path_component(char *path)
|
||||||
return 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)
|
static void check_realpath(const char *path, int expected_errno)
|
||||||
{
|
{
|
||||||
char buffer[PATH_MAX + 1], *resolved_path;
|
char buffer[PATH_MAX + 1], *resolved_path;
|
||||||
|
int expected_errno2;
|
||||||
struct stat statbuf[2];
|
struct stat statbuf[2];
|
||||||
|
|
||||||
assert(path);
|
assert(path);
|
||||||
|
|
||||||
|
/* any errors in the path that realpath should report? */
|
||||||
|
expected_errno2 = check_path_components(path);
|
||||||
|
|
||||||
/* run realpath */
|
/* run realpath */
|
||||||
subtest = path;
|
subtest = path;
|
||||||
|
errno = 0;
|
||||||
resolved_path = realpath(path, buffer);
|
resolved_path = realpath(path, buffer);
|
||||||
|
|
||||||
/* do we get errors when expected? */
|
/* do we get errors when expected? */
|
||||||
if (expected_errno)
|
if (expected_errno || expected_errno2)
|
||||||
{
|
{
|
||||||
if (errno != expected_errno) ERR;
|
|
||||||
if (resolved_path) ERR;
|
if (resolved_path) ERR;
|
||||||
|
if (errno != expected_errno && errno != expected_errno2) ERR;
|
||||||
subtest = NULL;
|
subtest = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -100,11 +134,17 @@ static void check_realpath(const char *path, int expected_errno)
|
||||||
}
|
}
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
/* do the paths point to the same file? */
|
/* do the paths point to the same file? (only check if exists) */
|
||||||
if (stat(path, &statbuf[0]) < 0) { ERR; return; }
|
if (stat(path, &statbuf[0]) < 0)
|
||||||
if (stat(resolved_path, &statbuf[1]) < 0) { ERR; return; }
|
{
|
||||||
if (statbuf[0].st_dev != statbuf[1].st_dev) ERR;
|
if (errno != ENOENT) { ERR; return; }
|
||||||
if (statbuf[0].st_ino != statbuf[1].st_ino) ERR;
|
}
|
||||||
|
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? */
|
/* is the path absolute? */
|
||||||
if (resolved_path[0] != '/') ERR;
|
if (resolved_path[0] != '/') ERR;
|
||||||
|
@ -186,7 +226,7 @@ static void check_realpath_recurse(const char *path, int depth)
|
||||||
/* loop through subdirectories (including . and ..) */
|
/* loop through subdirectories (including . and ..) */
|
||||||
if (!(dir = opendir(path)))
|
if (!(dir = opendir(path)))
|
||||||
{
|
{
|
||||||
if (errno != ENOTDIR)
|
if (errno != ENOENT && errno != ENOTDIR)
|
||||||
ERR;
|
ERR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue