fix: multi-user slicing crash on shared temp dir (#14607)

On Linux every account shares /tmp, but slicing builds temp paths there under
fixed, app-owned names via temporary_dir() (model backups, STEP import,
part-skip). The first user to slice creates and owns those dirs, so the next
user cannot write under them and slicing crashes with "No such file or
directory".

Tag the app temp root with the user id at startup (<temp>/orcaslicer_<uid>)
so every temporary_dir() consumer is isolated at once. The id stays at the
top level of the world-writable system temp so each user's dir is created
directly there; a shared parent dir would be owned by whichever user made it
first. The root is pre-created because STEP import writes into it directly.
Windows keeps the plain temp dir since it is already per-user.

Fixes #10108. Same root cause as #5969.
This commit is contained in:
raistlin7447
2026-07-05 20:18:04 -05:00
committed by GitHub
parent 218ec29d74
commit 2860353b9f
5 changed files with 84 additions and 1 deletions

View File

@@ -1317,7 +1317,13 @@ int CLI::run(int argc, char **argv)
return CLI_INVALID_PARAMS;
}
BOOST_LOG_TRIVIAL(info) << "finished setup params, argc="<< argc << std::endl;
std::string temp_path = wxFileName::GetTempDir().utf8_str().data();
std::string temp_path = per_user_temp_dir(wxFileName::GetTempDir().utf8_str().data(), per_user_temp_id());
// Some consumers write into the temp root directly, so create it up front.
try {
boost::filesystem::create_directories(temp_path);
} catch (const std::exception &ex) {
BOOST_LOG_TRIVIAL(warning) << "failed to create per-user temp dir " << temp_path << ": " << ex.what();
}
set_temporary_dir(temp_path);
m_extra_config.apply(m_config, true);

View File

@@ -300,6 +300,10 @@ std::string header_gcodeviewer_generated();
// getpid platform wrapper
extern unsigned get_current_pid();
// Per-user id for isolating temp dirs; empty on Windows (its temp dir is already per-user).
std::string per_user_temp_id();
// Per-user temp root under `base`; an empty `user_id` returns `base` unchanged.
std::string per_user_temp_dir(const std::string &base, const std::string &user_id);
// BBS: backup & restore
std::string get_process_name(int pid);

View File

@@ -1285,6 +1285,24 @@ unsigned get_current_pid()
#endif
}
std::string per_user_temp_id()
{
#ifdef WIN32
return {};
#else
return std::to_string(static_cast<unsigned long>(::getuid()));
#endif
}
std::string per_user_temp_dir(const std::string &base, const std::string &user_id)
{
if (user_id.empty())
return base;
// Keep the id at the top level so each user's dir sits directly in the world-writable temp
// root; a shared parent dir would be owned by whichever user created it first.
return base + "/orcaslicer_" + user_id;
}
// BBS: backup & restore
std::string get_process_name(int pid)
{