# HG changeset patch # User Olaf Wintermann # Date 1652202781 -7200 # Node ID abba342112c2b772935365a500108ff29c9e4284 # Parent 7bf652914e9b442713e119a5b0a7131c54fd8352 fix that pg mkdir can create directories with trailing path separators in the nodename diff -r 7bf652914e9b -r abba342112c2 src/server/plugins/postgresql/pgtest.c --- a/src/server/plugins/postgresql/pgtest.c Mon May 09 20:56:44 2022 +0200 +++ b/src/server/plugins/postgresql/pgtest.c Tue May 10 19:13:01 2022 +0200 @@ -357,18 +357,40 @@ UCX_TEST_BEGIN; + struct stat s; + SYS_FILE f1 = vfs_open(vfs, "/test_mkdir/file", O_WRONLY|O_CREAT); UCX_TEST_ASSERT(f1 == NULL, "open should fail"); int r = vfs_mkdir(vfs, "/test_mkdir"); UCX_TEST_ASSERT(r == 0, "mkdir failed"); + r = vfs_stat(vfs, "/test_mkdir", &s); + UCX_TEST_ASSERT(r == 0, "stat (1) failed"); + + UCX_TEST_ASSERT(S_ISDIR(s.st_mode), "/test_mkdir is not a directory"); + f1 = vfs_open(vfs, "/test_mkdir/file", O_WRONLY|O_CREAT); + vfs_close(f1); UCX_TEST_ASSERT(f1, "open failed"); + r = vfs_stat(vfs, "/test_mkdir/file", &s); + UCX_TEST_ASSERT(r == 0, "stat (2) failed"); + r = vfs_mkdir(vfs, "/test_mkdir/test_sub"); UCX_TEST_ASSERT(r == 0, "mkdir failed (2)"); + r = vfs_stat(vfs, "/test_mkdir/test_sub", &s); + UCX_TEST_ASSERT(r == 0, "stat (3) failed"); + UCX_TEST_ASSERT(S_ISDIR(s.st_mode), "/test_mkdir/test_sub is not a directory"); + + r = vfs_mkdir(vfs, "/test_mkdir/test_sub/test_sub2/"); + UCX_TEST_ASSERT(r == 0, "mkdir failed (4)"); + + r = vfs_stat(vfs, "/test_mkdir/test_sub/test_sub2/", &s); + UCX_TEST_ASSERT(r == 0, "stat (4) failed"); + UCX_TEST_ASSERT(S_ISDIR(s.st_mode), "/test_mkdir/test_sub/test_sub2/ is not a directory"); + UCX_TEST_END; testutil_destroy_session(sn); diff -r 7bf652914e9b -r abba342112c2 src/server/plugins/postgresql/vfs.c --- a/src/server/plugins/postgresql/vfs.c Mon May 09 20:56:44 2022 +0200 +++ b/src/server/plugins/postgresql/vfs.c Tue May 10 19:13:01 2022 +0200 @@ -430,6 +430,15 @@ char *parent_path = util_parent_path(path); if(!parent_path) return 1; + size_t pathlen = strlen(path); + char *pathf = NULL; + if(pathlen > 1 && path[pathlen-1] == '/') { + pathf = malloc(pathlen); + memcpy(pathf, path, pathlen); + pathf[pathlen-1] = 0; // remove trailing '/' + path = pathf; + } + const char *nodename = util_resource_name(path); // resolve the parent path @@ -445,11 +454,13 @@ FREE(parent_path); if(err) { ctx->vfs_errno = ENOENT; + if(pathf) free(pathf); return 1; } // parent path exists, check if it is a collection if(!iscollection) { + if(pathf) free(pathf); return 1; } @@ -464,6 +475,8 @@ ret = pg_create_res(pg, resid_str, nodename, new_resource_id, oid, resource_name, s); } + if(pathf) free(pathf); + if(res_parent_id) { // resource_id is still the id of the parent from previous pg_resolve_path call *res_parent_id = resource_id;