sapling/eden/fs/win/utils/Pipe.cpp
Xavier Deguillard 53c6c0befd win: rework the Pipe API a bit
Summary:
This makes it similar to the Unix one, which reduces the ifdef a tiny bit.
Ideally I'd want to move the pipe handling into its own class so callers won't
have to care about windows/linux specificities.

Reviewed By: fanzeyi

Differential Revision: D22954056

fbshipit-source-id: c92a25b6abe084a7c7496c0d6e07795779e0abad
2020-08-07 11:05:31 -07:00

106 lines
2.2 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
#include "Pipe.h"
#include <folly/portability/IOVec.h>
#include <folly/portability/Windows.h>
#include <stdio.h>
#include <strsafe.h>
#include <iostream>
#include <memory>
#include <vector>
#include "eden/fs/win/utils/WinError.h"
#include "folly/logging/xlog.h"
namespace facebook {
namespace eden {
Pipe::Pipe() {
auto sec = SECURITY_ATTRIBUTES();
sec.nLength = sizeof(sec);
sec.bInheritHandle = false;
sec.lpSecurityDescriptor = nullptr;
if (!CreatePipe(&readHandle_, &writeHandle_, &sec, 0)) {
throw makeWin32ErrorExplicit(GetLastError(), "Failed to create a pipe");
}
}
Pipe::~Pipe() {
if (readHandle_) {
CloseHandle(readHandle_);
}
if (writeHandle_) {
CloseHandle(writeHandle_);
}
}
ssize_t Pipe::read(HANDLE handle, void* buffer, size_t nbytes) {
ssize_t bytesRead = 0;
while (nbytes > 0) {
DWORD read = 0;
if (!ReadFile(
handle,
((char*)buffer + bytesRead),
folly::to_narrow(nbytes),
&read,
nullptr)) {
return -1;
}
bytesRead += read;
nbytes -= read;
}
return bytesRead;
}
ssize_t Pipe::write(HANDLE handle, void* buffer, size_t nbytes) {
ssize_t bytesWritten = 0;
while (nbytes > 0) {
DWORD written = 0;
if (!WriteFile(
handle,
(void*)((char*)buffer + bytesWritten),
folly::to_narrow(nbytes),
&written,
nullptr)) {
return -1;
}
bytesWritten += written;
nbytes -= written;
}
return bytesWritten;
}
ssize_t Pipe::writevFull(HANDLE handle, iovec* iov, int count) {
ssize_t bytesWritten = 0;
for (int i = 0; i < count; i++) {
auto written = write(handle, iov[i].iov_base, iov[i].iov_len);
if (written < 0) {
return written;
}
bytesWritten += written;
}
return bytesWritten;
}
ssize_t Pipe::read(void* buffer, size_t nbytes) {
return read(readHandle_, buffer, nbytes);
}
ssize_t Pipe::write(void* buffer, size_t nbytes) {
return write(writeHandle_, buffer, nbytes);
}
} // namespace eden
} // namespace facebook