Skip to content

Commit 612e056

Browse files
committed
Correct create_cache_dir() and adjust tests.
1 parent ccaaf3f commit 612e056

File tree

2 files changed

+131
-96
lines changed

2 files changed

+131
-96
lines changed

libmamba/src/core/subdir_index.cpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,10 @@ namespace mamba
10431043
auto create_cache_dir(const fs::u8path& cache_path) -> std::string
10441044
{
10451045
const auto cache_dir = cache_path / "cache";
1046-
fs::create_directories(cache_dir);
1046+
if (!std::filesystem::is_directory(cache_dir))
1047+
{
1048+
fs::create_directories(cache_dir);
1049+
}
10471050

10481051
// Some filesystems don't support special permissions such as setgid on directories (e.g.
10491052
// NFS). and fail if we try to set the setgid bit on the cache directory.
@@ -1062,17 +1065,21 @@ namespace mamba
10621065
LOG_TRACE << "Set permissions on cache directory " << cache_dir << " to 'rwxrwxr-x'";
10631066
}
10641067

1065-
std::error_code ec;
1066-
fs::permissions(cache_dir, fs::perms::set_gid, fs::perm_options::add, ec);
1067-
1068-
if (!ec)
1069-
{
1070-
LOG_TRACE << "Set setgid bit on cache directory " << cache_dir;
1071-
}
1072-
else
1068+
const auto setgid_perms = fs::perms::set_gid;
1069+
if (!fs::has_permissions(cache_dir, setgid_perms))
10731070
{
1074-
LOG_TRACE << "Could not set setgid bit on cache directory " << cache_dir
1075-
<< "\nReason:" << ec.message() << "; ignoring and continuing";
1071+
std::error_code ec;
1072+
fs::permissions(cache_dir, setgid_perms, fs::perm_options::add, ec);
1073+
1074+
if (!ec)
1075+
{
1076+
LOG_TRACE << "Set setgid bit on cache directory " << cache_dir;
1077+
}
1078+
else
1079+
{
1080+
LOG_TRACE << "Could not set setgid bit on cache directory " << cache_dir
1081+
<< "\nReason:" << ec.message() << "; ignoring and continuing";
1082+
}
10761083
}
10771084

10781085
return cache_dir.string();

libmamba/tests/src/core/test_filesystem.cpp

Lines changed: 113 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -293,91 +293,6 @@ namespace mamba
293293
}
294294
}
295295

296-
namespace {
297-
TEST_CASE("has_permissions()")
298-
{
299-
// Create temp folder
300-
const auto tmp_dir = fs::temp_directory_path()
301-
/ "mamba-fs-has_permissions";
302-
fs::create_directories(tmp_dir);
303-
304-
// Create file
305-
const auto some_file = tmp_dir / "some_file";
306-
{
307-
std::ofstream ofs{ some_file.std_path(),
308-
std::ofstream::binary
309-
| std::ofstream::trunc };
310-
ofs << "ABC" << std::endl;
311-
}
312-
313-
// Set permissions
314-
const auto perms = fs::perms::owner_read | fs::perms::owner_write
315-
| fs::perms::group_read;
316-
fs::permissions(some_file, perms, fs::perm_options::replace);
317-
318-
// Check permissions
319-
REQUIRE(fs::has_permissions(some_file, perms));
320-
REQUIRE(fs::has_permissions(some_file, fs::perms::owner_read));
321-
REQUIRE(fs::has_permissions(some_file, fs::perms::owner_write));
322-
REQUIRE(fs::has_permissions(some_file, fs::perms::group_read));
323-
REQUIRE(fs::has_permissions(some_file, fs::perms::owner_read
324-
| fs::perms::owner_write));
325-
REQUIRE(fs::has_permissions(some_file, fs::perms::owner_read
326-
| fs::perms::group_read));
327-
REQUIRE(fs::has_permissions(some_file, fs::perms::owner_write
328-
| fs::perms::group_read));
329-
REQUIRE_FALSE(fs::has_permissions(some_file,
330-
fs::perms::owner_exec));
331-
REQUIRE_FALSE(fs::has_permissions(some_file,
332-
fs::perms::group_write));
333-
REQUIRE_FALSE(fs::has_permissions(some_file,
334-
fs::perms::group_exec));
335-
REQUIRE_FALSE(fs::has_permissions(some_file,
336-
fs::perms::others_read));
337-
REQUIRE_FALSE(fs::has_permissions(some_file,
338-
fs::perms::others_write));
339-
REQUIRE_FALSE(fs::has_permissions(some_file,
340-
fs::perms::others_exec));
341-
REQUIRE_FALSE(fs::has_permissions(some_file, fs::perms::owner_read
342-
| fs::perms::owner_exec));
343-
344-
fs::remove_all(tmp_dir);
345-
}
346-
347-
// 2025-11-27 make_executable() bug
348-
TEST_CASE("Bug: failure when calling make_executable()"
349-
" on already executable file inside non-writable folder.")
350-
{
351-
// Create temp folder
352-
const auto tmp_dir = fs::temp_directory_path()
353-
/ "mamba-fs-make_executable-2025-11-27-bug";
354-
mamba::on_scope_exit _([&] { fs::remove_all(tmp_dir); });
355-
const auto folder = tmp_dir / "some_folder";
356-
fs::create_directories(folder);
357-
358-
// Create file
359-
const auto some_file = tmp_dir / "some_file";
360-
{
361-
std::ofstream ofs{ some_file.std_path(),
362-
std::ofstream::binary
363-
| std::ofstream::trunc };
364-
ofs << "ABC" << std::endl;
365-
}
366-
367-
// Make executable
368-
make_executable(some_file);
369-
370-
// Remove write permissions on folder
371-
const auto perms = fs::perms::owner_read
372-
| fs::perms::group_read | fs::perms::others_read;
373-
fs::permissions(folder, perms, fs::perm_options::replace);
374-
375-
// Make executable (again!)
376-
// This should not fail
377-
make_executable(some_file);
378-
}
379-
}
380-
381296
namespace
382297
{
383298
TEST_CASE("remove_readonly_file")
@@ -537,4 +452,117 @@ namespace mamba
537452

538453
}
539454

