Flutter Engine
The Flutter Engine
socket.cc
Go to the documentation of this file.
1// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "bin/socket.h"
6
7#include "bin/dartutils.h"
8#include "bin/eventhandler.h"
9#include "bin/file.h"
10#include "bin/io_buffer.h"
11#include "bin/isolate_data.h"
12#include "bin/lockers.h"
13#include "bin/process.h"
14#include "bin/thread.h"
16#include "bin/utils.h"
17
18#include "include/dart_api.h"
19
20#include "platform/globals.h"
21#include "platform/utils.h"
22
23namespace dart {
24namespace bin {
25
26static constexpr int kSocketIdNativeField = 0;
27
29
30bool Socket::short_socket_read_ = false;
31bool Socket::short_socket_write_ = false;
32
36}
37
40}
41
45}
46
47ListeningSocketRegistry::OSSocket* ListeningSocketRegistry::LookupByPort(
48 intptr_t port) {
49 SimpleHashMap::Entry* entry = sockets_by_port_.Lookup(
50 GetHashmapKeyFromIntptr(port), GetHashmapHashFromIntptr(port), false);
51 if (entry == nullptr) {
52 return nullptr;
53 }
54 return reinterpret_cast<OSSocket*>(entry->value);
55}
56
57void ListeningSocketRegistry::InsertByPort(intptr_t port, OSSocket* socket) {
58 SimpleHashMap::Entry* entry = sockets_by_port_.Lookup(
59 GetHashmapKeyFromIntptr(port), GetHashmapHashFromIntptr(port), true);
60 ASSERT(entry != nullptr);
61 entry->value = reinterpret_cast<void*>(socket);
62}
63
64void ListeningSocketRegistry::RemoveByPort(intptr_t port) {
65 sockets_by_port_.Remove(GetHashmapKeyFromIntptr(port),
66 GetHashmapHashFromIntptr(port));
67}
68
69ListeningSocketRegistry::OSSocket* ListeningSocketRegistry::LookupByFd(
70 Socket* fd) {
71 SimpleHashMap::Entry* entry = sockets_by_fd_.Lookup(
72 GetHashmapKeyFromIntptr(reinterpret_cast<intptr_t>(fd)),
73 GetHashmapHashFromIntptr(reinterpret_cast<intptr_t>(fd)), false);
74 if (entry == nullptr) {
75 return nullptr;
76 }
77 return reinterpret_cast<OSSocket*>(entry->value);
78}
79
80void ListeningSocketRegistry::InsertByFd(Socket* fd, OSSocket* socket) {
81 SimpleHashMap::Entry* entry = sockets_by_fd_.Lookup(
82 GetHashmapKeyFromIntptr(reinterpret_cast<intptr_t>(fd)),
83 GetHashmapHashFromIntptr(reinterpret_cast<intptr_t>(fd)), true);
84 ASSERT(entry != nullptr);
85 entry->value = reinterpret_cast<void*>(socket);
86}
87
88void ListeningSocketRegistry::RemoveByFd(Socket* fd) {
89 sockets_by_fd_.Remove(
90 GetHashmapKeyFromIntptr(reinterpret_cast<intptr_t>(fd)),
91 GetHashmapHashFromIntptr(reinterpret_cast<intptr_t>(fd)));
92}
93
96 intptr_t backlog,
97 bool v6_only,
98 bool shared) {
99 MutexLocker ml(&mutex_);
100
101 OSSocket* first_os_socket = nullptr;
103 if (port > 0) {
104 first_os_socket = LookupByPort(port);
105 if (first_os_socket != nullptr) {
106 // There is already a socket listening on this port. We need to ensure
107 // that if there is one also listening on the same address, it was created
108 // with `shared = true`, ...
109 OSSocket* os_socket = first_os_socket;
110 OSSocket* os_socket_same_addr = FindOSSocketWithAddress(os_socket, addr);
111
112 if (os_socket_same_addr != nullptr) {
113 if (!os_socket_same_addr->shared || !shared) {
114 OSError os_error(-1,
115 "The shared flag to bind() needs to be `true` if "
116 "binding multiple times on the same (address, port) "
117 "combination.",
119 return DartUtils::NewDartOSError(&os_error);
120 }
121 if (os_socket_same_addr->v6_only != v6_only) {
122 OSError os_error(-1,
123 "The v6Only flag to bind() needs to be the same if "
124 "binding multiple times on the same (address, port) "
125 "combination.",
127 return DartUtils::NewDartOSError(&os_error);
128 }
129
130 // This socket creation is the exact same as the one which originally
131 // created the socket. Feed same fd and store it into native field
132 // of dart socket_object. Sockets here will share same fd but contain a
133 // different port() through EventHandler_SendData.
134 Socket* socketfd = new Socket(os_socket_same_addr->fd);
135 os_socket_same_addr->ref_count++;
136 // We set as a side-effect the file descriptor on the dart
137 // socket_object.
138 Socket::ReuseSocketIdNativeField(socket_object, socketfd,
140 InsertByFd(socketfd, os_socket_same_addr);
141 return Dart_True();
142 }
143 }
144 }
145
146 // There is no socket listening on that (address, port), so we create new one.
147 intptr_t fd = ServerSocket::CreateBindListen(addr, backlog, v6_only);
148 if (fd == -5) {
149 OSError os_error(-1, "Invalid host", OSError::kUnknown);
150 return DartUtils::NewDartOSError(&os_error);
151 }
152 if (fd < 0) {
155 }
156 if (!ServerSocket::StartAccept(fd)) {
157 OSError os_error(-1, "Failed to start accept", OSError::kUnknown);
158 return DartUtils::NewDartOSError(&os_error);
159 }
160 intptr_t allocated_port = SocketBase::GetPort(fd);
161 ASSERT(allocated_port > 0);
162
163 if (allocated_port != port) {
164 // There are two cases to consider:
165 //
166 // a) The user requested (address, port) where port != 0 which means
167 // we re-use an existing socket if available (and it is shared) or we
168 // create a new one. The new socket is guaranteed to have that
169 // selected port.
170 //
171 // b) The user requested (address, 0). This will make us *always* create a
172 // new socket. The OS will assign it a new `allocated_port` and we will
173 // insert into our data structures. *BUT* There might already be an
174 // existing (address2, `allocated_port`) where address != address2. So
175 // we need to do another `LookupByPort(allocated_port)` and link them
176 // via `OSSocket->next`.
177 ASSERT(port == 0);
178 first_os_socket = LookupByPort(allocated_port);
179 }
180
181 Socket* socketfd = new Socket(fd);
182 OSSocket* os_socket =
183 new OSSocket(addr, allocated_port, v6_only, shared, socketfd, nullptr);
184 os_socket->ref_count = 1;
185 os_socket->next = first_os_socket;
186
187 InsertByPort(allocated_port, os_socket);
188 InsertByFd(socketfd, os_socket);
189
190 // We set as a side-effect the port on the dart socket_object.
191 Socket::ReuseSocketIdNativeField(socket_object, socketfd,
193
194 return Dart_True();
195}
196
198 Dart_Handle socket_object,
199 Namespace* namespc,
200 const char* path,
201 intptr_t backlog,
202 bool shared) {
203 MutexLocker ml(&mutex_);
204
208 if (!Dart_IsNull(result)) {
209 return result;
210 }
211
212#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
213 // Abstract unix domain socket doesn't exist in file system.
214 if (File::Exists(namespc, addr.un.sun_path) && path[0] != '@') {
215#else
216 if (File::Exists(namespc, addr.un.sun_path)) {
217#endif // defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
218 if (unix_domain_sockets_ != nullptr) {
219 // If there is a socket listening on this file. Ensure
220 // that it was created with `shared` mode and current `shared`
221 // is also true.
222 OSSocket* os_socket = unix_domain_sockets_;
223 OSSocket* os_socket_same_addr =
224 FindOSSocketWithPath(os_socket, namespc, addr.un.sun_path);
225 if (os_socket_same_addr != nullptr) {
226 if (!os_socket_same_addr->shared || !shared) {
227 OSError os_error(-1,
228 "The shared flag to bind() needs to be `true` if "
229 "binding multiple times on the same path.",
231 return DartUtils::NewDartOSError(&os_error);
232 }
233
234 // This socket creation is the exact same as the one which originally
235 // created the socket. Feed the same fd and store it into the native
236 // field of dart socket_object. Sockets here will share same fd but
237 // contain a different port() through EventHandler_SendData.
238 Socket* socketfd = new Socket(os_socket_same_addr->fd);
239 os_socket_same_addr->ref_count++;
240 // We set as a side-effect the file descriptor on the dart
241 // socket_object.
242 Socket::ReuseSocketIdNativeField(socket_object, socketfd,
244 InsertByFd(socketfd, os_socket_same_addr);
245 return Dart_True();
246 }
247 }
248 // Unix domain socket by default doesn't allow binding to an existing file.
249 // An error (EADDRINUSE) will be returned back. However, hanging is noticed
250 // on Android so we throw an exception for all platforms.
251 OSError os_error(-1, "File exists with given unix domain address",
253 return DartUtils::NewDartOSError(&os_error);
254 }
255
256 // There is no socket listening on that path, so we create new one.
257 intptr_t fd = ServerSocket::CreateUnixDomainBindListen(addr, backlog);
258
259 if (fd < 0) {
261 }
262
263 Socket* socketfd = new Socket(fd);
264 OSSocket* os_socket =
265 new OSSocket(addr, -1, false, shared, socketfd, namespc);
266 os_socket->ref_count = 1;
267 os_socket->next = unix_domain_sockets_;
268 unix_domain_sockets_ = os_socket;
269 InsertByFd(socketfd, os_socket);
270
271 Socket::ReuseSocketIdNativeField(socket_object, socketfd,
273
274 return Dart_True();
275}
276
277bool ListeningSocketRegistry::CloseOneSafe(OSSocket* os_socket,
278 Socket* socket) {
279 ASSERT(!mutex_.TryLock());
280 ASSERT(os_socket != nullptr);
281 ASSERT(os_socket->ref_count > 0);
282 os_socket->ref_count--;
283 RemoveByFd(socket);
284 if (os_socket->ref_count > 0) {
285 return false;
286 }
287 // Unlink the socket file, if os_socket contains unix domain sockets.
288 if (os_socket->address.addr.sa_family == AF_UNIX) {
289#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
290 // If the socket is abstract, which has a path starting with a null byte,
291 // unlink() is not necessary because the file doesn't exist.
292 if (os_socket->address.un.sun_path[0] != '\0') {
293 Utils::Unlink(os_socket->address.un.sun_path);
294 }
295#else
296 Utils::Unlink(os_socket->address.un.sun_path);
297#endif // defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
298 // Remove os_socket from unix_domain_sockets_ list.
299 OSSocket* prev = nullptr;
300 OSSocket* current = unix_domain_sockets_;
301 while (current != nullptr) {
302 if (current == os_socket) {
303 if (prev == nullptr) {
304 unix_domain_sockets_ = unix_domain_sockets_->next;
305 } else {
306 prev->next = current->next;
307 }
308 break;
309 }
310 prev = current;
311 current = current->next;
312 }
313 delete os_socket;
314 return true;
315 }
316 OSSocket* prev = nullptr;
317 OSSocket* current = LookupByPort(os_socket->port);
318 while (current != os_socket) {
319 ASSERT(current != nullptr);
320 prev = current;
321 current = current->next;
322 }
323
324 if ((prev == nullptr) && (current->next == nullptr)) {
325 // Remove last element from the list.
326 RemoveByPort(os_socket->port);
327 } else if (prev == nullptr) {
328 // Remove first element of the list.
329 InsertByPort(os_socket->port, current->next);
330 } else {
331 // Remove element from the list which is not the first one.
332 prev->next = os_socket->next;
333 }
334
335 ASSERT(os_socket->ref_count == 0);
336 delete os_socket;
337 return true;
338}
339
340void ListeningSocketRegistry::CloseAllSafe() {
341 MutexLocker ml(&mutex_);
342 for (SimpleHashMap::Entry* cursor = sockets_by_fd_.Start(); cursor != nullptr;
343 cursor = sockets_by_fd_.Next(cursor)) {
344 OSSocket* os_socket = reinterpret_cast<OSSocket*>(cursor->value);
345 ASSERT(os_socket != nullptr);
346 delete os_socket;
347 }
348}
349
351 ASSERT(!mutex_.TryLock());
352 OSSocket* os_socket = LookupByFd(socketfd);
353 if (os_socket != nullptr) {
354 return CloseOneSafe(os_socket, socketfd);
355 } else {
356 // A finalizer may direct the event handler to close a listening socket
357 // that it has never seen before. In this case, we return true to direct
358 // the eventhandler to clean up the socket.
359 return true;
360 }
361}
362
367 int64_t port = DartUtils::GetInt64ValueCheckRange(port_arg, 0, 65535);
368 SocketAddress::SetAddrPort(&addr, static_cast<intptr_t>(port));
369 if (addr.addr.sa_family == AF_INET6) {
370 Dart_Handle scope_id_arg = Dart_GetNativeArgument(args, 3);
371 int64_t scope_id =
372 DartUtils::GetInt64ValueCheckRange(scope_id_arg, 0, 65535);
374 }
375 intptr_t socket = Socket::CreateConnect(addr);
377 if (socket >= 0) {
381 } else {
383 }
384}
385
386// This function will abort if sourceAddr is a Unix domain socket.
387// The family ("sa_family") of the socket address is inferred from the length
388// of the address. Unix domain sockets addresses are the bytes of their file
389// system path so they have variable length. They cannot, therefore, be
390// differentiated from other address types in this function.
395 int64_t port = DartUtils::GetInt64ValueCheckRange(port_arg, 0, 65535);
396 SocketAddress::SetAddrPort(&addr, static_cast<intptr_t>(port));
397 RawAddr sourceAddr;
399 Dart_Handle source_port_arg = Dart_GetNativeArgument(args, 4);
400 int64_t source_port =
401 DartUtils::GetInt64ValueCheckRange(source_port_arg, 0, 65535);
402 SocketAddress::SetAddrPort(&sourceAddr, static_cast<intptr_t>(source_port));
403
404 if (addr.addr.sa_family == AF_INET6) {
405 Dart_Handle scope_id_arg = Dart_GetNativeArgument(args, 5);
406 int64_t scope_id =
407 DartUtils::GetInt64ValueCheckRange(scope_id_arg, 0, 65535);
409 }
410 intptr_t socket = Socket::CreateBindConnect(addr, sourceAddr);
412 if (socket >= 0) {
416 } else {
418 }
419}
420
423#if defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
424 OSError os_error(
425 -1, "Unix domain sockets are not available on this operating system.",
428#else
431 if (Dart_IsNull(address)) {
433 "expect address to be of type String"));
434 }
437 &addr);
438 if (!Dart_IsNull(result)) {
440 }
441
442 RawAddr sourceAddr;
443 address = Dart_GetNativeArgument(args, 2);
444 if (Dart_IsNull(address)) {
445 return Dart_SetReturnValue(
446 args,
447 DartUtils::NewDartArgumentError("expect address to be of type String"));
448 }
451 &sourceAddr);
452 if (!Dart_IsNull(result)) {
454 }
455
456 intptr_t socket = Socket::CreateUnixDomainBindConnect(addr, sourceAddr);
457 if (socket >= 0) {
461 } else {
463 }
464#endif // defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
465}
466
468#if defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
469 OSError os_error(
470 -1, "Unix domain sockets are not available on this operating system.",
473#else
476 if (Dart_IsNull(address)) {
477 return Dart_SetReturnValue(
478 args,
479 DartUtils::NewDartArgumentError("expect address to be of type String"));
480 }
483 &addr);
484 if (!Dart_IsNull(result)) {
486 }
487 intptr_t socket = Socket::CreateUnixDomainConnect(addr);
488 if (socket >= 0) {
492 } else {
494 }
495#endif // defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
496}
497
502 int64_t port = DartUtils::GetInt64ValueCheckRange(port_arg, 0, 65535);
507 intptr_t socket =
508 Socket::CreateBindDatagram(addr, reuse_addr, reuse_port, ttl);
509 if (socket >= 0) {
513 } else {
516 }
517}
518
520 Socket* socket =
522 intptr_t available = SocketBase::Available(socket->fd());
523 if (available >= 0) {
525 } else {
526 // Available failed. Mark socket as having data, to trigger a future read
527 // event where the actual error can be reported.
529 }
530}
531
533 Socket* socket =
535 int64_t length = 0;
537 (length >= 0)) {
539 length = (length + 1) / 2;
540 }
541 uint8_t* buffer = nullptr;
543 if (Dart_IsNull(result)) {
545 }
546 if (Dart_IsError(result)) {
548 }
549 ASSERT(buffer != nullptr);
550 intptr_t bytes_read =
552 if (bytes_read == length) {
554 } else if (bytes_read > 0) {
555 uint8_t* new_buffer = nullptr;
556 Dart_Handle new_result = IOBuffer::Allocate(bytes_read, &new_buffer);
557 if (Dart_IsNull(new_result)) {
559 }
560 if (Dart_IsError(new_result)) {
561 Dart_PropagateError(new_result);
562 }
563 ASSERT(new_buffer != nullptr);
564 memmove(new_buffer, buffer, bytes_read);
565 Dart_SetReturnValue(args, new_result);
566 } else if (bytes_read == 0) {
567 // On MacOS when reading from a tty Ctrl-D will result in reading one
568 // less byte then reported as available.
570 } else {
571 ASSERT(bytes_read == -1);
573 }
574 } else {
575 Dart_Handle exception;
576 {
577 // Make sure OSError destructor is called.
578 OSError os_error(-1, "Invalid argument", OSError::kUnknown);
579 exception = DartUtils::NewDartOSError(&os_error);
580 }
581 Dart_ThrowException(exception);
582 }
583}
584
586 // TODO(sgjesse): Use a MTU value here. Only the loopback adapter can
587 // handle 64k datagrams.
588 const int kReceiveBufferLen = 65536;
589 Socket* socket =
591
592 // Ensure that a receive buffer for the UDP socket exists.
593 ASSERT(socket != nullptr);
594 uint8_t* recv_buffer = socket->udp_receive_buffer();
595 if (recv_buffer == nullptr) {
596 recv_buffer = reinterpret_cast<uint8_t*>(malloc(kReceiveBufferLen));
597 socket->set_udp_receive_buffer(recv_buffer);
598 }
599
600 // Read data into the buffer.
602 const intptr_t bytes_read = SocketBase::RecvFrom(
603 socket->fd(), recv_buffer, kReceiveBufferLen, &addr, SocketBase::kAsync);
604 if (bytes_read == 0) {
606 return;
607 }
608 if (bytes_read < 0) {
609 ASSERT(bytes_read == -1);
611 }
612
613 // Datagram data read. Copy into buffer of the exact size,
614 ASSERT(bytes_read >= 0);
615 uint8_t* data_buffer = nullptr;
616 Dart_Handle data = IOBuffer::Allocate(bytes_read, &data_buffer);
617 if (Dart_IsNull(data)) {
619 }
620 if (Dart_IsError(data)) {
622 }
623 ASSERT(data_buffer != nullptr);
624 memmove(data_buffer, recv_buffer, bytes_read);
625
626 // Get the port and clear it in the sockaddr structure.
628 // TODO(21403): Add checks for AF_UNIX, if unix domain sockets
629 // are used in SOCK_DGRAM.
630 enum internet_type { IPv4, IPv6 };
631 internet_type type;
632 if (addr.addr.sa_family == AF_INET) {
633 addr.in.sin_port = 0;
634 type = IPv4;
635 } else {
636 ASSERT(addr.addr.sa_family == AF_INET6);
637 addr.in6.sin6_port = 0;
638 type = IPv6;
639 }
640 // Format the address to a string using the numeric format.
641 char numeric_address[INET6_ADDRSTRLEN];
642 SocketBase::FormatNumericAddress(addr, numeric_address, INET6_ADDRSTRLEN);
643
644 // Create a Datagram object with the data and sender address and port.
645 const int kNumArgs = 5;
646 Dart_Handle dart_args[kNumArgs];
647 dart_args[0] = data;
648 dart_args[1] = Dart_NewStringFromCString(numeric_address);
649 if (Dart_IsError(dart_args[1])) {
650 Dart_PropagateError(dart_args[1]);
651 }
652 dart_args[2] = SocketAddress::ToTypedData(addr);
653 dart_args[3] = Dart_NewInteger(port);
654 dart_args[4] = Dart_NewInteger(type);
655 if (Dart_IsError(dart_args[3])) {
656 Dart_PropagateError(dart_args[3]);
657 }
658 // TODO(sgjesse): Cache the _makeDatagram function somewhere.
660 if (Dart_IsError(io_lib)) {
661 Dart_PropagateError(io_lib);
662 }
664 io_lib, DartUtils::NewString("_makeDatagram"), kNumArgs, dart_args);
666}
667
671 ASSERT(socket != nullptr);
672
673 int64_t buffer_num_bytes = 0;
675 &buffer_num_bytes);
676 int64_t buffer_num_bytes_allocated = buffer_num_bytes;
677 uint8_t* buffer = nullptr;
678 Dart_Handle data = IOBuffer::Allocate(buffer_num_bytes, &buffer);
679 if (Dart_IsNull(data)) {
681 }
682 ASSERT(buffer != nullptr);
683
684 // Can't rely on RAII since Dart_ThrowException won't call destructors.
685 OSError* os_error = new OSError();
686 SocketControlMessage* control_messages;
687 const intptr_t messages_read = SocketBase::ReceiveMessage(
688 socket->fd(), buffer, &buffer_num_bytes, &control_messages,
689 SocketBase::kAsync, os_error);
690 if (messages_read < 0) {
691 ASSERT(messages_read == -1);
693 delete os_error;
695 }
696 delete os_error;
697 if (buffer_num_bytes > 0 && buffer_num_bytes != buffer_num_bytes_allocated) {
698 // If received fewer than allocated buffer size, truncate buffer.
699 uint8_t* new_buffer = nullptr;
700 Dart_Handle new_data = IOBuffer::Allocate(buffer_num_bytes, &new_buffer);
701 if (Dart_IsNull(new_data)) {
703 }
704 ASSERT(new_buffer != nullptr);
705 memmove(new_buffer, buffer, buffer_num_bytes);
706 data = new_data;
707 }
708
709 // returned list has a (level, type, message bytes) triple for every message,
710 // plus last element is raw data uint8list.
711 Dart_Handle list = ThrowIfError(Dart_NewList(messages_read * 3 + 1));
712 int j = 0;
713 for (intptr_t i = 0; i < messages_read; i++) {
714 SocketControlMessage* message = control_messages + i;
715 Dart_Handle uint8list_message_data = ThrowIfError(
716 DartUtils::MakeUint8Array(message->data(), message->data_length()));
718 list, j++, ThrowIfError(Dart_NewInteger(message->level()))));
720 list, j++, ThrowIfError(Dart_NewInteger(message->type()))));
721 ThrowIfError(Dart_ListSetAt(list, j++, uint8list_message_data));
722 }
725}
726
728#if defined(DART_HOST_OS_WINDOWS)
729 Socket* socket =
731 const bool result = SocketBase::HasPendingWrite(socket->fd());
732#else
733 const bool result = false;
734#endif // defined(DART_HOST_OS_WINDOWS)
736}
737
739 Socket* socket =
741 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
742 ASSERT(Dart_IsList(buffer_obj));
745 bool short_write = false;
747 if (length > 1) {
748 short_write = true;
749 }
750 length = (length + 1) / 2;
751 }
753 uint8_t* buffer = nullptr;
754 intptr_t len;
756 buffer_obj, &type, reinterpret_cast<void**>(&buffer), &len);
757 if (Dart_IsError(result)) {
759 }
760 ASSERT((offset + length) <= len);
761 buffer += offset;
762 intptr_t bytes_written =
764 if (bytes_written >= 0) {
765 Dart_TypedDataReleaseData(buffer_obj);
766 if (short_write) {
767 // If the write was forced 'short', indicate by returning the negative
768 // number of bytes. A forced short write may not trigger a write event.
769 Dart_SetIntegerReturnValue(args, -bytes_written);
770 } else {
771 Dart_SetIntegerReturnValue(args, bytes_written);
772 }
773 } else {
774 // Extract OSError before we release data, as it may override the error.
776 {
777 OSError os_error;
778 Dart_TypedDataReleaseData(buffer_obj);
779 error = DartUtils::NewDartOSError(&os_error);
780 }
782 }
783}
784
786 Socket* socket =
790
791 // List of triples <level, type, data> arranged to minimize dart api use in
792 // native methods.
793 Dart_Handle control_message_list_dart =
795 ASSERT(Dart_IsList(control_message_list_dart));
796 intptr_t num_control_messages_pieces;
798 Dart_ListLength(control_message_list_dart, &num_control_messages_pieces));
799 intptr_t num_control_messages = num_control_messages_pieces / 3;
800 ASSERT((num_control_messages * 3) == num_control_messages_pieces);
801 SocketControlMessage* control_messages =
802 reinterpret_cast<SocketControlMessage*>(Dart_ScopeAllocate(
803 sizeof(SocketControlMessage) * num_control_messages));
804 ASSERT(control_messages != nullptr);
805
806 SocketControlMessage* control_message = control_messages;
807 intptr_t j = 0;
808 for (intptr_t i = 0; i < num_control_messages; i++, control_message++) {
810 ThrowIfError(Dart_ListGetAt(control_message_list_dart, j++)));
812 ThrowIfError(Dart_ListGetAt(control_message_list_dart, j++)));
813 Dart_Handle uint8list_dart =
814 ThrowIfError(Dart_ListGetAt(control_message_list_dart, j++));
815
816 TypedDataScope data(uint8list_dart);
817 void* copied_data = Dart_ScopeAllocate(data.size_in_bytes());
818 ASSERT(copied_data != nullptr);
819 memmove(copied_data, data.data(), data.size_in_bytes());
820 new (control_message)
821 SocketControlMessage(level, type, copied_data, data.size_in_bytes());
822 }
823
824 // Can't rely on RAII since Dart_ThrowException won't call destructors.
825 OSError* os_error = new OSError();
826 intptr_t bytes_written;
827 {
828 Dart_Handle buffer_dart = Dart_GetNativeArgument(args, 1);
829 TypedDataScope data(buffer_dart);
830
831 ASSERT((offset + length) <= data.size_in_bytes());
832 uint8_t* buffer_at_offset =
833 reinterpret_cast<uint8_t*>(data.data()) + offset;
834 bytes_written = SocketBase::SendMessage(
835 socket->fd(), buffer_at_offset, length, control_messages,
836 num_control_messages, SocketBase::kAsync, os_error);
837 }
838
839 if (bytes_written < 0) {
841 delete os_error;
843 }
844 delete os_error;
845
846 Dart_SetIntegerReturnValue(args, bytes_written);
847}
848
850 Socket* socket =
852 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
855 Dart_Handle address_obj = Dart_GetNativeArgument(args, 4);
856 ASSERT(Dart_IsList(address_obj));
858 SocketAddress::GetSockAddr(address_obj, &addr);
860 Dart_GetNativeArgument(args, 5), 0, 65535);
863 uint8_t* buffer = nullptr;
864 intptr_t len;
866 buffer_obj, &type, reinterpret_cast<void**>(&buffer), &len);
867 if (Dart_IsError(result)) {
869 }
870 ASSERT((offset + length) <= len);
871 buffer += offset;
872 intptr_t bytes_written = SocketBase::SendTo(socket->fd(), buffer, length,
874 if (bytes_written >= 0) {
875 Dart_TypedDataReleaseData(buffer_obj);
876 Dart_SetIntegerReturnValue(args, bytes_written);
877 } else {
878 // Extract OSError before we release data, as it may override the error.
880 {
881 OSError os_error;
882 Dart_TypedDataReleaseData(buffer_obj);
883 error = DartUtils::NewDartOSError(&os_error);
884 }
886 }
887}
888
890 Socket* socket =
892 intptr_t port = SocketBase::GetPort(socket->fd());
893 if (port > 0) {
895 } else {
897 }
898}
899
901 Socket* socket =
903 intptr_t port = 0;
905 if (addr != nullptr) {
906 Dart_Handle list = Dart_NewList(2);
907 int type = addr->GetType();
908 Dart_Handle entry;
910 entry = Dart_NewList(2);
911 } else {
912 entry = Dart_NewList(3);
913 RawAddr raw = addr->addr();
915 }
917 Dart_ListSetAt(entry, 1, Dart_NewStringFromCString(addr->as_string()));
918
919 Dart_ListSetAt(list, 0, entry);
922 delete addr;
923 } else {
925 }
926}
927
929 Socket* socket =
931 OSError os_error;
932 SocketBase::GetError(socket->fd(), &os_error);
933 if (os_error.code() != 0) {
935 } else {
937 }
938}
939
942 const char* msgStr =
943 (!Dart_IsNull(msg)) ? DartUtils::GetStringValue(msg) : nullptr;
944 FATAL("Fatal error in dart:io (socket): %s", msgStr);
945}
946
948 Socket* socket =
951}
952
954 Socket* socket =
956 OSError os_error;
957 intptr_t type = SocketBase::GetType(socket->fd());
958 if (type >= 0) {
960 } else {
962 }
963}
964
966 int64_t num =
968 intptr_t socket = SocketBase::GetStdioHandle(num);
972}
973
975 Socket* socket =
977 intptr_t id = reinterpret_cast<intptr_t>(socket);
979}
980
983 intptr_t type_flag =
985 Socket::SocketFinalizer finalizer;
986 if (Socket::IsSignalSocketFlag(type_flag)) {
987 finalizer = Socket::kFinalizerSignal;
988 } else {
989 finalizer = Socket::kFinalizerNormal;
990 }
992 finalizer);
993}
994
999 Dart_GetNativeArgument(args, 2), 0, 65535);
1001 int64_t backlog = DartUtils::GetInt64ValueCheckRange(
1002 Dart_GetNativeArgument(args, 3), 0, 65535);
1005 if (addr.addr.sa_family == AF_INET6) {
1006 Dart_Handle scope_id_arg = Dart_GetNativeArgument(args, 6);
1007 int64_t scope_id =
1008 DartUtils::GetInt64ValueCheckRange(scope_id_arg, 0, 65535);
1010 }
1011
1012 Dart_Handle socket_object = Dart_GetNativeArgument(args, 0);
1014 socket_object, addr, backlog, v6_only, shared);
1016}
1017
1020#if defined(DART_HOST_OS_WINDOWS)
1021 OSError os_error(
1022 -1, "Unix domain sockets are not available on this operating system.",
1025#else
1027 if (Dart_IsNull(address)) {
1029 "expect address to be of type String"));
1030 }
1031 const char* path = DartUtils::GetStringValue(address);
1032 int64_t backlog = DartUtils::GetInt64ValueCheckRange(
1033 Dart_GetNativeArgument(args, 2), 0, 65535);
1035 Namespace* namespc = Namespace::GetNamespace(args, 4);
1036 Dart_Handle socket_object = Dart_GetNativeArgument(args, 0);
1039 socket_object, namespc, path, backlog, shared);
1041#endif // defined(DART_HOST_OS_WINDOWS)
1042}
1043
1045 Socket* socket =
1047 intptr_t new_socket = ServerSocket::Accept(socket->fd());
1048 if (new_socket >= 0) {
1052 } else {
1054 }
1055}
1056
1058 if ((request.Length() == 2) && request[0]->IsString() &&
1059 request[1]->IsInt32()) {
1060 CObjectString host(request[0]);
1061 CObjectInt32 type(request[1]);
1062 CObject* result = nullptr;
1063 OSError* os_error = nullptr;
1064 AddressList<SocketAddress>* addresses =
1065 SocketBase::LookupAddress(host.CString(), type.Value(), &os_error);
1066 if (addresses != nullptr) {
1067 CObjectArray* array =
1068 new CObjectArray(CObject::NewArray(addresses->count() + 1));
1069 array->SetAt(0, new CObjectInt32(CObject::NewInt32(0)));
1070 for (intptr_t i = 0; i < addresses->count(); i++) {
1071 SocketAddress* addr = addresses->GetAt(i);
1073
1075 new CObjectInt32(CObject::NewInt32(addr->GetType()));
1076 entry->SetAt(0, type);
1077
1078 CObjectString* as_string =
1079 new CObjectString(CObject::NewString(addr->as_string()));
1080 entry->SetAt(1, as_string);
1081
1082 RawAddr raw = addr->addr();
1084 entry->SetAt(2, data);
1085
1086 CObjectInt64* scope_id = new CObjectInt64(
1088 entry->SetAt(3, scope_id);
1089
1090 array->SetAt(i + 1, entry);
1091 }
1092 result = array;
1093 delete addresses;
1094 } else {
1095 result = CObject::NewOSError(os_error);
1096 delete os_error;
1097 }
1098 return result;
1099 }
1101}
1102
1104 if ((request.Length() == 1) && request[0]->IsTypedData()) {
1105 CObjectUint8Array addr_object(request[0]);
1106 RawAddr addr;
1107 int len = addr_object.Length();
1108 memset(reinterpret_cast<void*>(&addr), 0, sizeof(RawAddr));
1109 if (len == sizeof(in_addr)) {
1110 addr.in.sin_family = AF_INET;
1111 memmove(reinterpret_cast<void*>(&addr.in.sin_addr), addr_object.Buffer(),
1112 len);
1113 } else {
1114 ASSERT(len == sizeof(in6_addr));
1115 addr.in6.sin6_family = AF_INET6;
1116 memmove(reinterpret_cast<void*>(&addr.in6.sin6_addr),
1117 addr_object.Buffer(), len);
1118 }
1119
1120 OSError* os_error = nullptr;
1121 const intptr_t kMaxHostLength = 1025;
1122 char host[kMaxHostLength];
1123 if (SocketBase::ReverseLookup(addr, host, kMaxHostLength, &os_error)) {
1125 } else {
1126 CObject* result = CObject::NewOSError(os_error);
1127 delete os_error;
1128 return result;
1129 }
1130 }
1132}
1133
1135 if ((request.Length() == 1) && request[0]->IsInt32()) {
1136 CObjectInt32 type(request[0]);
1137 CObject* result = nullptr;
1138 OSError* os_error = nullptr;
1140 SocketBase::ListInterfaces(type.Value(), &os_error);
1141 if (addresses != nullptr) {
1142 CObjectArray* array =
1143 new CObjectArray(CObject::NewArray(addresses->count() + 1));
1144 array->SetAt(0, new CObjectInt32(CObject::NewInt32(0)));
1145 for (intptr_t i = 0; i < addresses->count(); i++) {
1146 InterfaceSocketAddress* interface = addresses->GetAt(i);
1147 SocketAddress* addr = interface->socket_address();
1149
1151 new CObjectInt32(CObject::NewInt32(addr->GetType()));
1152 entry->SetAt(0, type);
1153
1154 CObjectString* as_string =
1155 new CObjectString(CObject::NewString(addr->as_string()));
1156 entry->SetAt(1, as_string);
1157
1158 RawAddr raw = addr->addr();
1160 entry->SetAt(2, data);
1161
1162 CObjectString* interface_name =
1163 new CObjectString(CObject::NewString(interface->interface_name()));
1164 entry->SetAt(3, interface_name);
1165
1166 CObjectInt64* interface_index =
1167 new CObjectInt64(CObject::NewInt64(interface->interface_index()));
1168 entry->SetAt(4, interface_index);
1169
1170 array->SetAt(i + 1, entry);
1171 }
1172 result = array;
1173 delete addresses;
1174 } else {
1175 result = CObject::NewOSError(os_error);
1176 delete os_error;
1177 }
1178 return result;
1179 }
1181}
1182
1184 Socket* socket =
1187 intptr_t protocol = static_cast<intptr_t>(
1189 bool ok = false;
1190 switch (option) {
1191 case 0: { // TCP_NODELAY.
1192 bool enabled;
1193 ok = SocketBase::GetNoDelay(socket->fd(), &enabled);
1194 if (ok) {
1196 }
1197 break;
1198 }
1199 case 1: { // IP_MULTICAST_LOOP.
1200 bool enabled;
1201 ok = SocketBase::GetMulticastLoop(socket->fd(), protocol, &enabled);
1202 if (ok) {
1204 }
1205 break;
1206 }
1207 case 2: { // IP_MULTICAST_TTL.
1208 int value;
1209 ok = SocketBase::GetMulticastHops(socket->fd(), protocol, &value);
1210 if (ok) {
1212 }
1213 break;
1214 }
1215 case 3: { // IP_MULTICAST_IF.
1216 UNIMPLEMENTED();
1217 break;
1218 }
1219 case 4: { // IP_BROADCAST.
1220 bool enabled;
1221 ok = SocketBase::GetBroadcast(socket->fd(), &enabled);
1222 if (ok) {
1224 }
1225 break;
1226 }
1227 default:
1228 UNREACHABLE();
1229 break;
1230 }
1231 // In case of failure the return value is not set above.
1232 if (!ok) {
1234 }
1235}
1236
1238 bool result = false;
1239 Socket* socket =
1242 intptr_t protocol = static_cast<intptr_t>(
1244 switch (option) {
1245 case 0: // TCP_NODELAY.
1247 socket->fd(),
1249 break;
1250 case 1: // IP_MULTICAST_LOOP.
1252 socket->fd(), protocol,
1254 break;
1255 case 2: // IP_MULTICAST_TTL.
1257 socket->fd(), protocol,
1259 break;
1260 case 3: { // IP_MULTICAST_IF.
1261 UNIMPLEMENTED();
1262 break;
1263 }
1264 case 4: // IP_BROADCAST.
1266 socket->fd(),
1268 break;
1269 default:
1271 Dart_NewApiError("option to setOption() is outside expected range"));
1272 break;
1273 }
1274 if (!result) {
1276 }
1277}
1278
1280 Socket* socket =
1285 ASSERT(Dart_IsList(data_obj));
1286 char* data = nullptr;
1287 intptr_t length;
1290 data_obj, &type, reinterpret_cast<void**>(&data), &length);
1291 if (Dart_IsError(data_result)) {
1292 Dart_PropagateError(data_result);
1293 }
1294
1295 bool result = SocketBase::SetOption(socket->fd(), static_cast<int>(level),
1296 static_cast<int>(option), data,
1297 static_cast<int>(length));
1298
1299 Dart_TypedDataReleaseData(data_obj);
1300
1301 if (!result) {
1303 }
1304}
1305
1307 Socket* socket =
1312 ASSERT(Dart_IsList(data_obj));
1313 char* data = nullptr;
1314 intptr_t length;
1317 data_obj, &type, reinterpret_cast<void**>(&data), &length);
1318 if (Dart_IsError(data_result)) {
1319 Dart_PropagateError(data_result);
1320 }
1321 unsigned int int_length = static_cast<unsigned int>(length);
1322 bool result =
1323 SocketBase::GetOption(socket->fd(), static_cast<int>(level),
1324 static_cast<int>(option), data, &int_length);
1325
1326 Dart_TypedDataReleaseData(data_obj);
1327 if (!result) {
1329 }
1330}
1331
1332// Keep in sync with _RawSocketOptions in socket.dart
1333enum _RawSocketOptions : int64_t {
1342
1346 switch (key) {
1347 case DART_SOL_SOCKET:
1348 Dart_SetIntegerReturnValue(args, SOL_SOCKET);
1349 break;
1350 case DART_IPPROTO_IP:
1351 Dart_SetIntegerReturnValue(args, IPPROTO_IP);
1352 break;
1354 Dart_SetIntegerReturnValue(args, IP_MULTICAST_IF);
1355 break;
1356 case DART_IPPROTO_IPV6:
1357 Dart_SetIntegerReturnValue(args, IPPROTO_IPV6);
1358 break;
1360 Dart_SetIntegerReturnValue(args, IPV6_MULTICAST_IF);
1361 break;
1362 case DART_IPPROTO_TCP:
1363 Dart_SetIntegerReturnValue(args, IPPROTO_TCP);
1364 break;
1365 case DART_IPPROTO_UDP:
1366 Dart_SetIntegerReturnValue(args, IPPROTO_UDP);
1367 break;
1368 default:
1370 "option to getOptionValue() is outside expected range"));
1371 break;
1372 }
1373}
1374
1376 Socket* socket =
1378 RawAddr addr;
1380 RawAddr interface;
1381 if (Dart_GetNativeArgument(args, 2) != Dart_Null()) {
1383 }
1384 int interfaceIndex =
1386 if (!SocketBase::JoinMulticast(socket->fd(), addr, interface,
1387 interfaceIndex)) {
1389 }
1390}
1391
1393 Socket* socket =
1395 RawAddr addr;
1397 RawAddr interface;
1398 if (Dart_GetNativeArgument(args, 2) != Dart_Null()) {
1400 }
1401 int interfaceIndex =
1403 if (!SocketBase::LeaveMulticast(socket->fd(), addr, interface,
1404 interfaceIndex)) {
1406 }
1407}
1408
1410 const int kReceiveBufferLen = 1;
1411 Socket* socket =
1413 ASSERT(socket != nullptr);
1414 // Ensure that a receive buffer for peeking the UDP socket exists.
1415 uint8_t recv_buffer[kReceiveBufferLen];
1416 bool available = SocketBase::AvailableDatagram(socket->fd(), recv_buffer,
1417 kReceiveBufferLen);
1418 Dart_SetBooleanReturnValue(args, available);
1419}
1420
1421static void NormalSocketFinalizer(void* isolate_data, void* data) {
1422 Socket* socket = reinterpret_cast<Socket*>(data);
1423 const int64_t flags = 1 << kCloseCommand;
1424 socket->Retain(); // Bump reference till we send the message.
1425 EventHandler::SendFromNative(reinterpret_cast<intptr_t>(socket),
1426 socket->port(), flags);
1427 socket->Release(); // Release the reference we just added above.
1428}
1429
1430static void ListeningSocketFinalizer(void* isolate_data, void* data) {
1431 Socket* socket = reinterpret_cast<Socket*>(data);
1432 const int64_t flags = (1 << kListeningSocket) | (1 << kCloseCommand);
1433 socket->Retain(); // Bump reference till we send the message.
1434 EventHandler::SendFromNative(reinterpret_cast<intptr_t>(socket),
1435 socket->port(), flags);
1436 socket->Release(); // Release the reference we just added above.
1437}
1438
1439static void StdioSocketFinalizer(void* isolate_data, void* data) {
1440 Socket* socket = reinterpret_cast<Socket*>(data);
1441 if (socket->fd() >= 0) {
1442 socket->CloseFd();
1443 }
1444 socket->Release();
1445}
1446
1447static void SignalSocketFinalizer(void* isolate_data, void* data) {
1448 Socket* socket = reinterpret_cast<Socket*>(data);
1449 const int64_t flags = (1 << kSignalSocket) | (1 << kCloseCommand);
1450 socket->Retain(); // Bump reference till we send the message.
1451 EventHandler::SendFromNative(reinterpret_cast<intptr_t>(socket),
1452 socket->port(), flags);
1453 socket->Release(); // Release the reference we just added above.
1454}
1455
1457 Socket* socket,
1458 SocketFinalizer finalizer) {
1460 handle, kSocketIdNativeField, reinterpret_cast<intptr_t>(socket));
1461 if (Dart_IsError(err)) {
1463 }
1465 switch (finalizer) {
1466 case kFinalizerNormal:
1468 break;
1469 case kFinalizerListening:
1471 break;
1472 case kFinalizerStdio:
1474 break;
1475 case kFinalizerSignal:
1477 break;
1478 default:
1479 callback = nullptr;
1480 UNREACHABLE();
1481 break;
1482 }
1483 if (callback != nullptr) {
1484 Dart_NewFinalizableHandle(handle, reinterpret_cast<void*>(socket),
1485 sizeof(Socket), callback);
1486 }
1487}
1488
1490 intptr_t id,
1491 SocketFinalizer finalizer) {
1492 Socket* socket = new Socket(id);
1493 ReuseSocketIdNativeField(handle, socket, finalizer);
1494}
1495
1497 intptr_t id;
1498 Dart_Handle err =
1500 if (Dart_IsError(err)) {
1502 }
1503 Socket* socket = reinterpret_cast<Socket*>(id);
1504 if (socket == nullptr) {
1506 DartUtils::NewInternalError("No native peer")));
1507 }
1508 return socket;
1509}
1510
1513#if defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
1516 "This is not supported on this operating system"));
1517#else
1519 Dart_Handle handles_dart = Dart_GetNativeArgument(args, 1);
1520 if (Dart_IsNull(handles_dart)) {
1522 DartUtils::NewDartArgumentError("handles list can't be null"));
1523 }
1524 ASSERT(Dart_IsList(handles_dart));
1525 intptr_t num_handles;
1526 ThrowIfError(Dart_ListLength(handles_dart, &num_handles));
1527 intptr_t num_bytes = num_handles * sizeof(int);
1528 int* handles = reinterpret_cast<int*>(Dart_ScopeAllocate(num_bytes));
1529 Dart_Handle handle_dart_string =
1531 for (intptr_t i = 0; i < num_handles; i++) {
1532 Dart_Handle handle_dart = ThrowIfError(Dart_ListGetAt(handles_dart, i));
1533 Dart_Handle handle_int_dart =
1534 ThrowIfError(Dart_GetField(handle_dart, handle_dart_string));
1535 handles[i] = DartUtils::GetIntegerValue(handle_int_dart);
1536 }
1537
1538 Dart_Handle uint8list_dart =
1540 ThrowIfError(Dart_ListSetAsBytes(uint8list_dart, /*offset=*/0,
1541 reinterpret_cast<const uint8_t*>(handles),
1542 num_bytes));
1543 Dart_Handle dart_new_args[] = {Dart_NewInteger(SOL_SOCKET),
1544 Dart_NewInteger(SCM_RIGHTS), uint8list_dart};
1545
1546 Dart_Handle socket_control_message_impl = ThrowIfError(DartUtils::GetDartType(
1547 DartUtils::kIOLibURL, "_SocketControlMessageImpl"));
1549 args,
1550 Dart_New(socket_control_message_impl,
1551 /*constructor_name=*/Dart_Null(),
1552 sizeof(dart_new_args) / sizeof(Dart_Handle), dart_new_args));
1553#endif // defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
1554}
1555
1558#if defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
1561 "This is not supported on this operating system"));
1562#else
1563 Dart_Handle handle_type = ThrowIfError(
1564 DartUtils::GetDartType(DartUtils::kIOLibURL, "ResourceHandle"));
1565
1566 Dart_Handle message_dart = Dart_GetNativeArgument(args, 0);
1568 ThrowIfError(Dart_GetField(message_dart, DartUtils::NewString("level"))));
1570 ThrowIfError(Dart_GetField(message_dart, DartUtils::NewString("type"))));
1571 if (level != SOL_SOCKET || type != SCM_RIGHTS) {
1573 handle_type, Dart_Null(), 0)));
1574 return;
1575 }
1576
1577 Dart_Handle data_dart =
1578 ThrowIfError(Dart_GetField(message_dart, DartUtils::NewString("data")));
1579 ASSERT(Dart_IsTypedData(data_dart));
1580
1581 void* data;
1582 intptr_t bytes_count;
1583 Dart_TypedData_Type data_type;
1585 Dart_TypedDataAcquireData(data_dart, &data_type, &data, &bytes_count));
1586 ASSERT(data_type == Dart_TypedData_kUint8);
1587 int* ints_data = reinterpret_cast<int*>(Dart_ScopeAllocate(bytes_count));
1588 ASSERT(ints_data != nullptr);
1589 memmove(ints_data, data, bytes_count);
1591 intptr_t ints_count = bytes_count / sizeof(int);
1592
1593 Dart_Handle handle_impl_type =
1594 DartUtils::GetDartType(DartUtils::kIOLibURL, "_ResourceHandleImpl");
1595 Dart_Handle sentinel = ThrowIfError(
1596 Dart_GetField(handle_impl_type, DartUtils::NewString("_sentinel")));
1597 Dart_Handle handle_list =
1598 ThrowIfError(Dart_NewListOfTypeFilled(handle_type, sentinel, ints_count));
1599 for (intptr_t i = 0; i < ints_count; i++) {
1600 Dart_Handle constructor_args[] = {
1601 ThrowIfError(Dart_NewInteger(*(ints_data + i)))};
1602 Dart_Handle handle_impl = ThrowIfError(Dart_New(
1603 handle_impl_type,
1604 /*constructor_name=*/Dart_Null(),
1605 sizeof(constructor_args) / sizeof(Dart_Handle), constructor_args));
1606 ThrowIfError(Dart_ListSetAt(handle_list, i, handle_impl));
1607 }
1608
1609 Dart_SetReturnValue(args, handle_list);
1610#endif // defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
1611}
1612
1614#if defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
1617 "This is not supported on this operating system"));
1618#else
1620 Dart_Handle handle_field = ThrowIfError(
1621 Dart_GetField(handle_object, DartUtils::NewString("_handle")));
1622 intptr_t fd = DartUtils::GetIntegerValue(handle_field);
1623
1624 Dart_Handle random_access_file_type = ThrowIfError(
1625 DartUtils::GetDartType(DartUtils::kIOLibURL, "_RandomAccessFile"));
1626
1627 Dart_Handle dart_new_args[2];
1628 dart_new_args[1] = ThrowIfError(Dart_NewStringFromCString("<handle>"));
1629
1630 File* file = File::OpenFD(fd);
1631
1632 Dart_Handle result = Dart_NewInteger(reinterpret_cast<intptr_t>(file));
1633 if (Dart_IsError(result)) {
1634 file->Release();
1636 }
1637 dart_new_args[0] = result;
1638
1639 Dart_Handle new_random_access_file =
1640 Dart_New(random_access_file_type,
1641 /*constructor_name=*/Dart_Null(),
1642 /*number_of_arguments=*/2, dart_new_args);
1643 if (Dart_IsError(new_random_access_file)) {
1644 file->Release();
1645 Dart_PropagateError(new_random_access_file);
1646 }
1647
1648 Dart_SetReturnValue(args, new_random_access_file);
1649#endif // defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
1650}
1651
1655 "This is not supported on this operating system"));
1656}
1657
1659#if defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
1662 "This is not supported on this operating system"));
1663#else
1665 Dart_Handle handle_field = ThrowIfError(
1666 Dart_GetField(handle_object, DartUtils::NewString("_handle")));
1667 intptr_t fd = DartUtils::GetIntegerValue(handle_field);
1668
1669 SocketAddress* socket_address = reinterpret_cast<SocketAddress*>(
1671 ASSERT(socket_address != nullptr);
1672 SocketBase::GetSocketName(fd, socket_address);
1673
1674 // return a list describing socket_address: (type, hostname, typed_data_addr,
1675 // fd)
1678 list, 0, ThrowIfError(Dart_NewInteger(socket_address->GetType()))));
1680 list, 1,
1681 ThrowIfError(Dart_NewStringFromCString(socket_address->as_string()))));
1683 list, 2, SocketAddress::ToTypedData(socket_address->addr())));
1685
1687#endif // defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
1688}
1689
1694 "This is not supported on this operating system"));
1695}
1696
1697} // namespace bin
1698} // namespace dart
static float prev(float f)
static bool ok(int result)
#define UNREACHABLE()
Definition: assert.h:248
GLenum type
#define FUNCTION_NAME(name)
Definition: builtin.h:19
Entry * Start() const
Definition: hashmap.cc:123
Entry * Lookup(void *key, uint32_t hash, bool insert)
Definition: hashmap.cc:20
void Remove(void *key, uint32_t hash)
Definition: hashmap.cc:49
Entry * Next(Entry *p) const
Definition: hashmap.cc:127
static int Unlink(const char *path)
intptr_t count() const
Definition: socket_base.h:140
T * GetAt(intptr_t i) const
Definition: socket_base.h:141
void SetAt(intptr_t index, CObject *value)
Definition: dartutils.h:548
intptr_t Length() const
Definition: dartutils.h:544
const uint8_t * Buffer() const
Definition: dartutils.h:594
intptr_t Length() const
Definition: dartutils.h:593
static Dart_CObject * NewString(const char *str)
Definition: dartutils.cc:927
static CObject * IllegalArgumentError()
Definition: dartutils.cc:1026
static Dart_CObject * NewArray(intptr_t length)
Definition: dartutils.cc:936
static Dart_CObject * NewInt32(int32_t value)
Definition: dartutils.cc:902
static Dart_CObject * NewInt64(int64_t value)
Definition: dartutils.cc:908
static CObject * NewOSError()
Definition: dartutils.cc:1038
static int64_t GetIntegerValue(Dart_Handle value_obj)
Definition: dartutils.cc:81
static int64_t GetInt64ValueCheckRange(Dart_Handle value_obj, int64_t lower, int64_t upper)
Definition: dartutils.cc:90
static constexpr const char * kIOLibURL
Definition: dartutils.h:297
static Dart_Handle NewDartOSError()
Definition: dartutils.cc:702
static bool GetBooleanValue(Dart_Handle bool_obj)
Definition: dartutils.cc:137
static bool GetInt64Value(Dart_Handle value_obj, int64_t *value)
Definition: dartutils.cc:112
static const char * GetStringValue(Dart_Handle str_obj)
Definition: dartutils.cc:128
static Dart_Handle MakeUint8Array(const void *buffer, intptr_t length)
Definition: dartutils.cc:360
static Dart_Handle NewDartUnsupportedError(const char *message)
Definition: dartutils.cc:754
static intptr_t GetNativeIntptrArgument(Dart_NativeArguments args, intptr_t index)
Definition: dartutils.cc:166
static Dart_Handle NewString(const char *str)
Definition: dartutils.h:214
static Dart_Handle NewDartArgumentError(const char *message)
Definition: dartutils.cc:746
static Dart_Handle NewInternalError(const char *message)
Definition: dartutils.cc:781
static Dart_Handle GetDartType(const char *library_url, const char *class_name)
Definition: dartutils.cc:696
static intptr_t GetIntptrValue(Dart_Handle value_obj)
Definition: dartutils.cc:100
static void SendFromNative(intptr_t id, Dart_Port port, int64_t data)
Definition: eventhandler.cc:71
static bool Exists(Namespace *namespc, const char *path)
static File * OpenFD(int fd)
static Dart_Handle Allocate(intptr_t size, uint8_t **buffer)
Definition: io_buffer.cc:12
Dart_Handle CreateBindListen(Dart_Handle socket_object, RawAddr addr, intptr_t backlog, bool v6_only, bool shared)
Definition: socket.cc:94
bool CloseSafe(Socket *socketfd)
Definition: socket.cc:350
Dart_Handle CreateUnixDomainBindListen(Dart_Handle socket_object, Namespace *namespc, const char *path, intptr_t backlog, bool shared)
Definition: socket.cc:197
static ListeningSocketRegistry * Instance()
Definition: socket.cc:38
static Namespace * GetNamespace(Dart_NativeArguments args, intptr_t index)
Definition: namespace.cc:101
static intptr_t CreateBindListen(const RawAddr &addr, intptr_t backlog, bool v6_only=false)
static intptr_t Accept(intptr_t fd)
static bool StartAccept(intptr_t fd)
static intptr_t CreateUnixDomainBindListen(const RawAddr &addr, intptr_t backlog)
static void SetAddrScope(RawAddr *addr, intptr_t scope_id)
Definition: socket_base.cc:232
static void GetSockAddr(Dart_Handle obj, RawAddr *addr)
Definition: socket_base.cc:105
static intptr_t GetAddrScope(const RawAddr &addr)
Definition: socket_base.cc:237
static void SetAddrPort(RawAddr *addr, intptr_t port)
Definition: socket_base.cc:177
const char * as_string() const
Definition: socket_base.h:67
static CObjectUint8Array * ToCObject(const RawAddr &addr)
Definition: socket_base.cc:220
static Dart_Handle GetUnixDomainSockAddr(const char *path, Namespace *namespc, RawAddr *addr)
Definition: socket_base.cc:130
static Dart_Handle ToTypedData(const RawAddr &addr)
Definition: socket_base.cc:200
static intptr_t GetAddrPort(const RawAddr &addr)
Definition: socket_base.cc:187
const RawAddr & addr() const
Definition: socket_base.h:68
static bool LeaveMulticast(intptr_t fd, const RawAddr &addr, const RawAddr &interface, int interfaceIndex)
static bool AvailableDatagram(intptr_t fd, void *buffer, intptr_t num_bytes)
static int GetType(intptr_t fd)
static AddressList< SocketAddress > * LookupAddress(const char *host, int type, OSError **os_error)
static bool SetMulticastHops(intptr_t fd, intptr_t protocol, int value)
static intptr_t GetStdioHandle(intptr_t num)
static intptr_t ReceiveMessage(intptr_t fd, void *buffer, int64_t *p_buffer_num_bytes, SocketControlMessage **p_messages, SocketOpKind sync, OSError *p_oserror)
static bool SetOption(intptr_t fd, int level, int option, const char *data, int length)
static SocketAddress * GetRemotePeer(intptr_t fd, intptr_t *port)
static bool FormatNumericAddress(const RawAddr &addr, char *address, int len)
static bool SetNoDelay(intptr_t fd, bool enabled)
static bool GetSocketName(intptr_t fd, SocketAddress *p_sa)
static intptr_t Available(intptr_t fd)
static void GetError(intptr_t fd, OSError *os_error)
static intptr_t RecvFrom(intptr_t fd, void *buffer, intptr_t num_bytes, RawAddr *addr, SocketOpKind sync)
static intptr_t Read(intptr_t fd, void *buffer, intptr_t num_bytes, SocketOpKind sync)
static bool SetBroadcast(intptr_t fd, bool value)
static bool GetNoDelay(intptr_t fd, bool *enabled)
static bool SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled)
static bool GetOption(intptr_t fd, int level, int option, char *data, unsigned int *length)
static bool ReverseLookup(const RawAddr &addr, char *host, intptr_t host_len, OSError **os_error)
static intptr_t SendTo(intptr_t fd, const void *buffer, intptr_t num_bytes, const RawAddr &addr, SocketOpKind sync)
static bool GetMulticastHops(intptr_t fd, intptr_t protocol, int *value)
static bool GetMulticastLoop(intptr_t fd, intptr_t protocol, bool *enabled)
static bool JoinMulticast(intptr_t fd, const RawAddr &addr, const RawAddr &interface, int interfaceIndex)
static intptr_t SendMessage(intptr_t fd, void *buffer, size_t buffer_num_bytes, SocketControlMessage *messages, intptr_t num_messages, SocketOpKind sync, OSError *p_oserror)
static AddressList< InterfaceSocketAddress > * ListInterfaces(int type, OSError **os_error)
static bool GetBroadcast(intptr_t fd, bool *value)
static intptr_t Write(intptr_t fd, const void *buffer, intptr_t num_bytes, SocketOpKind sync)
Definition: socket_base.cc:321
static intptr_t GetPort(intptr_t fd)
static bool IsSignalSocketFlag(intptr_t flag)
Definition: socket.h:111
static CObject * ListInterfacesRequest(const CObjectArray &request)
Definition: socket.cc:1134
intptr_t fd() const
Definition: socket.h:52
static bool short_socket_read()
Definition: socket.h:102
void set_udp_receive_buffer(uint8_t *buffer)
Definition: socket.h:67
static CObject * ReverseLookupRequest(const CObjectArray &request)
Definition: socket.cc:1103
static bool short_socket_write()
Definition: socket.h:106
static intptr_t CreateUnixDomainConnect(const RawAddr &addr)
uint8_t * udp_receive_buffer() const
Definition: socket.h:66
static void SetSocketIdNativeField(Dart_Handle handle, intptr_t id, SocketFinalizer finalizer)
Definition: socket.cc:1489
Dart_Port port() const
Definition: socket.h:63
static Socket * GetSocketIdNativeField(Dart_Handle socket)
Definition: socket.cc:1496
static intptr_t CreateConnect(const RawAddr &addr)
static intptr_t CreateBindDatagram(const RawAddr &addr, bool reuseAddress, bool reusePort, int ttl=1)
static void ReuseSocketIdNativeField(Dart_Handle handle, Socket *socket, SocketFinalizer finalizer)
Definition: socket.cc:1456
static CObject * LookupRequest(const CObjectArray &request)
Definition: socket.cc:1057
static intptr_t CreateBindConnect(const RawAddr &addr, const RawAddr &source_addr)
@ kFinalizerListening
Definition: socket.h:37
static intptr_t CreateUnixDomainBindConnect(const RawAddr &addr, const RawAddr &source_addr)
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
void(* Dart_HandleFinalizer)(void *isolate_callback_data, void *peer)
Definition: dart_api.h:265
struct _Dart_NativeArguments * Dart_NativeArguments
Definition: dart_api.h:3019
Dart_TypedData_Type
Definition: dart_api.h:2612
@ Dart_TypedData_kUint8
Definition: dart_api.h:2615
#define UNIMPLEMENTED
#define ASSERT(E)
#define FATAL(error)
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
GAsyncResult * result
size_t length
Win32Message message
void FUNCTION_NAME() Socket_CreateBindDatagram(Dart_NativeArguments args)
Definition: socket.cc:498
static constexpr int kSocketIdNativeField
Definition: socket.cc:26
void FUNCTION_NAME() Socket_GetPort(Dart_NativeArguments args)
Definition: socket.cc:889
void FUNCTION_NAME() Socket_ReceiveMessage(Dart_NativeArguments args)
Definition: socket.cc:668
static void StdioSocketFinalizer(void *isolate_data, void *data)
Definition: socket.cc:1439
void FUNCTION_NAME() ResourceHandleImpl_toFile(Dart_NativeArguments args)
Definition: socket.cc:1613
void FUNCTION_NAME() Socket_GetFD(Dart_NativeArguments args)
Definition: socket.cc:947
void FUNCTION_NAME() ResourceHandleImpl_toSocket(Dart_NativeArguments args)
Definition: socket.cc:1652
@ kListeningSocket
Definition: eventhandler.h:33
static Dart_Handle ThrowIfError(Dart_Handle handle)
Definition: dartutils.h:31
void FUNCTION_NAME() Socket_GetError(Dart_NativeArguments args)
Definition: socket.cc:928
void FUNCTION_NAME() Socket_GetRemotePeer(Dart_NativeArguments args)
Definition: socket.cc:900
void FUNCTION_NAME() Socket_JoinMulticast(Dart_NativeArguments args)
Definition: socket.cc:1375
ListeningSocketRegistry * globalTcpListeningSocketRegistry
Definition: socket.cc:28
void FUNCTION_NAME() SocketControlMessage_fromHandles(Dart_NativeArguments args)
Definition: socket.cc:1511
_RawSocketOptions
Definition: socket.cc:1333
@ DART_IPV6_MULTICAST_IF
Definition: socket.cc:1338
@ DART_IPPROTO_UDP
Definition: socket.cc:1340
@ DART_IPPROTO_IPV6
Definition: socket.cc:1337
@ DART_IPPROTO_TCP
Definition: socket.cc:1339
@ DART_IPPROTO_IP
Definition: socket.cc:1335
@ DART_IP_MULTICAST_IF
Definition: socket.cc:1336
@ DART_SOL_SOCKET
Definition: socket.cc:1334
static void SignalSocketFinalizer(void *isolate_data, void *data)
Definition: socket.cc:1447
void FUNCTION_NAME() SocketControlMessageImpl_extractHandles(Dart_NativeArguments args)
Definition: socket.cc:1556
void FUNCTION_NAME() RawSocketOption_GetOptionValue(Dart_NativeArguments args)
Definition: socket.cc:1343
void FUNCTION_NAME() Socket_Read(Dart_NativeArguments args)
Definition: socket.cc:532
static void NormalSocketFinalizer(void *isolate_data, void *data)
Definition: socket.cc:1421
void FUNCTION_NAME() Socket_GetOption(Dart_NativeArguments args)
Definition: socket.cc:1183
void FUNCTION_NAME() ServerSocket_CreateBindListen(Dart_NativeArguments args)
Definition: socket.cc:995
void FUNCTION_NAME() ServerSocket_Accept(Dart_NativeArguments args)
Definition: socket.cc:1044
void FUNCTION_NAME() Socket_AvailableDatagram(Dart_NativeArguments args)
Definition: socket.cc:1409
void FUNCTION_NAME() Socket_RecvFrom(Dart_NativeArguments args)
Definition: socket.cc:585
void FUNCTION_NAME() Socket_SetRawOption(Dart_NativeArguments args)
Definition: socket.cc:1279
void FUNCTION_NAME() Socket_LeaveMulticast(Dart_NativeArguments args)
Definition: socket.cc:1392
void FUNCTION_NAME() Socket_CreateUnixDomainBindConnect(Dart_NativeArguments args)
Definition: socket.cc:421
void FUNCTION_NAME() Socket_SendMessage(Dart_NativeArguments args)
Definition: socket.cc:785
void FUNCTION_NAME() Socket_SetSocketId(Dart_NativeArguments args)
Definition: socket.cc:981
void FUNCTION_NAME() ServerSocket_CreateUnixDomainBindListen(Dart_NativeArguments args)
Definition: socket.cc:1018
void FUNCTION_NAME() Socket_Fatal(Dart_NativeArguments args)
Definition: socket.cc:940
void FUNCTION_NAME() Socket_SendTo(Dart_NativeArguments args)
Definition: socket.cc:849
void FUNCTION_NAME() ResourceHandleImpl_toRawSocket(Dart_NativeArguments args)
Definition: socket.cc:1658
void FUNCTION_NAME() ResourceHandleImpl_toRawDatagramSocket(Dart_NativeArguments args)
Definition: socket.cc:1690
void FUNCTION_NAME() Socket_CreateBindConnect(Dart_NativeArguments args)
Definition: socket.cc:391
void FUNCTION_NAME() Socket_SetOption(Dart_NativeArguments args)
Definition: socket.cc:1237
void FUNCTION_NAME() Socket_GetSocketId(Dart_NativeArguments args)
Definition: socket.cc:974
void FUNCTION_NAME() Socket_GetType(Dart_NativeArguments args)
Definition: socket.cc:953
void FUNCTION_NAME() Socket_GetRawOption(Dart_NativeArguments args)
Definition: socket.cc:1306
void FUNCTION_NAME() Socket_GetStdioHandle(Dart_NativeArguments args)
Definition: socket.cc:965
void FUNCTION_NAME() Socket_CreateUnixDomainConnect(Dart_NativeArguments args)
Definition: socket.cc:467
void FUNCTION_NAME() Socket_Available(Dart_NativeArguments args)
Definition: socket.cc:519
static void ListeningSocketFinalizer(void *isolate_data, void *data)
Definition: socket.cc:1430
void FUNCTION_NAME() Socket_CreateConnect(Dart_NativeArguments args)
Definition: socket.cc:363
void FUNCTION_NAME() Socket_HasPendingWrite(Dart_NativeArguments args)
Definition: socket.cc:727
void FUNCTION_NAME() Socket_WriteList(Dart_NativeArguments args)
Definition: socket.cc:738
Definition: dart_vm.cc:33
DART_EXPORT Dart_Handle Dart_ListGetAt(Dart_Handle list, intptr_t index)
DART_EXPORT Dart_Handle Dart_False()
DART_EXPORT Dart_Handle Dart_GetNativeInstanceField(Dart_Handle obj, int index, intptr_t *value)
DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target, Dart_Handle name, int number_of_arguments, Dart_Handle *arguments)
DART_EXPORT Dart_Handle Dart_True()
DART_EXPORT void Dart_SetBooleanReturnValue(Dart_NativeArguments args, bool retval)
void * malloc(size_t size)
Definition: allocation.cc:19
DART_EXPORT Dart_Handle Dart_NewUnhandledExceptionError(Dart_Handle exception)
DART_EXPORT Dart_Handle Dart_NewInteger(int64_t value)
DART_EXPORT void Dart_PropagateError(Dart_Handle handle)
DART_EXPORT Dart_FinalizableHandle Dart_NewFinalizableHandle(Dart_Handle object, void *peer, intptr_t external_allocation_size, Dart_HandleFinalizer callback)
DART_EXPORT Dart_Handle Dart_NewTypedData(Dart_TypedData_Type type, intptr_t length)
DART_EXPORT uint8_t * Dart_ScopeAllocate(intptr_t size)
DART_EXPORT void Dart_SetReturnValue(Dart_NativeArguments args, Dart_Handle retval)
DART_EXPORT Dart_Handle Dart_GetField(Dart_Handle container, Dart_Handle name)
DART_EXPORT Dart_Handle Dart_TypedDataAcquireData(Dart_Handle object, Dart_TypedData_Type *type, void **data, intptr_t *len)
DART_EXPORT Dart_Handle Dart_NewListOfTypeFilled(Dart_Handle element_type, Dart_Handle fill_object, intptr_t length)
DART_EXPORT Dart_Handle Dart_ListSetAt(Dart_Handle list, intptr_t index, Dart_Handle value)
DART_EXPORT Dart_Handle Dart_NewBoolean(bool value)
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT Dart_Handle Dart_SetNativeInstanceField(Dart_Handle obj, int index, intptr_t value)
DART_EXPORT void Dart_SetIntegerReturnValue(Dart_NativeArguments args, int64_t retval)
DART_EXPORT Dart_Handle Dart_ListSetAsBytes(Dart_Handle list, intptr_t offset, const uint8_t *native_array, intptr_t length)
DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args, int index)
DART_EXPORT Dart_Handle Dart_TypedDataReleaseData(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_NewApiError(const char *error)
DART_EXPORT Dart_Handle Dart_ListLength(Dart_Handle list, intptr_t *len)
DART_EXPORT Dart_Handle Dart_NewList(intptr_t length)
DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url)
DART_EXPORT bool Dart_IsList(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception)
DART_EXPORT bool Dart_IsNull(Dart_Handle object)
DART_EXPORT bool Dart_IsTypedData(Dart_Handle handle)
DART_EXPORT Dart_Handle Dart_Null()
DART_EXPORT Dart_Handle Dart_New(Dart_Handle type, Dart_Handle constructor_name, int number_of_arguments, Dart_Handle *arguments)
static int8_t data[kExtLength]
DART_EXPORT Dart_Handle Dart_NewStringFromCString(const char *str)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service port
Definition: switches.h:87
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service host
Definition: switches.h:74
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
SeparatedVector2 offset
const uintptr_t id