libc: strip trailing '/' for directory operations

Fixes #2686
This commit is contained in:
Norman Feske 2020-05-04 14:39:51 +02:00
parent 151828752c
commit eb0a33302a
2 changed files with 34 additions and 19 deletions

View File

@ -386,6 +386,7 @@ extern "C" int mkdir(const char *path, mode_t mode)
try {
Absolute_path resolved_path;
resolve_symlinks_except_last_element(path, resolved_path);
resolved_path.remove_trailing('/');
FNAME_FUNC_WRAPPER(mkdir, resolved_path.base(), mode);
} catch(Symlink_resolve_error) {
return -1;
@ -608,6 +609,10 @@ extern "C" int rename(const char *oldpath, const char *newpath)
Absolute_path resolved_oldpath, resolved_newpath;
resolve_symlinks_except_last_element(oldpath, resolved_oldpath);
resolve_symlinks_except_last_element(newpath, resolved_newpath);
resolved_oldpath.remove_trailing('/');
resolved_newpath.remove_trailing('/');
FNAME_FUNC_WRAPPER(rename, resolved_oldpath.base(), resolved_newpath.base());
} catch(Symlink_resolve_error) {
return -1;
@ -617,19 +622,21 @@ extern "C" int rename(const char *oldpath, const char *newpath)
extern "C" int rmdir(const char *path)
{
struct stat stat_buf;
if (stat(path, &stat_buf) == -1)
return -1;
if (!S_ISDIR(stat_buf.st_mode)) {
errno = ENOTDIR;
return -1;
}
try {
Absolute_path resolved_path;
resolve_symlinks_except_last_element(path, resolved_path);
resolved_path.remove_trailing('/');
struct stat stat_buf { };
if (stat(resolved_path.base(), &stat_buf) == -1)
return -1;
if (!S_ISDIR(stat_buf.st_mode)) {
errno = ENOTDIR;
return -1;
}
FNAME_FUNC_WRAPPER(rmdir, resolved_path.base());
} catch(Symlink_resolve_error) {
return -1;

View File

@ -97,16 +97,18 @@ static void test(Genode::Xml_node node)
int ret, fd;
ssize_t count;
char const *dir_name = "testdir";
char const *dir_name2 = "testdir2";
char const *file_name = "test.tst";
char const *file_name2 = "test2.tst";
char const *file_name3 = "test3.tst";
char const *file_name4 = "test4.tst";
char const *file_name5 = "test5.tst";
char const *pattern = "a single line of text";
char const *trailing_slash_dir_name = "testdir/";
size_t pattern_size = strlen(pattern) + 1;
char const *dir_name = "testdir";
char const *dir_name2 = "testdir2";
char const *file_name = "test.tst";
char const *file_name2 = "test2.tst";
char const *file_name3 = "test3.tst";
char const *file_name4 = "test4.tst";
char const *file_name5 = "test5.tst";
char const *pattern = "a single line of text";
size_t const pattern_size = strlen(pattern) + 1;
unsigned int iterations = 1;
@ -116,6 +118,12 @@ static void test(Genode::Xml_node node)
for (unsigned int i = 0; i < iterations; i++) {
/* create directory given with a trailing slash */
CALL_AND_CHECK(ret, mkdir(trailing_slash_dir_name, 0777), (ret == 0), "dir_name=%s", dir_name);
/* remove directory given with a trailing slash */
CALL_AND_CHECK(ret, rmdir(trailing_slash_dir_name), (ret == 0), "dir_name=%s", dir_name);
/* create directory (short name) */
CALL_AND_CHECK(ret, mkdir(dir_name, 0777), ((ret == 0) || (errno == EEXIST)), "dir_name=%s", dir_name);