mirror of
https://github.com/NixOS/nix.git
synced 2025-12-22 08:51:08 +01:00
commit
188cb798ad
6 changed files with 76 additions and 62 deletions
|
|
@ -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"); });
|
||||||
|
|
|
||||||
|
|
@ -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',
|
||||||
|
|
|
||||||
61
src/libutil/include/nix/util/socket.hh
Normal file
61
src/libutil/include/nix/util/socket.hh
Normal 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
|
||||||
|
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue