1 // Copyright 2017 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 #include "mojo/public/cpp/system/message_pipe.h"
6
7 #include "base/numerics/safe_math.h"
8
9 namespace mojo {
10
WriteMessageRaw(MessagePipeHandle message_pipe,const void * bytes,size_t num_bytes,const MojoHandle * handles,size_t num_handles,MojoWriteMessageFlags flags)11 MojoResult WriteMessageRaw(MessagePipeHandle message_pipe,
12 const void* bytes,
13 size_t num_bytes,
14 const MojoHandle* handles,
15 size_t num_handles,
16 MojoWriteMessageFlags flags) {
17 ScopedMessageHandle message_handle;
18 MojoResult rv = CreateMessage(&message_handle);
19 DCHECK_EQ(MOJO_RESULT_OK, rv);
20
21 MojoAppendMessageDataOptions append_options;
22 append_options.struct_size = sizeof(append_options);
23 append_options.flags = MOJO_APPEND_MESSAGE_DATA_FLAG_COMMIT_SIZE;
24 void* buffer;
25 uint32_t buffer_size;
26 rv = MojoAppendMessageData(message_handle->value(),
27 base::checked_cast<uint32_t>(num_bytes), handles,
28 base::checked_cast<uint32_t>(num_handles),
29 &append_options, &buffer, &buffer_size);
30 if (rv != MOJO_RESULT_OK)
31 return MOJO_RESULT_ABORTED;
32
33 DCHECK(buffer);
34 DCHECK_GE(buffer_size, base::checked_cast<uint32_t>(num_bytes));
35 memcpy(buffer, bytes, num_bytes);
36
37 MojoWriteMessageOptions write_options;
38 write_options.struct_size = sizeof(write_options);
39 write_options.flags = flags;
40 return MojoWriteMessage(message_pipe.value(),
41 message_handle.release().value(), &write_options);
42 }
43
ReadMessageRaw(MessagePipeHandle message_pipe,std::vector<uint8_t> * payload,std::vector<ScopedHandle> * handles,MojoReadMessageFlags flags)44 MojoResult ReadMessageRaw(MessagePipeHandle message_pipe,
45 std::vector<uint8_t>* payload,
46 std::vector<ScopedHandle>* handles,
47 MojoReadMessageFlags flags) {
48 ScopedMessageHandle message_handle;
49 MojoResult rv = ReadMessageNew(message_pipe, &message_handle, flags);
50 if (rv != MOJO_RESULT_OK)
51 return rv;
52
53 rv = MojoSerializeMessage(message_handle->value(), nullptr);
54 if (rv != MOJO_RESULT_OK && rv != MOJO_RESULT_FAILED_PRECONDITION)
55 return MOJO_RESULT_ABORTED;
56
57 void* buffer = nullptr;
58 uint32_t num_bytes = 0;
59 uint32_t num_handles = 0;
60 rv = MojoGetMessageData(message_handle->value(), nullptr, &buffer, &num_bytes,
61 nullptr, &num_handles);
62 if (rv == MOJO_RESULT_RESOURCE_EXHAUSTED) {
63 DCHECK(handles);
64 handles->resize(num_handles);
65 rv = MojoGetMessageData(
66 message_handle->value(), nullptr, &buffer, &num_bytes,
67 reinterpret_cast<MojoHandle*>(handles->data()), &num_handles);
68 }
69
70 if (num_bytes) {
71 DCHECK(buffer);
72 uint8_t* payload_data = reinterpret_cast<uint8_t*>(buffer);
73 payload->resize(num_bytes);
74 std::copy(payload_data, payload_data + num_bytes, payload->begin());
75 } else if (payload) {
76 payload->clear();
77 }
78
79 if (handles && !num_handles)
80 handles->clear();
81
82 if (rv != MOJO_RESULT_OK)
83 return MOJO_RESULT_ABORTED;
84
85 return MOJO_RESULT_OK;
86 }
87
88 } // namespace mojo
89