Flutter Engine
The Flutter Engine
socket_base_macos.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 "platform/globals.h"
6#if defined(DART_HOST_OS_MACOS)
7
8#include "bin/socket_base.h"
9
10#include <errno.h> // NOLINT
11#include <ifaddrs.h> // NOLINT
12#include <net/if.h> // NOLINT
13#include <netinet/tcp.h> // NOLINT
14#include <stdio.h> // NOLINT
15#include <stdlib.h> // NOLINT
16#include <string.h> // NOLINT
17#include <sys/stat.h> // NOLINT
18#include <unistd.h> // NOLINT
19
20#include "bin/fdutils.h"
21#include "bin/file.h"
24
25namespace dart {
26namespace bin {
27
28void SocketBase::GetError(intptr_t fd, OSError* os_error) {
29 int len = sizeof(errno);
30 getsockopt(fd, SOL_SOCKET, SO_ERROR, &errno,
31 reinterpret_cast<socklen_t*>(&len));
32 os_error->SetCodeAndMessage(OSError::kSystem, errno);
33}
34
35int SocketBase::GetType(intptr_t fd) {
36 struct stat buf;
37 int result = fstat(fd, &buf);
38 if (result == -1) {
39 return -1;
40 }
41 if (S_ISCHR(buf.st_mode)) {
42 return File::kTerminal;
43 }
44 if (S_ISFIFO(buf.st_mode)) {
45 return File::kPipe;
46 }
47 if (S_ISREG(buf.st_mode)) {
48 return File::kFile;
49 }
50 return File::kOther;
51}
52
53AddressList<SocketAddress>* SocketBase::LookupAddress(const char* host,
54 int type,
55 OSError** os_error) {
56 // Perform a name lookup for a host name.
57 struct addrinfo hints;
58 memset(&hints, 0, sizeof(hints));
59 hints.ai_family = SocketAddress::FromType(type);
60 hints.ai_socktype = SOCK_STREAM;
61 hints.ai_flags = 0;
62 hints.ai_protocol = IPPROTO_TCP;
63 struct addrinfo* info = nullptr;
64 int status = getaddrinfo(host, nullptr, &hints, &info);
65 if (status != 0) {
66 ASSERT(*os_error == nullptr);
67 *os_error =
68 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo);
69 return nullptr;
70 }
71 intptr_t count = 0;
72 for (struct addrinfo* c = info; c != nullptr; c = c->ai_next) {
73 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) {
74 count++;
75 }
76 }
77 intptr_t i = 0;
78 AddressList<SocketAddress>* addresses = new AddressList<SocketAddress>(count);
79 for (struct addrinfo* c = info; c != nullptr; c = c->ai_next) {
80 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) {
81 addresses->SetAt(i, new SocketAddress(c->ai_addr));
82 i++;
83 }
84 }
85 freeaddrinfo(info);
86 return addresses;
87}
88
89bool SocketBase::SetMulticastLoop(intptr_t fd,
90 intptr_t protocol,
91 bool enabled) {
92 u_int on = enabled ? 1 : 0;
93 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
94 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP
95 : IPV6_MULTICAST_LOOP;
96 return NO_RETRY_EXPECTED(setsockopt(
97 fd, level, optname, reinterpret_cast<char*>(&on), sizeof(on))) ==
98 0;
99}
100
101bool SocketBase::GetOption(intptr_t fd,
102 int level,
103 int option,
104 char* data,
105 unsigned int* length) {
106 return NO_RETRY_EXPECTED(getsockopt(fd, level, option, data, length)) == 0;
107}
108
109static bool JoinOrLeaveMulticast(intptr_t fd,
110 const RawAddr& addr,
111 const RawAddr& interface,
112 int interfaceIndex,
113 bool join) {
114 if (addr.addr.sa_family == AF_INET) {
115 ASSERT(interface.addr.sa_family == AF_INET);
116 struct ip_mreq mreq;
117 memmove(&mreq.imr_multiaddr, &addr.in.sin_addr,
119 memmove(&mreq.imr_interface, &interface.in.sin_addr,
121 if (join) {
122 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
123 &mreq, sizeof(mreq))) == 0;
124 } else {
125 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
126 &mreq, sizeof(mreq))) == 0;
127 }
128 } else {
129 ASSERT(addr.addr.sa_family == AF_INET6);
130 struct ipv6_mreq mreq;
131 memmove(&mreq.ipv6mr_multiaddr, &addr.in6.sin6_addr,
133 mreq.ipv6mr_interface = interfaceIndex;
134 if (join) {
135 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
136 &mreq, sizeof(mreq))) == 0;
137 } else {
138 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
139 &mreq, sizeof(mreq))) == 0;
140 }
141 }
142}
143
144bool SocketBase::JoinMulticast(intptr_t fd,
145 const RawAddr& addr,
146 const RawAddr& interface,
147 int interfaceIndex) {
148 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, true);
149}
150
151bool SocketBase::LeaveMulticast(intptr_t fd,
152 const RawAddr& addr,
153 const RawAddr& interface,
154 int interfaceIndex) {
155 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, false);
156}
157
158} // namespace bin
159} // namespace dart
160
161#endif // defined(DART_HOST_OS_MACOS)
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
int count
Definition: FontMgrTest.cpp:50
GLenum type
static int16_t FromType(int type)
Definition: socket_base.cc:163
static intptr_t GetInAddrLength(const RawAddr &addr)
Definition: socket_base.cc:74
static bool LeaveMulticast(intptr_t fd, const RawAddr &addr, const RawAddr &interface, int interfaceIndex)
static int GetType(intptr_t fd)
static AddressList< SocketAddress > * LookupAddress(const char *host, int type, OSError **os_error)
static void GetError(intptr_t fd, OSError *os_error)
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 JoinMulticast(intptr_t fd, const RawAddr &addr, const RawAddr &interface, int interfaceIndex)
#define ASSERT(E)
GAsyncResult * result
size_t length
Definition: dart_vm.cc:33
static int8_t data[kExtLength]
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
#define NO_RETRY_EXPECTED(expression)
static SkString join(const CommandLineFlags::StringArray &)
Definition: skpbench.cpp:741