Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
37
41
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
95 RawAddr addr,
96 intptr_t backlog,
97 bool v6_only,
98 bool shared) {
99 MutexLocker ml(&mutex_);
100
101 OSSocket* first_os_socket = nullptr;
102 intptr_t port = SocketAddress::GetAddrPort(addr);
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
205 RawAddr addr;
207 SocketAddress::GetUnixDomainSockAddr(path, namespc, &addr);
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
364 RawAddr addr;
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);
373 SocketAddress::SetAddrScope(&addr, scope_id);
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.
392 RawAddr addr;
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);
408 SocketAddress::SetAddrScope(&addr, scope_id);
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
429 RawAddr addr;
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
474 RawAddr addr;
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
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.
601 RawAddr addr;
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.
627 int port = SocketAddress::GetAddrPort(addr);
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++) {
809 int level = DartUtils::GetIntegerValue(
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));
857 RawAddr addr;
858 SocketAddress::GetSockAddr(address_obj, &addr);
860 Dart_GetNativeArgument(args, 5), 0, 65535);
861 SocketAddress::SetAddrPort(&addr, port);
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,
873 addr, SocketBase::kAsync);
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;
904 SocketAddress* addr = SocketBase::GetRemotePeer(socket->fd(), &port);
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);
920 Dart_ListSetAt(list, 1, Dart_NewInteger(port));
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
952
964
973
975 Socket* socket =
977 intptr_t id = reinterpret_cast<intptr_t>(socket);
979}
980
994
996 RawAddr addr;
999 Dart_GetNativeArgument(args, 2), 0, 65535);
1000 SocketAddress::SetAddrPort(&addr, port);
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);
1009 SocketAddress::SetAddrScope(&addr, scope_id);
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)) {
1124 return new CObjectString(CObject::NewString(host));
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
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);
1567 intptr_t level = DartUtils::GetIntegerValue(
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
Type::kYUV Type::kRGBA() int(0.7 *637)
#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
T * GetAt(intptr_t i) const
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:933
static CObject * IllegalArgumentError()
static Dart_CObject * NewArray(intptr_t length)
Definition dartutils.cc:942
static Dart_CObject * NewInt32(int32_t value)
Definition dartutils.cc:908
static Dart_CObject * NewInt64(int64_t value)
Definition dartutils.cc:914
static CObject * NewOSError()
static int64_t GetIntegerValue(Dart_Handle value_obj)
Definition dartutils.cc:85
static int64_t GetInt64ValueCheckRange(Dart_Handle value_obj, int64_t lower, int64_t upper)
Definition dartutils.cc:94
static constexpr const char * kIOLibURL
Definition dartutils.h:297
static Dart_Handle NewDartOSError()
Definition dartutils.cc:706
static bool GetBooleanValue(Dart_Handle bool_obj)
Definition dartutils.cc:141
static bool GetInt64Value(Dart_Handle value_obj, int64_t *value)
Definition dartutils.cc:116
static const char * GetStringValue(Dart_Handle str_obj)
Definition dartutils.cc:132
static Dart_Handle MakeUint8Array(const void *buffer, intptr_t length)
Definition dartutils.cc:364
static Dart_Handle NewDartUnsupportedError(const char *message)
Definition dartutils.cc:758
static intptr_t GetNativeIntptrArgument(Dart_NativeArguments args, intptr_t index)
Definition dartutils.cc:170
static Dart_Handle NewString(const char *str)
Definition dartutils.h:214
static Dart_Handle NewDartArgumentError(const char *message)
Definition dartutils.cc:750
static Dart_Handle NewInternalError(const char *message)
Definition dartutils.cc:786
static Dart_Handle GetDartType(const char *library_url, const char *class_name)
Definition dartutils.cc:700
static intptr_t GetIntptrValue(Dart_Handle value_obj)
Definition dartutils.cc:104
static void SendFromNative(intptr_t id, Dart_Port port, int64_t data)
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)
static void GetSockAddr(Dart_Handle obj, RawAddr *addr)
static intptr_t GetAddrScope(const RawAddr &addr)
static void SetAddrPort(RawAddr *addr, intptr_t port)
const char * as_string() const
Definition socket_base.h:67
static CObjectUint8Array * ToCObject(const RawAddr &addr)
static Dart_Handle GetUnixDomainSockAddr(const char *path, Namespace *namespc, RawAddr *addr)
static Dart_Handle ToTypedData(const RawAddr &addr)
static intptr_t GetAddrPort(const RawAddr &addr)
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)
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)
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:3010
Dart_TypedData_Type
Definition dart_api.h:2603
@ Dart_TypedData_kUint8
Definition dart_api.h:2606
#define UNIMPLEMENTED
#define ASSERT(E)
#define FATAL(error)
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
static const uint8_t buffer[]
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
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
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)
Point offset
const uintptr_t id