1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_ipc_FileDescriptor_h 8 #define mozilla_ipc_FileDescriptor_h 9 10 #include "base/basictypes.h" 11 #include "base/process.h" 12 #include "mozilla/UniquePtrExtensions.h" 13 14 #ifdef XP_UNIX 15 # include "base/file_descriptor_posix.h" 16 #endif 17 18 namespace mozilla { 19 namespace ipc { 20 21 // This class is used by IPDL to share file descriptors across processes. When 22 // sending a FileDescriptor IPDL will first duplicate a platform-specific file 23 // handle type ('PlatformHandleType') into a handle that is valid in the other 24 // process. Then IPDL will convert the duplicated handle into a type suitable 25 // for pickling ('PickleType') and then send that through the IPC pipe. In the 26 // receiving process the pickled data is converted into a platform-specific file 27 // handle and then returned to the receiver. 28 // 29 // To use this class add 'FileDescriptor' as an argument in the IPDL protocol 30 // and then pass a file descriptor from C++ to the Call/Send method. The 31 // Answer/Recv method will receive a FileDescriptor& on which PlatformHandle() 32 // can be called to return the platform file handle. 33 class FileDescriptor { 34 public: 35 typedef base::ProcessId ProcessId; 36 37 using UniquePlatformHandle = mozilla::UniqueFileHandle; 38 using PlatformHandleType = UniquePlatformHandle::ElementType; 39 40 #ifdef XP_WIN 41 typedef PlatformHandleType PickleType; 42 #else 43 typedef base::FileDescriptor PickleType; 44 #endif 45 46 // This should only ever be created by IPDL. 47 struct IPDLPrivate {}; 48 49 // Represents an invalid handle. 50 FileDescriptor(); 51 52 // Copy constructor will duplicate a new handle. 53 FileDescriptor(const FileDescriptor& aOther); 54 55 FileDescriptor(FileDescriptor&& aOther); 56 57 // This constructor will duplicate a new handle. 58 // The caller still have to close aHandle. 59 explicit FileDescriptor(PlatformHandleType aHandle); 60 61 explicit FileDescriptor(UniquePlatformHandle&& aHandle); 62 63 // This constructor WILL NOT duplicate the handle. 64 // FileDescriptor takes the ownership from IPC message. 65 FileDescriptor(const IPDLPrivate&, const PickleType& aPickle); 66 67 ~FileDescriptor(); 68 69 FileDescriptor& operator=(const FileDescriptor& aOther); 70 71 FileDescriptor& operator=(FileDescriptor&& aOther); 72 73 // Performs platform-specific actions to duplicate mHandle in the other 74 // process (e.g. dup() on POSIX, DuplicateHandle() on Windows). Returns a 75 // pickled value that can be passed to the other process via IPC. 76 PickleType ShareTo(const IPDLPrivate&, ProcessId aTargetPid) const; 77 78 // Tests mHandle against a well-known invalid platform-specific file handle 79 // (e.g. -1 on POSIX, INVALID_HANDLE_VALUE on Windows). 80 bool IsValid() const; 81 82 // Returns a duplicated handle, it is caller's responsibility to close the 83 // handle. 84 UniquePlatformHandle ClonePlatformHandle() const; 85 86 // Extracts the underlying handle and makes this object an invalid handle. 87 // (Compare UniquePtr::release.) 88 UniquePlatformHandle TakePlatformHandle(); 89 90 // Only used in nsTArray. 91 bool operator==(const FileDescriptor& aOther) const; 92 93 private: 94 static UniqueFileHandle Clone(PlatformHandleType aHandle); 95 96 UniquePlatformHandle mHandle; 97 }; 98 99 } // namespace ipc 100 } // namespace mozilla 101 102 #endif // mozilla_ipc_FileDescriptor_h 103