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
Comment #1 by bugzilla — 2007-01-09T02:42:05Z
Cannot reproduce this with DMD on Windows.
Comment #2 by thomas-dloop — 2007-01-21T17:41:12Z
# import std.socket, std.stdio; # # class Test : InternetAddress{ # this(){ } # # void check(){ # ubyte* d = cast(ubyte*)cast(void*)&sin; # writefln("%s", d[0 .. sin.sizeof]); # writefln("%s", sin.sin_family == AddressFamily.INET); # } # } # # void main(){ # (new Test()).check(); # } dmd-1.0 / Linux: > [2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] > true gdmd-0.21 / Linux: > [2,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255] > true
Comment #3 by chris — 2007-01-29T15:06:05Z
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)
Comment #6 by dvdfrdmn — 2007-03-08T20:08:56Z
Fixed in release 0.22