| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2017, 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 #if !defined(DART_IO_DISABLED) |
| 6 |
| 7 #include "bin/socket_common.h" |
| 8 #include "bin/socket.h" |
| 9 |
| 10 #include "bin/dartutils.h" |
| 11 #include "bin/io_buffer.h" |
| 12 #include "bin/isolate_data.h" |
| 13 #include "bin/lockers.h" |
| 14 #include "bin/thread.h" |
| 15 #include "bin/utils.h" |
| 16 |
| 17 #include "include/dart_api.h" |
| 18 |
| 19 #include "platform/globals.h" |
| 20 #include "platform/utils.h" |
| 21 |
| 22 namespace dart { |
| 23 namespace bin { |
| 24 |
| 25 static const int kSocketIdNativeField = 0; |
| 26 |
| 27 bool short_socket_read = false; |
| 28 |
| 29 bool short_socket_write = false; |
| 30 |
| 31 void FUNCTION_NAME(InternetAddress_Parse)(Dart_NativeArguments args) { |
| 32 const char* address = |
| 33 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0)); |
| 34 ASSERT(address != NULL); |
| 35 RawAddr raw; |
| 36 memset(&raw, 0, sizeof(raw)); |
| 37 int type = strchr(address, ':') == NULL ? SocketAddress::TYPE_IPV4 |
| 38 : SocketAddress::TYPE_IPV6; |
| 39 if (type == SocketAddress::TYPE_IPV4) { |
| 40 raw.addr.sa_family = AF_INET; |
| 41 } else { |
| 42 raw.addr.sa_family = AF_INET6; |
| 43 } |
| 44 bool ok = BaseSocket::ParseAddress(type, address, &raw); |
| 45 if (!ok) { |
| 46 Dart_SetReturnValue(args, Dart_Null()); |
| 47 } else { |
| 48 Dart_SetReturnValue(args, SocketAddress::ToTypedData(raw)); |
| 49 } |
| 50 } |
| 51 |
| 52 |
| 53 void FUNCTION_NAME(NetworkInterface_ListSupported)(Dart_NativeArguments args) { |
| 54 Dart_SetReturnValue(args, Dart_NewBoolean(Socket::ListInterfacesSupported())); |
| 55 } |
| 56 |
| 57 |
| 58 void FUNCTION_NAME(BaseSocket_IsBindError)(Dart_NativeArguments args) { |
| 59 intptr_t error_number = |
| 60 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1)); |
| 61 bool is_bind_error = BaseSocket::IsBindError(error_number); |
| 62 Dart_SetReturnValue(args, is_bind_error ? Dart_True() : Dart_False()); |
| 63 } |
| 64 |
| 65 |
| 66 void FUNCTION_NAME(BaseSocket_Available)(Dart_NativeArguments args) { |
| 67 intptr_t socket = |
| 68 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); |
| 69 intptr_t available = BaseSocket::Available(socket); |
| 70 if (available >= 0) { |
| 71 Dart_SetReturnValue(args, Dart_NewInteger(available)); |
| 72 } else { |
| 73 // Available failed. Mark socket as having data, to trigger a future read |
| 74 // event where the actual error can be reported. |
| 75 Dart_SetReturnValue(args, Dart_NewInteger(1)); |
| 76 } |
| 77 } |
| 78 |
| 79 |
| 80 void FUNCTION_NAME(BaseSocket_Read)(Dart_NativeArguments args) { |
| 81 intptr_t socket = |
| 82 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); |
| 83 int64_t length = 0; |
| 84 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &length)) { |
| 85 if (short_socket_read) { |
| 86 length = (length + 1) / 2; |
| 87 } |
| 88 uint8_t* buffer = NULL; |
| 89 Dart_Handle result = IOBuffer::Allocate(length, &buffer); |
| 90 if (Dart_IsError(result)) { |
| 91 Dart_PropagateError(result); |
| 92 } |
| 93 ASSERT(buffer != NULL); |
| 94 intptr_t bytes_read = BaseSocket::Read(socket, buffer, length); |
| 95 if (bytes_read == length) { |
| 96 Dart_SetReturnValue(args, result); |
| 97 } else if (bytes_read > 0) { |
| 98 uint8_t* new_buffer = NULL; |
| 99 Dart_Handle new_result = IOBuffer::Allocate(bytes_read, &new_buffer); |
| 100 if (Dart_IsError(new_result)) { |
| 101 Dart_PropagateError(new_result); |
| 102 } |
| 103 ASSERT(new_buffer != NULL); |
| 104 memmove(new_buffer, buffer, bytes_read); |
| 105 Dart_SetReturnValue(args, new_result); |
| 106 } else if (bytes_read == 0) { |
| 107 // On MacOS when reading from a tty Ctrl-D will result in reading one |
| 108 // less byte then reported as available. |
| 109 Dart_SetReturnValue(args, Dart_Null()); |
| 110 } else { |
| 111 ASSERT(bytes_read == -1); |
| 112 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 113 } |
| 114 } else { |
| 115 OSError os_error(-1, "Invalid argument", OSError::kUnknown); |
| 116 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error)); |
| 117 } |
| 118 } |
| 119 |
| 120 |
| 121 void FUNCTION_NAME(BaseSocket_RecvFrom)(Dart_NativeArguments args) { |
| 122 intptr_t socket = |
| 123 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); |
| 124 |
| 125 // TODO(sgjesse): Use a MTU value here. Only the loopback adapter can |
| 126 // handle 64k datagrams. |
| 127 IsolateData* isolate_data = |
| 128 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); |
| 129 if (isolate_data->udp_receive_buffer == NULL) { |
| 130 isolate_data->udp_receive_buffer = |
| 131 reinterpret_cast<uint8_t*>(malloc(65536)); |
| 132 } |
| 133 RawAddr addr; |
| 134 intptr_t bytes_read = BaseSocket::RecvFrom( |
| 135 socket, isolate_data->udp_receive_buffer, 65536, &addr); |
| 136 if (bytes_read == 0) { |
| 137 Dart_SetReturnValue(args, Dart_Null()); |
| 138 return; |
| 139 } |
| 140 if (bytes_read < 0) { |
| 141 ASSERT(bytes_read == -1); |
| 142 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 143 return; |
| 144 } |
| 145 // Datagram data read. Copy into buffer of the exact size, |
| 146 ASSERT(bytes_read > 0); |
| 147 uint8_t* data_buffer = NULL; |
| 148 Dart_Handle data = IOBuffer::Allocate(bytes_read, &data_buffer); |
| 149 if (Dart_IsError(data)) { |
| 150 Dart_PropagateError(data); |
| 151 } |
| 152 ASSERT(data_buffer != NULL); |
| 153 memmove(data_buffer, isolate_data->udp_receive_buffer, bytes_read); |
| 154 |
| 155 // Get the port and clear it in the sockaddr structure. |
| 156 int port = SocketAddress::GetAddrPort(addr); |
| 157 if (addr.addr.sa_family == AF_INET) { |
| 158 addr.in.sin_port = 0; |
| 159 } else { |
| 160 ASSERT(addr.addr.sa_family == AF_INET6); |
| 161 addr.in6.sin6_port = 0; |
| 162 } |
| 163 // Format the address to a string using the numeric format. |
| 164 char numeric_address[INET6_ADDRSTRLEN]; |
| 165 BaseSocket::FormatNumericAddress(addr, numeric_address, INET6_ADDRSTRLEN); |
| 166 |
| 167 // Create a Datagram object with the data and sender address and port. |
| 168 const int kNumArgs = 4; |
| 169 Dart_Handle dart_args[kNumArgs]; |
| 170 dart_args[0] = data; |
| 171 dart_args[1] = Dart_NewStringFromCString(numeric_address); |
| 172 if (Dart_IsError(dart_args[1])) { |
| 173 Dart_PropagateError(dart_args[1]); |
| 174 } |
| 175 dart_args[2] = SocketAddress::ToTypedData(addr); |
| 176 dart_args[3] = Dart_NewInteger(port); |
| 177 if (Dart_IsError(dart_args[3])) { |
| 178 Dart_PropagateError(dart_args[3]); |
| 179 } |
| 180 // TODO(sgjesse): Cache the _makeDatagram function somewhere. |
| 181 Dart_Handle io_lib = Dart_LookupLibrary(DartUtils::NewString("dart:io")); |
| 182 if (Dart_IsError(io_lib)) { |
| 183 Dart_PropagateError(io_lib); |
| 184 } |
| 185 Dart_Handle result = Dart_Invoke( |
| 186 io_lib, DartUtils::NewString("_makeDatagram"), kNumArgs, dart_args); |
| 187 Dart_SetReturnValue(args, result); |
| 188 } |
| 189 |
| 190 |
| 191 void FUNCTION_NAME(BaseSocket_WriteList)(Dart_NativeArguments args) { |
| 192 intptr_t socket = |
| 193 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); |
| 194 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1); |
| 195 ASSERT(Dart_IsList(buffer_obj)); |
| 196 intptr_t offset = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2)); |
| 197 intptr_t length = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3)); |
| 198 bool short_write = false; |
| 199 if (short_socket_write) { |
| 200 if (length > 1) { |
| 201 short_write = true; |
| 202 } |
| 203 length = (length + 1) / 2; |
| 204 } |
| 205 Dart_TypedData_Type type; |
| 206 uint8_t* buffer = NULL; |
| 207 intptr_t len; |
| 208 Dart_Handle result = Dart_TypedDataAcquireData( |
| 209 buffer_obj, &type, reinterpret_cast<void**>(&buffer), &len); |
| 210 if (Dart_IsError(result)) { |
| 211 Dart_PropagateError(result); |
| 212 } |
| 213 ASSERT((offset + length) <= len); |
| 214 buffer += offset; |
| 215 intptr_t bytes_written = BaseSocket::Write(socket, buffer, length); |
| 216 if (bytes_written >= 0) { |
| 217 Dart_TypedDataReleaseData(buffer_obj); |
| 218 if (short_write) { |
| 219 // If the write was forced 'short', indicate by returning the negative |
| 220 // number of bytes. A forced short write may not trigger a write event. |
| 221 Dart_SetReturnValue(args, Dart_NewInteger(-bytes_written)); |
| 222 } else { |
| 223 Dart_SetReturnValue(args, Dart_NewInteger(bytes_written)); |
| 224 } |
| 225 } else { |
| 226 // Extract OSError before we release data, as it may override the error. |
| 227 OSError os_error; |
| 228 Dart_TypedDataReleaseData(buffer_obj); |
| 229 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error)); |
| 230 } |
| 231 } |
| 232 |
| 233 |
| 234 void FUNCTION_NAME(BaseSocket_SendTo)(Dart_NativeArguments args) { |
| 235 intptr_t socket = |
| 236 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); |
| 237 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1); |
| 238 intptr_t offset = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2)); |
| 239 intptr_t length = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3)); |
| 240 Dart_Handle address_obj = Dart_GetNativeArgument(args, 4); |
| 241 ASSERT(Dart_IsList(address_obj)); |
| 242 RawAddr addr; |
| 243 SocketAddress::GetSockAddr(address_obj, &addr); |
| 244 int64_t port = DartUtils::GetInt64ValueCheckRange( |
| 245 Dart_GetNativeArgument(args, 5), 0, 65535); |
| 246 SocketAddress::SetAddrPort(&addr, port); |
| 247 Dart_TypedData_Type type; |
| 248 uint8_t* buffer = NULL; |
| 249 intptr_t len; |
| 250 Dart_Handle result = Dart_TypedDataAcquireData( |
| 251 buffer_obj, &type, reinterpret_cast<void**>(&buffer), &len); |
| 252 if (Dart_IsError(result)) { |
| 253 Dart_PropagateError(result); |
| 254 } |
| 255 ASSERT((offset + length) <= len); |
| 256 buffer += offset; |
| 257 intptr_t bytes_written = BaseSocket::SendTo(socket, buffer, length, addr); |
| 258 if (bytes_written >= 0) { |
| 259 Dart_TypedDataReleaseData(buffer_obj); |
| 260 Dart_SetReturnValue(args, Dart_NewInteger(bytes_written)); |
| 261 } else { |
| 262 // Extract OSError before we release data, as it may override the error. |
| 263 OSError os_error; |
| 264 Dart_TypedDataReleaseData(buffer_obj); |
| 265 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error)); |
| 266 } |
| 267 } |
| 268 |
| 269 |
| 270 void FUNCTION_NAME(BaseSocket_GetPort)(Dart_NativeArguments args) { |
| 271 intptr_t socket = |
| 272 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); |
| 273 OSError os_error; |
| 274 intptr_t port = BaseSocket::GetPort(socket); |
| 275 if (port > 0) { |
| 276 Dart_SetReturnValue(args, Dart_NewInteger(port)); |
| 277 } else { |
| 278 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 279 } |
| 280 } |
| 281 |
| 282 |
| 283 void FUNCTION_NAME(BaseSocket_GetRemotePeer)(Dart_NativeArguments args) { |
| 284 intptr_t socket = |
| 285 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); |
| 286 OSError os_error; |
| 287 intptr_t port = 0; |
| 288 SocketAddress* addr = BaseSocket::GetRemotePeer(socket, &port); |
| 289 if (addr != NULL) { |
| 290 Dart_Handle list = Dart_NewList(2); |
| 291 |
| 292 Dart_Handle entry = Dart_NewList(3); |
| 293 Dart_ListSetAt(entry, 0, Dart_NewInteger(addr->GetType())); |
| 294 Dart_ListSetAt(entry, 1, Dart_NewStringFromCString(addr->as_string())); |
| 295 |
| 296 RawAddr raw = addr->addr(); |
| 297 Dart_ListSetAt(entry, 2, SocketAddress::ToTypedData(raw)); |
| 298 |
| 299 Dart_ListSetAt(list, 0, entry); |
| 300 Dart_ListSetAt(list, 1, Dart_NewInteger(port)); |
| 301 Dart_SetReturnValue(args, list); |
| 302 delete addr; |
| 303 } else { |
| 304 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 305 } |
| 306 } |
| 307 |
| 308 |
| 309 void FUNCTION_NAME(BaseSocket_GetError)(Dart_NativeArguments args) { |
| 310 intptr_t socket = |
| 311 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); |
| 312 OSError os_error; |
| 313 BaseSocket::GetError(socket, &os_error); |
| 314 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error)); |
| 315 } |
| 316 |
| 317 |
| 318 void FUNCTION_NAME(BaseSocket_GetType)(Dart_NativeArguments args) { |
| 319 intptr_t socket = |
| 320 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); |
| 321 OSError os_error; |
| 322 intptr_t type = BaseSocket::GetType(socket); |
| 323 if (type >= 0) { |
| 324 Dart_SetReturnValue(args, Dart_NewInteger(type)); |
| 325 } else { |
| 326 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 327 } |
| 328 } |
| 329 |
| 330 |
| 331 void FUNCTION_NAME(BaseSocket_GetStdioHandle)(Dart_NativeArguments args) { |
| 332 int64_t num = |
| 333 DartUtils::GetInt64ValueCheckRange(Dart_GetNativeArgument(args, 1), 0, 2); |
| 334 intptr_t socket = BaseSocket::GetStdioHandle(num); |
| 335 BaseSocket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket); |
| 336 Dart_SetReturnValue(args, Dart_NewBoolean(socket >= 0)); |
| 337 } |
| 338 |
| 339 |
| 340 void FUNCTION_NAME(BaseSocket_GetSocketId)(Dart_NativeArguments args) { |
| 341 intptr_t id = |
| 342 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); |
| 343 Dart_SetReturnValue(args, Dart_NewInteger(id)); |
| 344 } |
| 345 |
| 346 |
| 347 void FUNCTION_NAME(BaseSocket_SetSocketId)(Dart_NativeArguments args) { |
| 348 intptr_t id = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1)); |
| 349 BaseSocket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), id); |
| 350 } |
| 351 |
| 352 |
| 353 void FUNCTION_NAME(BaseSocket_GetOption)(Dart_NativeArguments args) { |
| 354 intptr_t socket = |
| 355 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); |
| 356 int64_t option = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1)); |
| 357 intptr_t protocol = static_cast<intptr_t>( |
| 358 DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 2))); |
| 359 bool ok = false; |
| 360 switch (option) { |
| 361 case 0: { // TCP_NODELAY. |
| 362 bool enabled; |
| 363 ok = BaseSocket::GetNoDelay(socket, &enabled); |
| 364 if (ok) { |
| 365 Dart_SetReturnValue(args, enabled ? Dart_True() : Dart_False()); |
| 366 } |
| 367 break; |
| 368 } |
| 369 case 1: { // IP_MULTICAST_LOOP. |
| 370 bool enabled; |
| 371 ok = BaseSocket::GetMulticastLoop(socket, protocol, &enabled); |
| 372 if (ok) { |
| 373 Dart_SetReturnValue(args, enabled ? Dart_True() : Dart_False()); |
| 374 } |
| 375 break; |
| 376 } |
| 377 case 2: { // IP_MULTICAST_TTL. |
| 378 int value; |
| 379 ok = BaseSocket::GetMulticastHops(socket, protocol, &value); |
| 380 if (ok) { |
| 381 Dart_SetReturnValue(args, Dart_NewInteger(value)); |
| 382 } |
| 383 break; |
| 384 } |
| 385 case 3: { // IP_MULTICAST_IF. |
| 386 UNIMPLEMENTED(); |
| 387 break; |
| 388 } |
| 389 case 4: { // IP_BROADCAST. |
| 390 bool enabled; |
| 391 ok = BaseSocket::GetBroadcast(socket, &enabled); |
| 392 if (ok) { |
| 393 Dart_SetReturnValue(args, enabled ? Dart_True() : Dart_False()); |
| 394 } |
| 395 break; |
| 396 } |
| 397 default: |
| 398 UNREACHABLE(); |
| 399 break; |
| 400 } |
| 401 // In case of failure the return value is not set above. |
| 402 if (!ok) { |
| 403 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 404 } |
| 405 } |
| 406 |
| 407 |
| 408 void FUNCTION_NAME(BaseSocket_SetOption)(Dart_NativeArguments args) { |
| 409 bool result = false; |
| 410 intptr_t socket = |
| 411 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); |
| 412 int64_t option = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1)); |
| 413 int64_t protocol = DartUtils::GetInt64ValueCheckRange( |
| 414 Dart_GetNativeArgument(args, 2), SocketAddress::TYPE_IPV4, |
| 415 SocketAddress::TYPE_IPV6); |
| 416 switch (option) { |
| 417 case 0: // TCP_NODELAY. |
| 418 result = BaseSocket::SetNoDelay( |
| 419 socket, DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3))); |
| 420 break; |
| 421 case 1: // IP_MULTICAST_LOOP. |
| 422 result = BaseSocket::SetMulticastLoop( |
| 423 socket, protocol, |
| 424 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3))); |
| 425 break; |
| 426 case 2: // IP_MULTICAST_TTL. |
| 427 result = BaseSocket::SetMulticastHops( |
| 428 socket, protocol, |
| 429 DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3))); |
| 430 break; |
| 431 case 3: { // IP_MULTICAST_IF. |
| 432 UNIMPLEMENTED(); |
| 433 break; |
| 434 } |
| 435 case 4: // IP_BROADCAST. |
| 436 result = BaseSocket::SetBroadcast( |
| 437 socket, DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3))); |
| 438 break; |
| 439 default: |
| 440 Dart_PropagateError(Dart_NewApiError("Value outside expected range")); |
| 441 break; |
| 442 } |
| 443 if (result) { |
| 444 Dart_SetReturnValue(args, Dart_Null()); |
| 445 } else { |
| 446 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 447 } |
| 448 } |
| 449 |
| 450 |
| 451 void FUNCTION_NAME(BaseSocket_JoinMulticast)(Dart_NativeArguments args) { |
| 452 intptr_t socket = |
| 453 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); |
| 454 RawAddr addr; |
| 455 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr); |
| 456 RawAddr interface; |
| 457 if (Dart_GetNativeArgument(args, 2) != Dart_Null()) { |
| 458 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 2), &interface); |
| 459 } |
| 460 int interfaceIndex = |
| 461 DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3)); |
| 462 if (BaseSocket::JoinMulticast(socket, addr, interface, interfaceIndex)) { |
| 463 Dart_SetReturnValue(args, Dart_Null()); |
| 464 } else { |
| 465 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 466 } |
| 467 } |
| 468 |
| 469 |
| 470 void FUNCTION_NAME(BaseSocket_LeaveMulticast)(Dart_NativeArguments args) { |
| 471 intptr_t socket = |
| 472 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); |
| 473 RawAddr addr; |
| 474 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr); |
| 475 RawAddr interface; |
| 476 if (Dart_GetNativeArgument(args, 2) != Dart_Null()) { |
| 477 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 2), &interface); |
| 478 } |
| 479 int interfaceIndex = |
| 480 DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3)); |
| 481 if (Socket::LeaveMulticast(socket, addr, interface, interfaceIndex)) { |
| 482 Dart_SetReturnValue(args, Dart_Null()); |
| 483 } else { |
| 484 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
| 485 } |
| 486 } |
| 487 |
| 488 |
| 489 void BaseSocket::SetSocketIdNativeField(Dart_Handle socket, intptr_t id) { |
| 490 Dart_Handle err = |
| 491 Dart_SetNativeInstanceField(socket, kSocketIdNativeField, id); |
| 492 if (Dart_IsError(err)) { |
| 493 Dart_PropagateError(err); |
| 494 } |
| 495 } |
| 496 |
| 497 |
| 498 intptr_t BaseSocket::GetSocketIdNativeField(Dart_Handle socket_obj) { |
| 499 intptr_t socket = 0; |
| 500 Dart_Handle err = |
| 501 Dart_GetNativeInstanceField(socket_obj, kSocketIdNativeField, &socket); |
| 502 if (Dart_IsError(err)) { |
| 503 Dart_PropagateError(err); |
| 504 } |
| 505 return socket; |
| 506 } |
| 507 |
| 508 } // namespace bin |
| 509 } // namespace dart |
| 510 |
| 511 #endif // !defined(DART_IO_DISABLED) |
| OLD | NEW |