|
54 | 54 | import static com.oracle.graal.python.runtime.PosixConstants.AF_INET; |
55 | 55 | import static com.oracle.graal.python.runtime.PosixConstants.AF_INET6; |
56 | 56 | import static com.oracle.graal.python.runtime.PosixConstants.AF_UNSPEC; |
| 57 | +import static com.oracle.graal.python.runtime.PosixConstants.AI_CANONNAME; |
57 | 58 | import static com.oracle.graal.python.runtime.PosixConstants.AI_NUMERICHOST; |
58 | 59 | import static com.oracle.graal.python.runtime.PosixConstants.INADDR_ANY; |
59 | 60 | import static com.oracle.graal.python.runtime.PosixConstants.NI_DGRAM; |
|
80 | 81 | import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; |
81 | 82 | import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum; |
82 | 83 | import com.oracle.graal.python.builtins.objects.function.PKeyword; |
| 84 | +import com.oracle.graal.python.builtins.objects.list.PList; |
83 | 85 | import com.oracle.graal.python.builtins.objects.module.PythonModule; |
84 | 86 | import com.oracle.graal.python.builtins.objects.socket.SocketNodes; |
85 | 87 | import com.oracle.graal.python.builtins.objects.socket.SocketNodes.IdnaFromStringOrBytesConverterNode; |
@@ -370,6 +372,55 @@ protected static IdnaFromStringOrBytesConverterNode createIdnaConverter() { |
370 | 372 | } |
371 | 373 | } |
372 | 374 |
|
| 375 | + @Builtin(name = "gethostbyname_ex", minNumOfPositionalArgs = 1) |
| 376 | + @GenerateNodeFactory |
| 377 | + public abstract static class GetHostByNameExNode extends PythonUnaryBuiltinNode { |
| 378 | + @Specialization |
| 379 | + Object get(VirtualFrame frame, Object nameObj, |
| 380 | + @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, |
| 381 | + @CachedLibrary(limit = "1") UniversalSockAddrLibrary addrLib, |
| 382 | + @CachedLibrary(limit = "1") AddrInfoCursorLibrary addrInfoCursorLib, |
| 383 | + @Bind("this") Node inliningTarget, |
| 384 | + @Cached("createIdnaConverter()") IdnaFromStringOrBytesConverterNode idnaConverter, |
| 385 | + @Cached SysModuleBuiltins.AuditNode auditNode, |
| 386 | + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, |
| 387 | + @Cached PythonObjectFactory factory) { |
| 388 | + byte[] name = idnaConverter.execute(frame, nameObj); |
| 389 | + // The event name is really without the _ex, it's not a copy-paste error |
| 390 | + auditNode.audit(inliningTarget, "socket.gethostbyname", factory.createTuple(new Object[]{nameObj})); |
| 391 | + /* |
| 392 | + * TODO this uses getaddrinfo to emulate the legacy gethostbyname. It doesn't support |
| 393 | + * aliases and multiple addresses. We might want to use the legacy gethostbyname_r API |
| 394 | + * in the future |
| 395 | + */ |
| 396 | + try { |
| 397 | + AddrInfoCursor cursor = posixLib.getaddrinfo(getPosixSupport(), posixLib.createPathFromBytes(getPosixSupport(), name), |
| 398 | + null, AF_INET.value, 0, 0, AI_CANONNAME.value); |
| 399 | + try { |
| 400 | + TruffleString canonName = posixLib.getPathAsString(getPosixSupport(), addrInfoCursorLib.getCanonName(cursor)); |
| 401 | + Inet4SockAddr inet4SockAddr = addrLib.asInet4SockAddr(addrInfoCursorLib.getSockAddr(cursor)); |
| 402 | + TruffleString addr = posixLib.getPathAsString(getPosixSupport(), posixLib.inet_ntop(getPosixSupport(), AF_INET.value, inet4SockAddr.getAddressAsBytes())); |
| 403 | + // getaddrinfo doesn't support aliases |
| 404 | + PList aliases = factory.createList(); |
| 405 | + // we support just one address for now |
| 406 | + PList addrs = factory.createList(new Object[]{addr}); |
| 407 | + return factory.createTuple(new Object[]{canonName, aliases, addrs}); |
| 408 | + } finally { |
| 409 | + addrInfoCursorLib.release(cursor); |
| 410 | + } |
| 411 | + } catch (GetAddrInfoException e) { |
| 412 | + throw constructAndRaiseNode.get(inliningTarget).executeWithArgsOnly(frame, SocketHError, new Object[]{e.getMessageAsTruffleString()}); |
| 413 | + } catch (PosixException e) { |
| 414 | + throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); |
| 415 | + } |
| 416 | + } |
| 417 | + |
| 418 | + @NeverDefault |
| 419 | + protected static IdnaFromStringOrBytesConverterNode createIdnaConverter() { |
| 420 | + return IdnaFromStringOrBytesConverterNode.create("gethostbyname_ex", 1); |
| 421 | + } |
| 422 | + } |
| 423 | + |
373 | 424 | @Builtin(name = "getservbyname", minNumOfPositionalArgs = 1, numOfPositionalOnlyArgs = 2, parameterNames = {"servicename", "protocolname"}) |
374 | 425 | @ArgumentClinic(name = "servicename", conversion = ArgumentClinic.ClinicConversion.TString) |
375 | 426 | @ArgumentClinic(name = "protocolname", conversion = ArgumentClinic.ClinicConversion.TString, defaultValue = "PNone.NO_VALUE") |
|
0 commit comments