455+
namespace
456+
{
457+
TEST_CASE("has_permissions()")
458+
{
459+
// Create temp folder
460+
const auto tmp_dir = fs::temp_directory_path() / "mamba-fs-has_permissions";
461+
mamba::on_scope_exit _([&] { fs::remove_all(tmp_dir); });
462+
fs::create_directories(tmp_dir);
463+
464+
// Create file
465+
const auto some_file = tmp_dir / "some_file";
466+
{
467+
std::ofstream ofs{ some_file.std_path(),
468+
std::ofstream::binary | std::ofstream::trunc };
469+
ofs << "ABC" << std::endl;
470+
}
471+
472+
// Set permissions
473+
const auto perms = fs::perms::owner_read | fs::perms::owner_write | fs::perms::group_read;
474+
fs::permissions(some_file, perms, fs::perm_options::replace);
475+
476+
// Check permissions
477+
REQUIRE(fs::has_permissions(some_file, perms));
478+
REQUIRE(fs::has_permissions(some_file, fs::perms::owner_read));
479+
REQUIRE(fs::has_permissions(some_file, fs::perms::owner_write));
480+
REQUIRE(fs::has_permissions(some_file, fs::perms::group_read));
481+
REQUIRE(fs::has_permissions(some_file, fs::perms::owner_read | fs::perms::owner_write));
482+
REQUIRE(fs::has_permissions(some_file, fs::perms::owner_read | fs::perms::group_read));
483+
REQUIRE(fs::has_permissions(some_file, fs::perms::owner_write | fs::perms::group_read));
484+
REQUIRE_FALSE(fs::has_permissions(some_file, fs::perms::owner_exec));
485+
REQUIRE_FALSE(fs::has_permissions(some_file, fs::perms::group_write));
486+
REQUIRE_FALSE(fs::has_permissions(some_file, fs::perms::group_exec));
487+
REQUIRE_FALSE(fs::has_permissions(some_file, fs::perms::others_read));
488+
REQUIRE_FALSE(fs::has_permissions(some_file, fs::perms::others_write));
489+
REQUIRE_FALSE(fs::has_permissions(some_file, fs::perms::others_exec));
490+
REQUIRE_FALSE(
491+
fs::has_permissions(some_file, fs::perms::owner_read | fs::perms::owner_exec)
492+
);
493+
}
494+
495+
// 2025-11-27 make_executable() bug
496+
TEST_CASE(
497+
"Bug: failure when calling make_executable()"
498+
" on already executable file inside non-writable folder."
499+
)
500+
{
501+
// Create temp folder
502+
const auto tmp_dir = fs::temp_directory_path()
503+
/ "mamba-fs-make_executable-2025-11-27-bug";
504+
mamba::on_scope_exit _([&] { fs::remove_all(tmp_dir); });
505+
const auto folder = tmp_dir / "some_folder";
506+
fs::create_directories(folder);
507+
508+
// Create file
509+
const auto some_file = tmp_dir / "some_file";
510+
{
511+
std::ofstream ofs{ some_file.std_path(),
512+
std::ofstream::binary | std::ofstream::trunc };
513+
ofs << "ABC" << std::endl;
514+
}
515+
516+
// Make executable
517+
make_executable(some_file);
518+
519+
// Remove write permissions on parent folder
520+
const auto perms = fs::perms::owner_read | fs::perms::owner_exec | fs::perms::group_read
521+
| fs::perms::group_exec | fs::perms::others_read
522+
| fs::perms::others_exec;
523+
fs::permissions(folder, perms, fs::perm_options::replace);
524+
525+
// Make executable (again!)
526+
// This should not fail
527+
make_executable(some_file);
528+
529+
// Reset writing permission
530+
const auto write_perms = fs::perms::owner_all;
531+
fs::permissions(folder, write_perms, fs::perm_options::replace);
532+
}
533+
534+
// 2025-11-27 create_cache_dir() bug
535+
TEST_CASE(
536+
"Bug: failure when calling create_cache_dir()"
537+
" on already existing cache directory inside"
538+
" non-writable folder."
539+
)
540+
{
541+
// Create temp folder
542+
const auto tmp_dir = fs::temp_directory_path()
543+
/ "mamba-fs-create_cache_dir-2025-11-27-bug";
544+
mamba::on_scope_exit _([&] { fs::remove_all(tmp_dir); });
545+
const auto folder = tmp_dir / "some_folder";
546+
fs::create_directories(folder);
547+
548+
// Create cache folder
549+
auto cache_dir = folder / "cache_dir";
550+
create_cache_dir(cache_dir);
551+
552+
// Remove write permissions on parent folder
553+
const auto perms = fs::perms::owner_read | fs::perms::owner_exec | fs::perms::group_read
554+
| fs::perms::group_exec | fs::perms::others_read
555+
| fs::perms::others_exec;
556+
fs::permissions(folder, perms, fs::perm_options::replace);
557+
558+
// Create cache folder (again!)
559+
// This should not fail
560+
create_cache_dir(cache_dir);
561+
562+
// Reset writing permission
563+
const auto write_perms = fs::perms::owner_all;
564+
fs::permissions(folder, write_perms, fs::perm_options::replace);
565+
}
566+
}
567+
540568
}

0 commit comments

Comments
 (0)