OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | |
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 CHROME_COMMON_FILE_DESCRIPTOR_POSIX_H_ | |
6 #define CHROME_COMMON_FILE_DESCRIPTOR_POSIX_H_ | |
7 | |
8 #include <vector> | |
9 | |
10 // ----------------------------------------------------------------------------- | |
11 // A FileDescriptor is a structure for use in IPC messages. It allows one to | |
12 // send descriptors over an IPC channel. | |
13 // | |
14 // In the Windows world, processes can peek and poke the HANDLE table of other | |
15 // processes. On POSIX, in order to transmit descriptors we need to include | |
16 // them in a control-message (a side-channel on the UNIX domain socket). | |
17 // Serialising this type adds descriptors to a vector in the IPC Message, from | |
18 // which the IPC channel can package them up for the kernel. | |
19 // ----------------------------------------------------------------------------- | |
20 struct FileDescriptor { | |
21 FileDescriptor() | |
22 : fd(-1), | |
23 auto_close(false) { } | |
24 | |
25 int fd; | |
26 // If true, close this descriptor after it has been sent. | |
27 bool auto_close; | |
28 }; | |
29 | |
30 // ----------------------------------------------------------------------------- | |
31 // A DescriptorSet is an ordered set of POSIX file descriptors. These are | |
32 // associated with IPC messages so that descriptors can be transmitted over a | |
33 // UNIX domain socket. | |
34 // ----------------------------------------------------------------------------- | |
35 class DescriptorSet { | |
36 public: | |
37 DescriptorSet(); | |
38 ~DescriptorSet(); | |
39 | |
40 // This is the maximum number of descriptors per message. We need to know this | |
41 // because the control message kernel interface has to be given a buffer which | |
42 // is large enough to store all the descriptor numbers. Otherwise the kernel | |
43 // tells us that it truncated the control data and the extra descriptors are | |
44 // lost. | |
45 // | |
46 // In debugging mode, it's a fatal error to try and add more than this number | |
47 // of descriptors to a DescriptorSet. | |
48 enum { | |
49 MAX_DESCRIPTORS_PER_MESSAGE = 4, | |
50 }; | |
51 | |
52 // --------------------------------------------------------------------------- | |
53 // Interfaces for building during message serialisation... | |
54 | |
55 // Add a descriptor to the end of the set | |
56 void Add(int fd); | |
57 // Add a descriptor to the end of the set and automatically close it after | |
58 // transmission. | |
59 void AddAndAutoClose(int fd); | |
60 | |
61 // --------------------------------------------------------------------------- | |
62 | |
63 | |
64 // --------------------------------------------------------------------------- | |
65 // Interfaces for accessing during message deserialisation... | |
66 | |
67 // Return the number of descriptors remaining | |
68 unsigned size() const { return descriptors_.size() - next_descriptor_; } | |
69 // Return true if no unconsumed descriptors remain | |
70 bool empty() const { return descriptors_.size() == next_descriptor_; } | |
71 // Fetch the next descriptor from the beginning of the set. This interface is | |
72 // designed for the deserialising code as it doesn't support close flags. | |
73 // returns: file descriptor, or -1 on error | |
74 int NextDescriptor(); | |
75 | |
76 // --------------------------------------------------------------------------- | |
77 | |
78 | |
79 // --------------------------------------------------------------------------- | |
80 // Interfaces for transmission... | |
81 | |
82 // Fill an array with file descriptors without 'consuming' them. CommitAll | |
83 // must be called after these descriptors have been transmitted. | |
84 // buffer: (output) a buffer of, at least, size() integers. | |
85 void GetDescriptors(int* buffer) const; | |
86 // This must be called after transmitting the descriptors returned by | |
87 // GetDescriptors. It marks all the descriptors as consumed and closes those | |
88 // which are auto-close. | |
89 void CommitAll(); | |
90 | |
91 // --------------------------------------------------------------------------- | |
92 | |
93 | |
94 // --------------------------------------------------------------------------- | |
95 // Interfaces for receiving... | |
96 | |
97 // Set the contents of the set from the given buffer. This set must be empty | |
98 // before calling. The auto-close flag is set on all the descriptors so that | |
99 // unconsumed descriptors are closed on destruction. | |
100 void SetDescriptors(const int* buffer, unsigned count); | |
101 | |
102 // --------------------------------------------------------------------------- | |
103 | |
104 // --------------------------------------------------------------------------- | |
105 // Interfaces for IPC::Message... | |
106 | |
107 // Take all the FileDescriptors from another set. Just like a copy | |
108 // constructor, except that the source is emptied. | |
109 void TakeFrom(DescriptorSet* other); | |
110 | |
111 // --------------------------------------------------------------------------- | |
112 | |
113 private: | |
114 // A vector of descriptors and close flags. If this message is sent, then | |
115 // these descriptors are sent as control data. After sending, any descriptors | |
116 // with a true flag are closed. If this message has been received, then these | |
117 // are the descriptors which were received and all close flags are true. | |
118 std::vector<FileDescriptor> descriptors_; | |
119 // When deserialising the message, the descriptors will be extracted | |
120 // one-by-one. This contains the index of the next unused descriptor. | |
121 unsigned next_descriptor_; | |
122 }; | |
123 | |
124 #endif // CHROME_COMMON_FILE_DESCRIPTOR_POSIX_H_ | |
OLD | NEW |