1 // Copyright 2011 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef IPC_IPC_MESSAGE_ATTACHMENT_SET_H_ 6 #define IPC_IPC_MESSAGE_ATTACHMENT_SET_H_ 7 8 #include <stddef.h> 9 10 #include <vector> 11 12 #include "base/memory/ref_counted.h" 13 #include "build/build_config.h" 14 #include "ipc/ipc_message_support_export.h" 15 16 namespace IPC { 17 18 class MessageAttachment; 19 20 // ----------------------------------------------------------------------------- 21 // A MessageAttachmentSet is an ordered set of MessageAttachment objects 22 // associated with an IPC message. All attachments are wrapped in a mojo handle 23 // if necessary and sent over the mojo message pipe. 24 // 25 // For ChannelNacl under SFI NaCl, only Type::PLATFORM_FILE is supported. In 26 // that case, the FD is sent over socket. 27 // ----------------------------------------------------------------------------- 28 class IPC_MESSAGE_SUPPORT_EXPORT MessageAttachmentSet 29 : public base::RefCountedThreadSafe<MessageAttachmentSet> { 30 public: 31 MessageAttachmentSet(); 32 33 MessageAttachmentSet(const MessageAttachmentSet&) = delete; 34 MessageAttachmentSet& operator=(const MessageAttachmentSet&) = delete; 35 36 // Return the number of attachments 37 unsigned size() const; 38 39 // Return true if no unconsumed descriptors remain empty()40 bool empty() const { return attachments_.empty(); } 41 42 // Returns whether the attachment was successfully added. 43 // |index| is an output variable. On success, it contains the index of the 44 // newly added attachment. 45 bool AddAttachment(scoped_refptr<MessageAttachment> attachment, 46 size_t* index); 47 48 // Similar to the above method, but without output variables. 49 bool AddAttachment(scoped_refptr<MessageAttachment> attachment); 50 51 // Take the nth from the beginning of the vector, Code using this /must/ 52 // access the attachments in order, and must do it at most once. 53 // 54 // This interface is designed for the deserialising code as it doesn't 55 // support close flags. 56 // returns: an attachment, or nullptr on error 57 scoped_refptr<MessageAttachment> GetAttachmentAt(unsigned index); 58 59 // Marks all the descriptors as consumed and closes those which are 60 // auto-close. 61 void CommitAllDescriptors(); 62 63 #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) 64 // This is the maximum number of descriptors per message. We need to know this 65 // because the control message kernel interface has to be given a buffer which 66 // is large enough to store all the descriptor numbers. Otherwise the kernel 67 // tells us that it truncated the control data and the extra descriptors are 68 // lost. 69 // 70 // In debugging mode, it's a fatal error to try and add more than this number 71 // of descriptors to a MessageAttachmentSet. 72 static const size_t kMaxDescriptorsPerMessage = 7; 73 #endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) 74 75 // --------------------------------------------------------------------------- 76 77 private: 78 friend class base::RefCountedThreadSafe<MessageAttachmentSet>; 79 80 ~MessageAttachmentSet(); 81 82 // Return the number of file descriptors 83 unsigned num_descriptors() const; 84 85 std::vector<scoped_refptr<MessageAttachment>> attachments_; 86 87 // This contains the index of the next descriptor which should be consumed. 88 // It's used in a couple of ways. Firstly, at destruction we can check that 89 // all the descriptors have been read (with GetNthDescriptor). Secondly, we 90 // can check that they are read in order. 91 unsigned consumed_descriptor_highwater_; 92 }; 93 94 } // namespace IPC 95 96 #endif // IPC_IPC_MESSAGE_ATTACHMENT_SET_H_ 97