--- a/UnixOperatingSystem.st Tue Mar 20 22:07:03 2018 +0100
+++ b/UnixOperatingSystem.st Tue Mar 20 22:40:45 2018 +0100
@@ -10184,7 +10184,7 @@
#endif
%}.
seconds notNil ifTrue:[
- ^ { ((seconds * 1000) + millis) . micros }
+ ^ { ((seconds * 1000) + millis) . micros }
].
self primitiveFailed.
@@ -13342,6 +13342,10 @@
int ret, __flags;
char *bp;
int nInstBytes, sockAddrSize;
+ union {
+ struct sockaddr_in addr;
+ char enoughBytesForBigAddresses[1024];
+ } sav_addr;
if (wantHostName == true) {
hp = host;
@@ -13376,13 +13380,32 @@
}
{
+ char *sav_bp;
+
bp = (char *)(__byteArrayVal(socketAddress));
bp += nInstBytes;
+
+ // when we run this interruptable (or even in a separate thread),
+ // we cannot pass ST/X objects to it
+ // (some other ST/X thread might trigger a GC)
+ if (sockAddrSize <= sizeof(sav_addr)) {
+ sav_bp = (char *)(&sav_addr.addr);
+ } else {
+ fprintf(stderr, "OS: sockAddr buffer size too small\n");
+ sav_bp = (char *)malloc(sockAddrSize + 32);
+ }
+ memcpy(sav_bp, bp, sockAddrSize);
+
__BEGIN_INTERRUPTABLE__
- ret = getnameinfo((struct sockaddr *)bp, sockAddrSize,
+ ret = getnameinfo((struct sockaddr *)sav_bp, sockAddrSize,
hp, hsz, sp, ssz, __flags);
__END_INTERRUPTABLE__
+
+ if (sav_bp != (char *)(&sav_addr.addr)) {
+ free(sav_bp);
+ }
} while (ret == EAI_SYSTEM && errno == EINTR);
+
if (ret != 0) {
switch (ret) {
case EAI_FAMILY: