mirror of
https://github.com/NixOS/nix
synced 2025-07-06 05:01:48 +02:00
Merge pull request #10556 from nix-windows/uds-remote-on-windows
Enable the `unix://` store on Windows
This commit is contained in:
commit
1948ec390c
11 changed files with 166 additions and 88 deletions
|
@ -1,24 +1,31 @@
|
|||
#include "file-system.hh"
|
||||
#include "processes.hh"
|
||||
#include "unix-domain-socket.hh"
|
||||
#include "util.hh"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#ifdef _WIN32
|
||||
# include <winsock2.h>
|
||||
# include <afunix.h>
|
||||
#else
|
||||
# include <sys/socket.h>
|
||||
# include <sys/un.h>
|
||||
# include "processes.hh"
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
|
||||
namespace nix {
|
||||
|
||||
AutoCloseFD createUnixDomainSocket()
|
||||
{
|
||||
AutoCloseFD fdSocket = socket(PF_UNIX, SOCK_STREAM
|
||||
AutoCloseFD fdSocket = toDescriptor(socket(PF_UNIX, SOCK_STREAM
|
||||
#ifdef SOCK_CLOEXEC
|
||||
| SOCK_CLOEXEC
|
||||
#endif
|
||||
, 0);
|
||||
, 0));
|
||||
if (!fdSocket)
|
||||
throw SysError("cannot create Unix domain socket");
|
||||
#ifndef _WIN32
|
||||
closeOnExec(fdSocket.get());
|
||||
#endif
|
||||
return fdSocket;
|
||||
}
|
||||
|
||||
|
@ -32,16 +39,15 @@ AutoCloseFD createUnixDomainSocket(const Path & path, mode_t mode)
|
|||
if (chmod(path.c_str(), mode) == -1)
|
||||
throw SysError("changing permissions on '%1%'", path);
|
||||
|
||||
if (listen(fdSocket.get(), 100) == -1)
|
||||
if (listen(toSocket(fdSocket.get()), 100) == -1)
|
||||
throw SysError("cannot listen on socket '%1%'", path);
|
||||
|
||||
return fdSocket;
|
||||
}
|
||||
|
||||
|
||||
static void bindConnectProcHelper(
|
||||
std::string_view operationName, auto && operation,
|
||||
int fd, const std::string & path)
|
||||
Socket fd, const std::string & path)
|
||||
{
|
||||
struct sockaddr_un addr;
|
||||
addr.sun_family = AF_UNIX;
|
||||
|
@ -54,6 +60,9 @@ static void bindConnectProcHelper(
|
|||
auto * psaddr = reinterpret_cast<struct sockaddr *>(&addr);
|
||||
|
||||
if (path.size() + 1 >= sizeof(addr.sun_path)) {
|
||||
#ifdef _WIN32
|
||||
throw Error("cannot %s to socket at '%s': path is too long", operationName, path);
|
||||
#else
|
||||
Pipe pipe;
|
||||
pipe.create();
|
||||
Pid pid = startProcess([&] {
|
||||
|
@ -83,6 +92,7 @@ static void bindConnectProcHelper(
|
|||
errno = *errNo;
|
||||
throw SysError("cannot %s to socket at '%s'", operationName, path);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
memcpy(addr.sun_path, path.c_str(), path.size() + 1);
|
||||
if (operation(fd, psaddr, sizeof(addr)) == -1)
|
||||
|
@ -91,7 +101,7 @@ static void bindConnectProcHelper(
|
|||
}
|
||||
|
||||
|
||||
void bind(int fd, const std::string & path)
|
||||
void bind(Socket fd, const std::string & path)
|
||||
{
|
||||
unlink(path.c_str());
|
||||
|
||||
|
@ -99,7 +109,7 @@ void bind(int fd, const std::string & path)
|
|||
}
|
||||
|
||||
|
||||
void connect(int fd, const std::string & path)
|
||||
void connect(Socket fd, const std::string & path)
|
||||
{
|
||||
bindConnectProcHelper("connect", ::connect, fd, path);
|
||||
}
|
84
src/libutil/unix-domain-socket.hh
Normal file
84
src/libutil/unix-domain-socket.hh
Normal file
|
@ -0,0 +1,84 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "types.hh"
|
||||
#include "file-descriptor.hh"
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <winsock2.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
|
||||
namespace nix {
|
||||
|
||||
/**
|
||||
* Create a Unix domain socket.
|
||||
*/
|
||||
AutoCloseFD createUnixDomainSocket();
|
||||
|
||||
/**
|
||||
* Create a Unix domain socket in listen 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
|
||||
#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.
|
||||
*/
|
||||
void bind(Socket fd, const std::string & path);
|
||||
|
||||
/**
|
||||
* Connect to a Unix domain socket.
|
||||
*/
|
||||
void connect(Socket fd, const std::string & path);
|
||||
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "types.hh"
|
||||
#include "file-descriptor.hh"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
namespace nix {
|
||||
|
||||
/**
|
||||
* Create a Unix domain socket.
|
||||
*/
|
||||
AutoCloseFD createUnixDomainSocket();
|
||||
|
||||
/**
|
||||
* Create a Unix domain socket in listen mode.
|
||||
*/
|
||||
AutoCloseFD createUnixDomainSocket(const Path & path, mode_t mode);
|
||||
|
||||
/**
|
||||
* Bind a Unix domain socket to a path.
|
||||
*/
|
||||
void bind(int fd, const std::string & path);
|
||||
|
||||
/**
|
||||
* Connect to a Unix domain socket.
|
||||
*/
|
||||
void connect(int fd, const std::string & path);
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue