michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "FileDescriptor.h" michael@0: michael@0: #include "mozilla/Assertions.h" michael@0: #include "nsDebug.h" michael@0: michael@0: #ifdef XP_WIN michael@0: michael@0: #include michael@0: #define INVALID_HANDLE INVALID_HANDLE_VALUE michael@0: michael@0: #else // XP_WIN michael@0: michael@0: #include michael@0: michael@0: #ifndef OS_POSIX michael@0: #define OS_POSIX michael@0: #endif michael@0: michael@0: #include "base/eintr_wrapper.h" michael@0: #define INVALID_HANDLE -1 michael@0: michael@0: #endif // XP_WIN michael@0: michael@0: using mozilla::ipc::FileDescriptor; michael@0: michael@0: FileDescriptor::FileDescriptor() michael@0: : mHandle(INVALID_HANDLE), mHandleCreatedByOtherProcess(false), michael@0: mHandleCreatedByOtherProcessWasUsed(false) michael@0: { } michael@0: michael@0: FileDescriptor::FileDescriptor(PlatformHandleType aHandle) michael@0: : mHandle(INVALID_HANDLE), mHandleCreatedByOtherProcess(false), michael@0: mHandleCreatedByOtherProcessWasUsed(false) michael@0: { michael@0: DuplicateInCurrentProcess(aHandle); michael@0: } michael@0: michael@0: void michael@0: FileDescriptor::DuplicateInCurrentProcess(PlatformHandleType aHandle) michael@0: { michael@0: MOZ_ASSERT_IF(mHandleCreatedByOtherProcess, michael@0: mHandleCreatedByOtherProcessWasUsed); michael@0: michael@0: if (IsValid(aHandle)) { michael@0: PlatformHandleType newHandle; michael@0: #ifdef XP_WIN michael@0: if (DuplicateHandle(GetCurrentProcess(), aHandle, GetCurrentProcess(), michael@0: &newHandle, 0, FALSE, DUPLICATE_SAME_ACCESS)) { michael@0: #else // XP_WIN michael@0: if ((newHandle = dup(aHandle)) != INVALID_HANDLE) { michael@0: #endif michael@0: mHandle = newHandle; michael@0: return; michael@0: } michael@0: NS_WARNING("Failed to duplicate file handle for current process!"); michael@0: } michael@0: michael@0: mHandle = INVALID_HANDLE; michael@0: } michael@0: michael@0: void michael@0: FileDescriptor::CloseCurrentProcessHandle() michael@0: { michael@0: MOZ_ASSERT_IF(mHandleCreatedByOtherProcess, michael@0: mHandleCreatedByOtherProcessWasUsed); michael@0: michael@0: // Don't actually close handles created by another process. michael@0: if (mHandleCreatedByOtherProcess) { michael@0: return; michael@0: } michael@0: michael@0: if (IsValid()) { michael@0: #ifdef XP_WIN michael@0: if (!CloseHandle(mHandle)) { michael@0: NS_WARNING("Failed to close file handle for current process!"); michael@0: } michael@0: #else // XP_WIN michael@0: HANDLE_EINTR(close(mHandle)); michael@0: #endif michael@0: mHandle = INVALID_HANDLE; michael@0: } michael@0: } michael@0: michael@0: FileDescriptor::PickleType michael@0: FileDescriptor::ShareTo(const FileDescriptor::IPDLPrivate&, michael@0: FileDescriptor::ProcessHandle aOtherProcess) const michael@0: { michael@0: PlatformHandleType newHandle; michael@0: #ifdef XP_WIN michael@0: if (IsValid()) { michael@0: if (DuplicateHandle(GetCurrentProcess(), mHandle, aOtherProcess, michael@0: &newHandle, 0, FALSE, DUPLICATE_SAME_ACCESS)) { michael@0: return newHandle; michael@0: } michael@0: NS_WARNING("Failed to duplicate file handle for other process!"); michael@0: } michael@0: return INVALID_HANDLE; michael@0: #else // XP_WIN michael@0: if (IsValid()) { michael@0: newHandle = dup(mHandle); michael@0: if (IsValid(newHandle)) { michael@0: return base::FileDescriptor(newHandle, /* auto_close */ true); michael@0: } michael@0: NS_WARNING("Failed to duplicate file handle for other process!"); michael@0: } michael@0: return base::FileDescriptor(); michael@0: #endif michael@0: michael@0: MOZ_CRASH("Must not get here!"); michael@0: } michael@0: michael@0: // static michael@0: bool michael@0: FileDescriptor::IsValid(PlatformHandleType aHandle) michael@0: { michael@0: return aHandle != INVALID_HANDLE; michael@0: }