forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathipc_message_attachment_set.h
138 lines (108 loc) · 5.5 KB
/
ipc_message_attachment_set.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IPC_IPC_MESSAGE_ATTACHMENT_SET_H_
#define IPC_IPC_MESSAGE_ATTACHMENT_SET_H_
#include <vector>
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_vector.h"
#include "ipc/ipc_export.h"
#if defined(OS_POSIX)
#include "base/files/file.h"
#endif
namespace IPC {
class MessageAttachment;
// -----------------------------------------------------------------------------
// A MessageAttachmentSet is an ordered set of POSIX file descriptors. These are
// associated with IPC messages so that descriptors can be transmitted over a
// UNIX domain socket.
// -----------------------------------------------------------------------------
class IPC_EXPORT MessageAttachmentSet
: public base::RefCountedThreadSafe<MessageAttachmentSet> {
public:
MessageAttachmentSet();
// Return the number of attachments
unsigned size() const;
// Return the number of file descriptors
unsigned num_descriptors() const;
// Return true if no unconsumed descriptors remain
bool empty() const { return 0 == size(); }
void AddAttachment(scoped_refptr<MessageAttachment> attachment);
scoped_refptr<MessageAttachment> GetAttachmentAt(unsigned index);
#if defined(OS_POSIX)
// This is the maximum number of descriptors per message. We need to know this
// because the control message kernel interface has to be given a buffer which
// is large enough to store all the descriptor numbers. Otherwise the kernel
// tells us that it truncated the control data and the extra descriptors are
// lost.
//
// In debugging mode, it's a fatal error to try and add more than this number
// of descriptors to a MessageAttachmentSet.
static const size_t kMaxDescriptorsPerMessage = 7;
// ---------------------------------------------------------------------------
// Interfaces for building during message serialisation...
// Add a descriptor to the end of the set. Returns false iff the set is full.
bool AddToBorrow(base::PlatformFile fd);
// Add a descriptor to the end of the set and automatically close it after
// transmission. Returns false iff the set is full.
bool AddToOwn(base::ScopedFD fd);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// Interfaces for accessing during message deserialisation...
// Take the nth descriptor from the beginning of the set,
// transferring the ownership of the descriptor taken. Code using this
// /must/ access the descriptors in order, and must do it at most once.
//
// This interface is designed for the deserialising code as it doesn't
// support close flags.
// returns: file descriptor, or -1 on error
base::PlatformFile TakeDescriptorAt(unsigned n);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// Interfaces for transmission...
// Fill an array with file descriptors without 'consuming' them. CommitAll
// must be called after these descriptors have been transmitted.
// buffer: (output) a buffer of, at least, size() integers.
void PeekDescriptors(base::PlatformFile* buffer) const;
// This must be called after transmitting the descriptors returned by
// PeekDescriptors. It marks all the descriptors as consumed and closes those
// which are auto-close.
void CommitAll();
// Returns true if any contained file descriptors appear to be handles to a
// directory.
bool ContainsDirectoryDescriptor() const;
// Fetch all filedescriptors with the "auto close" property.
// Used instead of CommitAll() when closing must be handled manually.
void ReleaseFDsToClose(std::vector<base::PlatformFile>* fds);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// Interfaces for receiving...
// Set the contents of the set from the given buffer. This set must be empty
// before calling. The auto-close flag is set on all the descriptors so that
// unconsumed descriptors are closed on destruction.
void AddDescriptorsToOwn(const base::PlatformFile* buffer, unsigned count);
#endif // OS_POSIX
// ---------------------------------------------------------------------------
private:
friend class base::RefCountedThreadSafe<MessageAttachmentSet>;
~MessageAttachmentSet();
// A vector of attachments of the message, which might be |PlatformFile| or
// |MessagePipe|.
std::vector<scoped_refptr<MessageAttachment>> attachments_;
#if defined(OS_POSIX)
// A vector of owning descriptors. If this message is sent, then file
// descriptors are sent as control data. After sending, any owning descriptors
// are closed. If this message has been received then all received
// descriptors are owned by this message.
ScopedVector<base::ScopedFD> owned_descriptors_;
#endif
// This contains the index of the next descriptor which should be consumed.
// It's used in a couple of ways. Firstly, at destruction we can check that
// all the descriptors have been read (with GetNthDescriptor). Secondly, we
// can check that they are read in order.
mutable unsigned consumed_descriptor_highwater_;
DISALLOW_COPY_AND_ASSIGN(MessageAttachmentSet);
};
} // namespace IPC
#endif // IPC_IPC_MESSAGE_ATTACHMENT_SET_H_