1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-12-22 08:51:08 +01:00

Merge pull request #14817 from NixOS/fix-socket-mingw

Windows fixes
This commit is contained in:
John Ericson 2025-12-18 00:30:19 +00:00 committed by GitHub
commit 188cb798ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 76 additions and 62 deletions

View file

@ -91,7 +91,9 @@ TEST_F(FSSourceAccessorTest, works)
{ {
RestoreSink sink(false); RestoreSink sink(false);
sink.dstPath = tmpDir; sink.dstPath = tmpDir;
#ifndef _WIN32
sink.dirFd = openDirectory(tmpDir); sink.dirFd = openDirectory(tmpDir);
#endif
sink.createDirectory(CanonPath("subdir")); sink.createDirectory(CanonPath("subdir"));
sink.createRegularFile(CanonPath("file1"), [](CreateRegularFileSink & crf) { crf("content1"); }); sink.createRegularFile(CanonPath("file1"), [](CreateRegularFileSink & crf) { crf("content1"); });
sink.createRegularFile(CanonPath("subdir/file2"), [](CreateRegularFileSink & crf) { crf("content2"); }); sink.createRegularFile(CanonPath("subdir/file2"), [](CreateRegularFileSink & crf) { crf("content2"); });

View file

@ -65,6 +65,7 @@ headers = files(
'signals.hh', 'signals.hh',
'signature/local-keys.hh', 'signature/local-keys.hh',
'signature/signer.hh', 'signature/signer.hh',
'socket.hh',
'sort.hh', 'sort.hh',
'source-accessor.hh', 'source-accessor.hh',
'source-path.hh', 'source-path.hh',

View file

@ -0,0 +1,61 @@
#pragma once
///@file
#include "nix/util/file-descriptor.hh"
#ifdef _WIN32
# include <winsock2.h>
#endif
namespace nix {
/**
* Often we want to use `Descriptor`, but Windows makes a slightly
* stronger file descriptor vs socket distinction, at least at the level
* of C types.
*/
using Socket =
#ifdef _WIN32
SOCKET
#else
int
#endif
;
#ifdef _WIN32
/**
* Windows gives this a different name
*/
# define SHUT_WR SD_SEND
# define SHUT_RDWR SD_BOTH
#endif
/**
* Convert a `Descriptor` to a `Socket`
*
* This is a no-op except on Windows.
*/
static inline Socket toSocket(Descriptor fd)
{
#ifdef _WIN32
return reinterpret_cast<Socket>(fd);
#else
return fd;
#endif
}
/**
* Convert a `Socket` to a `Descriptor`
*
* This is a no-op except on Windows.
*/
static inline Descriptor fromSocket(Socket fd)
{
#ifdef _WIN32
return reinterpret_cast<Descriptor>(fd);
#else
return fd;
#endif
}
} // namespace nix

View file

@ -3,10 +3,8 @@
#include "nix/util/types.hh" #include "nix/util/types.hh"
#include "nix/util/file-descriptor.hh" #include "nix/util/file-descriptor.hh"
#include "nix/util/socket.hh"
#ifdef _WIN32
# include <winsock2.h>
#endif
#include <unistd.h> #include <unistd.h>
#include <filesystem> #include <filesystem>
@ -23,55 +21,6 @@ AutoCloseFD createUnixDomainSocket();
*/ */
AutoCloseFD createUnixDomainSocket(const Path & path, mode_t mode); AutoCloseFD createUnixDomainSocket(const Path & path, mode_t mode);
/**
* Often we want to use `Descriptor`, but Windows makes a slightly
* stronger file descriptor vs socket distinction, at least at the level
* of C types.
*/
using Socket =
#ifdef _WIN32
SOCKET
#else
int
#endif
;
#ifdef _WIN32
/**
* Windows gives this a different name
*/
# define SHUT_WR SD_SEND
# define SHUT_RDWR SD_BOTH
#endif
/**
* Convert a `Socket` to a `Descriptor`
*
* This is a no-op except on Windows.
*/
static inline Socket toSocket(Descriptor fd)
{
#ifdef _WIN32
return reinterpret_cast<Socket>(fd);
#else
return fd;
#endif
}
/**
* Convert a `Socket` to a `Descriptor`
*
* This is a no-op except on Windows.
*/
static inline Descriptor fromSocket(Socket fd)
{
#ifdef _WIN32
return reinterpret_cast<Descriptor>(fd);
#else
return fd;
#endif
}
/** /**
* Bind a Unix domain socket to a path. * Bind a Unix domain socket to a path.
*/ */

View file

@ -2,6 +2,7 @@
#include "nix/util/file-descriptor.hh" #include "nix/util/file-descriptor.hh"
#include "nix/util/compression.hh" #include "nix/util/compression.hh"
#include "nix/util/signals.hh" #include "nix/util/signals.hh"
#include "nix/util/socket.hh"
#include "nix/util/util.hh" #include "nix/util/util.hh"
#include <cstring> #include <cstring>
@ -12,7 +13,6 @@
#ifdef _WIN32 #ifdef _WIN32
# include <fileapi.h> # include <fileapi.h>
# include <winsock2.h>
# include "nix/util/windows-error.hh" # include "nix/util/windows-error.hh"
#else #else
# include <poll.h> # include <poll.h>
@ -185,20 +185,20 @@ bool FdSource::hasData()
while (true) { while (true) {
fd_set fds; fd_set fds;
FD_ZERO(&fds); FD_ZERO(&fds);
int fd_ = fromDescriptorReadOnly(fd); Socket sock = toSocket(fd);
FD_SET(fd_, &fds); FD_SET(sock, &fds);
struct timeval timeout; struct timeval timeout;
timeout.tv_sec = 0; timeout.tv_sec = 0;
timeout.tv_usec = 0; timeout.tv_usec = 0;
auto n = select(fd_ + 1, &fds, nullptr, nullptr, &timeout); auto n = select(sock + 1, &fds, nullptr, nullptr, &timeout);
if (n < 0) { if (n < 0) {
if (errno == EINTR) if (errno == EINTR)
continue; continue;
throw SysError("polling file descriptor"); throw SysError("polling file descriptor");
} }
return FD_ISSET(fd, &fds); return FD_ISSET(sock, &fds);
} }
} }

View file

@ -437,22 +437,23 @@ static void forwardStdioConnection(RemoteStore & store)
int from = conn->from.fd; int from = conn->from.fd;
int to = conn->to.fd; int to = conn->to.fd;
auto nfds = std::max(from, STDIN_FILENO) + 1; Socket fromSock = toSocket(from), stdinSock = toSocket(getStandardInput());
auto nfds = std::max(fromSock, stdinSock) + 1;
while (true) { while (true) {
fd_set fds; fd_set fds;
FD_ZERO(&fds); FD_ZERO(&fds);
FD_SET(from, &fds); FD_SET(fromSock, &fds);
FD_SET(STDIN_FILENO, &fds); FD_SET(stdinSock, &fds);
if (select(nfds, &fds, nullptr, nullptr, nullptr) == -1) if (select(nfds, &fds, nullptr, nullptr, nullptr) == -1)
throw SysError("waiting for data from client or server"); throw SysError("waiting for data from client or server");
if (FD_ISSET(from, &fds)) { if (FD_ISSET(fromSock, &fds)) {
auto res = splice(from, nullptr, STDOUT_FILENO, nullptr, SSIZE_MAX, SPLICE_F_MOVE); auto res = splice(from, nullptr, STDOUT_FILENO, nullptr, SSIZE_MAX, SPLICE_F_MOVE);
if (res == -1) if (res == -1)
throw SysError("splicing data from daemon socket to stdout"); throw SysError("splicing data from daemon socket to stdout");
else if (res == 0) else if (res == 0)
throw EndOfFile("unexpected EOF from daemon socket"); throw EndOfFile("unexpected EOF from daemon socket");
} }
if (FD_ISSET(STDIN_FILENO, &fds)) { if (FD_ISSET(stdinSock, &fds)) {
auto res = splice(STDIN_FILENO, nullptr, to, nullptr, SSIZE_MAX, SPLICE_F_MOVE); auto res = splice(STDIN_FILENO, nullptr, to, nullptr, SSIZE_MAX, SPLICE_F_MOVE);
if (res == -1) if (res == -1)
throw SysError("splicing data from stdin to daemon socket"); throw SysError("splicing data from stdin to daemon socket");