mirror of
https://github.com/NixOS/nix.git
synced 2025-11-09 12:06:01 +01:00
Merge pull request #14110 from Mic92/ptsname
Fix thread-safety issue with ptsname() usage
This commit is contained in:
commit
b6f4788a8f
3 changed files with 39 additions and 3 deletions
|
|
@ -18,6 +18,7 @@
|
||||||
#include "nix/store/user-lock.hh"
|
#include "nix/store/user-lock.hh"
|
||||||
#include "nix/store/globals.hh"
|
#include "nix/store/globals.hh"
|
||||||
#include "nix/store/build/derivation-env-desugar.hh"
|
#include "nix/store/build/derivation-env-desugar.hh"
|
||||||
|
#include "nix/util/terminal.hh"
|
||||||
|
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
|
|
@ -808,8 +809,7 @@ std::optional<Descriptor> DerivationBuilderImpl::startBuild()
|
||||||
if (!builderOut)
|
if (!builderOut)
|
||||||
throw SysError("opening pseudoterminal master");
|
throw SysError("opening pseudoterminal master");
|
||||||
|
|
||||||
// FIXME: not thread-safe, use ptsname_r
|
std::string slaveName = getPtsName(builderOut.get());
|
||||||
std::string slaveName = ptsname(builderOut.get());
|
|
||||||
|
|
||||||
if (buildUser) {
|
if (buildUser) {
|
||||||
if (chmod(slaveName.c_str(), 0600))
|
if (chmod(slaveName.c_str(), 0600))
|
||||||
|
|
@ -923,7 +923,7 @@ void DerivationBuilderImpl::prepareSandbox()
|
||||||
|
|
||||||
void DerivationBuilderImpl::openSlave()
|
void DerivationBuilderImpl::openSlave()
|
||||||
{
|
{
|
||||||
std::string slaveName = ptsname(builderOut.get());
|
std::string slaveName = getPtsName(builderOut.get());
|
||||||
|
|
||||||
AutoCloseFD builderOut = open(slaveName.c_str(), O_RDWR | O_NOCTTY);
|
AutoCloseFD builderOut = open(slaveName.c_str(), O_RDWR | O_NOCTTY);
|
||||||
if (!builderOut)
|
if (!builderOut)
|
||||||
|
|
|
||||||
|
|
@ -36,4 +36,12 @@ void updateWindowSize();
|
||||||
*/
|
*/
|
||||||
std::pair<unsigned short, unsigned short> getWindowSize();
|
std::pair<unsigned short, unsigned short> getWindowSize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the slave name of a pseudoterminal in a thread-safe manner.
|
||||||
|
*
|
||||||
|
* @param fd The file descriptor of the pseudoterminal master
|
||||||
|
* @return The slave device name as a string
|
||||||
|
*/
|
||||||
|
std::string getPtsName(int fd);
|
||||||
|
|
||||||
} // namespace nix
|
} // namespace nix
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "nix/util/terminal.hh"
|
#include "nix/util/terminal.hh"
|
||||||
#include "nix/util/environment-variables.hh"
|
#include "nix/util/environment-variables.hh"
|
||||||
#include "nix/util/sync.hh"
|
#include "nix/util/sync.hh"
|
||||||
|
#include "nix/util/error.hh"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# include <io.h>
|
# include <io.h>
|
||||||
|
|
@ -12,6 +13,8 @@
|
||||||
#endif
|
#endif
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <widechar_width.h>
|
#include <widechar_width.h>
|
||||||
|
#include <mutex>
|
||||||
|
#include <cstdlib> // for ptsname and ptsname_r
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|
@ -176,4 +179,29 @@ std::pair<unsigned short, unsigned short> getWindowSize()
|
||||||
return *windowSize.lock();
|
return *windowSize.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string getPtsName(int fd)
|
||||||
|
{
|
||||||
|
#ifdef __APPLE__
|
||||||
|
static std::mutex ptsnameMutex;
|
||||||
|
// macOS doesn't have ptsname_r, use mutex-protected ptsname
|
||||||
|
std::lock_guard<std::mutex> lock(ptsnameMutex);
|
||||||
|
const char * name = ptsname(fd);
|
||||||
|
if (!name) {
|
||||||
|
throw SysError("getting pseudoterminal slave name");
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
#else
|
||||||
|
// Use thread-safe ptsname_r on platforms that support it
|
||||||
|
// PTY names are typically short:
|
||||||
|
// - Linux: /dev/pts/N (where N is usually < 1000)
|
||||||
|
// - FreeBSD: /dev/pts/N
|
||||||
|
// 64 bytes is more than sufficient for any Unix PTY name
|
||||||
|
char buf[64];
|
||||||
|
if (ptsname_r(fd, buf, sizeof(buf)) != 0) {
|
||||||
|
throw SysError("getting pseudoterminal slave name");
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace nix
|
} // namespace nix
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue