Bug 818 – std.socket.InternetAddress.sin needs to be properly initialized on OS X
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
PowerPC
OS
Mac OS X
Creation time
2007-01-08T03:25:00Z
Last change time
2015-06-09T05:14:44Z
Assigned to
dvdfrdmn
Creator
d
Comments
Comment #0 by d — 2007-01-08T03:25:01Z
While translating a C++ program into D on Mac OS X 10.4.7, I was unable to get the bind() call to work on any address other than ADDR_ANY and kept receiving a EADDRNOTAVAIL error code. After dissecting D's std/stream.d, I have discovered that the problem originated from the InternetAddress class in std.socket because it does not zero out the sockaddr_in struct and does not set the sin_family value to AddressFamily.INET. This caused OS X's bind() to fail.
To temporarily fix this problem I created a wrapper around InternetAddress:
/**
* A modified InternetAddress that works on Darwin.
*/
class IPAddress : InternetAddress {
private import std.c.string;
this(char[] addr, ushort port) {
memset(cast(void *) &sin, 0, sin.sizeof);
sin.sin_family = AddressFamily.INET;
super(addr, port);
}
}
InternetAddress's constructors should be changed to zero out the sockaddr_in and set sin_family so that this problem can be avoided on Mac OS X.
Reference: http://cvs.haskell.org/trac/ghc/ticket/647
-- Jeff
sockaddr_in's initializer automatically sets these values, perhaps they just don't in your OS X port.
e.g.
struct sockaddr_in
{
int16_t sin_family = AF_INET; // Here.
uint16_t sin_port;
in_addr sin_addr;
ubyte[8] sin_zero; // D automatically initializes with 0.
}
Comment #4 by d — 2007-01-29T22:01:30Z
On OS X sin_zero is initialized to [0, 255, 255, 255, 255, 255, 255, 255] instead of all-zero. Using this fixes the EADDRNOTAVAIL errors on my PPC Mac:
class IPAddress : InternetAddress {
this(char[] addr, ushort port) {
sin.sin_zero[] = 0;
super(addr, port);
}
}
Comment #5 by afb — 2007-01-30T02:35:21Z
This seems to be a bug in the generated configunix.d:
char[8] sin_zero = [0];
As you are pointing out, it should instead have been:
ubyte[8] sin_zero = 0;
This is a GDC bug, so that it works in DMD doesn't help.
(std.c.windows.socket and std.c.linux.socket uses ubyte)