mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 14:55:47 +00:00
Bug 1732343 - Part 4: Use attached handles for Windows FileDescriptor serialization, r=handyman
Differential Revision: https://phabricator.services.mozilla.com/D126566
This commit is contained in:
parent
4bd83c851e
commit
aa3b31b0e4
@ -35,14 +35,6 @@ FileDescriptor::FileDescriptor(PlatformHandleType aHandle)
|
||||
FileDescriptor::FileDescriptor(UniquePlatformHandle&& aHandle)
|
||||
: mHandle(std::move(aHandle)) {}
|
||||
|
||||
FileDescriptor::FileDescriptor(const IPDLPrivate&, PickleType aPickle) {
|
||||
#ifdef XP_WIN
|
||||
mHandle.reset(aPickle);
|
||||
#else
|
||||
mHandle = std::move(aPickle);
|
||||
#endif
|
||||
}
|
||||
|
||||
FileDescriptor::~FileDescriptor() = default;
|
||||
|
||||
FileDescriptor& FileDescriptor::operator=(const FileDescriptor& aOther) {
|
||||
@ -59,33 +51,6 @@ FileDescriptor& FileDescriptor::operator=(FileDescriptor&& aOther) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
FileDescriptor::PickleType FileDescriptor::ShareTo(
|
||||
const FileDescriptor::IPDLPrivate&,
|
||||
FileDescriptor::ProcessId aTargetPid) const {
|
||||
PlatformHandleType newHandle;
|
||||
#ifdef XP_WIN
|
||||
if (IsValid()) {
|
||||
if (mozilla::ipc::DuplicateHandle(mHandle.get(), aTargetPid, &newHandle, 0,
|
||||
DUPLICATE_SAME_ACCESS)) {
|
||||
return newHandle;
|
||||
}
|
||||
NS_WARNING("Failed to duplicate file handle for other process!");
|
||||
}
|
||||
return INVALID_HANDLE_VALUE;
|
||||
#else // XP_WIN
|
||||
if (IsValid()) {
|
||||
newHandle = dup(mHandle.get());
|
||||
if (newHandle >= 0) {
|
||||
return UniquePlatformHandle(newHandle);
|
||||
}
|
||||
NS_WARNING("Failed to duplicate file handle for other process!");
|
||||
}
|
||||
return nullptr;
|
||||
#endif
|
||||
|
||||
MOZ_CRASH("Must not get here!");
|
||||
}
|
||||
|
||||
bool FileDescriptor::IsValid() const { return mHandle != nullptr; }
|
||||
|
||||
FileDescriptor::UniquePlatformHandle FileDescriptor::ClonePlatformHandle()
|
||||
@ -130,30 +95,19 @@ FileDescriptor::UniquePlatformHandle FileDescriptor::Clone(
|
||||
void IPDLParamTraits<FileDescriptor>::Write(IPC::Message* aMsg,
|
||||
IProtocol* aActor,
|
||||
const FileDescriptor& aParam) {
|
||||
#ifdef XP_WIN
|
||||
FileDescriptor::PickleType pfd =
|
||||
aParam.ShareTo(FileDescriptor::IPDLPrivate(), aActor->OtherPid());
|
||||
#else
|
||||
// The pid returned by OtherPID() is only required for Windows to
|
||||
// send file descriptors. For the use case of the fork server,
|
||||
// aActor is always null. Since it is only for the special case of
|
||||
// Windows, here we skip it for other platforms.
|
||||
FileDescriptor::PickleType pfd =
|
||||
aParam.ShareTo(FileDescriptor::IPDLPrivate(), 0);
|
||||
#endif
|
||||
WriteIPDLParam(aMsg, aActor, std::move(pfd));
|
||||
WriteIPDLParam(aMsg, aActor, aParam.ClonePlatformHandle());
|
||||
}
|
||||
|
||||
bool IPDLParamTraits<FileDescriptor>::Read(const IPC::Message* aMsg,
|
||||
PickleIterator* aIter,
|
||||
IProtocol* aActor,
|
||||
FileDescriptor* aResult) {
|
||||
FileDescriptor::PickleType pfd;
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &pfd)) {
|
||||
UniqueFileHandle handle;
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &handle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*aResult = FileDescriptor(FileDescriptor::IPDLPrivate(), std::move(pfd));
|
||||
*aResult = FileDescriptor(std::move(handle));
|
||||
if (!aResult->IsValid()) {
|
||||
printf_stderr("IPDL protocol Error: Received an invalid file descriptor\n");
|
||||
}
|
||||
|
@ -15,17 +15,13 @@ namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
// This class is used by IPDL to share file descriptors across processes. When
|
||||
// sending a FileDescriptor IPDL will first duplicate a platform-specific file
|
||||
// handle type ('PlatformHandleType') into a handle that is valid in the other
|
||||
// process. Then IPDL will convert the duplicated handle into a type suitable
|
||||
// for pickling ('PickleType') and then send that through the IPC pipe. In the
|
||||
// receiving process the pickled data is converted into a platform-specific file
|
||||
// handle and then returned to the receiver.
|
||||
// sending a FileDescriptor, IPDL will transfer a duplicate of the handle into
|
||||
// the remote process.
|
||||
//
|
||||
// To use this class add 'FileDescriptor' as an argument in the IPDL protocol
|
||||
// and then pass a file descriptor from C++ to the Call/Send method. The
|
||||
// Answer/Recv method will receive a FileDescriptor& on which PlatformHandle()
|
||||
// can be called to return the platform file handle.
|
||||
// and then pass a file descriptor from C++ to the Send method. The Recv method
|
||||
// will receive a FileDescriptor& on which PlatformHandle() can be called to
|
||||
// return the platform file handle.
|
||||
class FileDescriptor {
|
||||
public:
|
||||
typedef base::ProcessId ProcessId;
|
||||
@ -33,12 +29,6 @@ class FileDescriptor {
|
||||
using UniquePlatformHandle = mozilla::UniqueFileHandle;
|
||||
using PlatformHandleType = UniquePlatformHandle::ElementType;
|
||||
|
||||
#ifdef XP_WIN
|
||||
typedef PlatformHandleType PickleType;
|
||||
#else
|
||||
typedef UniquePlatformHandle PickleType;
|
||||
#endif
|
||||
|
||||
// This should only ever be created by IPDL.
|
||||
struct IPDLPrivate {};
|
||||
|
||||
@ -56,21 +46,12 @@ class FileDescriptor {
|
||||
|
||||
explicit FileDescriptor(UniquePlatformHandle&& aHandle);
|
||||
|
||||
// This constructor WILL NOT duplicate the handle.
|
||||
// FileDescriptor takes the ownership from IPC message.
|
||||
FileDescriptor(const IPDLPrivate&, PickleType aPickle);
|
||||
|
||||
~FileDescriptor();
|
||||
|
||||
FileDescriptor& operator=(const FileDescriptor& aOther);
|
||||
|
||||
FileDescriptor& operator=(FileDescriptor&& aOther);
|
||||
|
||||
// Performs platform-specific actions to duplicate mHandle in the other
|
||||
// process (e.g. dup() on POSIX, DuplicateHandle() on Windows). Returns a
|
||||
// pickled value that can be passed to the other process via IPC.
|
||||
PickleType ShareTo(const IPDLPrivate&, ProcessId aTargetPid) const;
|
||||
|
||||
// Tests mHandle against a well-known invalid platform-specific file handle
|
||||
// (e.g. -1 on POSIX, INVALID_HANDLE_VALUE on Windows).
|
||||
bool IsValid() const;
|
||||
|
Loading…
Reference in New Issue
Block a user