File tree Expand file tree Collapse file tree 3 files changed +39
-3
lines changed Expand file tree Collapse file tree 3 files changed +39
-3
lines changed Original file line number Diff line number Diff line change 1818#include " nix/store/user-lock.hh"
1919#include " nix/store/globals.hh"
2020#include " nix/store/build/derivation-env-desugar.hh"
21+ #include " nix/util/terminal.hh"
2122
2223#include < queue>
2324
@@ -808,8 +809,7 @@ std::optional<Descriptor> DerivationBuilderImpl::startBuild()
808809 if (!builderOut)
809810 throw SysError (" opening pseudoterminal master" );
810811
811- // FIXME: not thread-safe, use ptsname_r
812- std::string slaveName = ptsname (builderOut.get ());
812+ std::string slaveName = getPtsName (builderOut.get ());
813813
814814 if (buildUser) {
815815 if (chmod (slaveName.c_str (), 0600 ))
@@ -923,7 +923,7 @@ void DerivationBuilderImpl::prepareSandbox()
923923
924924void DerivationBuilderImpl::openSlave ()
925925{
926- std::string slaveName = ptsname (builderOut.get ());
926+ std::string slaveName = getPtsName (builderOut.get ());
927927
928928 AutoCloseFD builderOut = open (slaveName.c_str (), O_RDWR | O_NOCTTY);
929929 if (!builderOut)
Original file line number Diff line number Diff line change @@ -36,4 +36,12 @@ void updateWindowSize();
3636 */
3737std::pair<unsigned short , unsigned short > getWindowSize ();
3838
39+ /* *
40+ * Get the slave name of a pseudoterminal in a thread-safe manner.
41+ *
42+ * @param fd The file descriptor of the pseudoterminal master
43+ * @return The slave device name as a string
44+ */
45+ std::string getPtsName (int fd);
46+
3947} // namespace nix
Original file line number Diff line number Diff line change 11#include " nix/util/terminal.hh"
22#include " nix/util/environment-variables.hh"
33#include " nix/util/sync.hh"
4+ #include " nix/util/error.hh"
45
56#ifdef _WIN32
67# include < io.h>
1213#endif
1314#include < unistd.h>
1415#include < widechar_width.h>
16+ #include < mutex>
17+ #include < cstdlib> // for ptsname and ptsname_r
1518
1619namespace {
1720
@@ -176,4 +179,29 @@ std::pair<unsigned short, unsigned short> getWindowSize()
176179 return *windowSize.lock ();
177180}
178181
182+ std::string getPtsName (int fd)
183+ {
184+ #ifdef __APPLE__
185+ static std::mutex ptsnameMutex;
186+ // macOS doesn't have ptsname_r, use mutex-protected ptsname
187+ std::lock_guard<std::mutex> lock (ptsnameMutex);
188+ const char * name = ptsname (fd);
189+ if (!name) {
190+ throw SysError (" getting pseudoterminal slave name" );
191+ }
192+ return name;
193+ #else
194+ // Use thread-safe ptsname_r on platforms that support it
195+ // PTY names are typically short:
196+ // - Linux: /dev/pts/N (where N is usually < 1000)
197+ // - FreeBSD: /dev/pts/N
198+ // 64 bytes is more than sufficient for any Unix PTY name
199+ char buf[64 ];
200+ if (ptsname_r (fd, buf, sizeof (buf)) != 0 ) {
201+ throw SysError (" getting pseudoterminal slave name" );
202+ }
203+ return buf;
204+ #endif
205+ }
206+
179207} // namespace nix
You can’t perform that action at this time.
0 commit comments