PageRenderTime 12ms CodeModel.GetById 1ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/platform/unix/scaffold/socket.d

http://github.com/wilkie/djehuty
D | 169 lines | 111 code | 43 blank | 15 comment | 11 complexity | f9698b54191d341a834564d6e2738ece MD5 | raw file
  1/*
  2 * socket.d
  3 *
  4 * This Scaffold holds the Socket implementations for the Linux platform
  5 *
  6 * Author: Dave Wilkinson
  7 *
  8 */
  9
 10module scaffold.socket;
 11
 12import platform.vars.socket;
 13
 14import platform.unix.common;
 15
 16import core.string;
 17import core.main;
 18import core.definitions;
 19
 20import io.console;
 21
 22// SOCKET
 23
 24// phobos (in, at least, GDC 0.24) has incorrect addrinfo
 25struct addrinfo_fix {
 26  int		ai_flags;			/* AI_PASSIVE, AI_CANONNAME */
 27  int		ai_family;			/* PF_xxx */
 28  int		ai_socktype;		/* SOCK_xxx */
 29  int		ai_protocol;		/* IPPROTO_xxx for IPv4 and IPv6 */
 30  size_t	ai_addrlen;			/* length of ai_addr */
 31  sockaddr	*ai_addr;	/* binary address */
 32  char		*ai_canonname;		/* canonical name for host */
 33  addrinfo	*ai_next;	/* next structure in linked list */
 34}
 35extern(C) char* gai_strerror(int ecode);
 36
 37bool SocketOpen(ref SocketPlatformVars sockVars, ref string hostname, ref ushort port)
 38{
 39	addrinfo_fix* result;
 40
 41    int error;
 42
 43    addrinfo_fix hints;
 44
 45	hints.ai_family = AF_UNSPEC;
 46    hints.ai_protocol = IPPROTO_TCP;
 47    hints.ai_socktype = SOCK_STREAM;
 48
 49	// make C style strings
 50	string portstr = toStr(port) ~ '\0';
 51	hostname = hostname.dup ~ '\0';
 52
 53	error = getaddrinfo( hostname.ptr, portstr.ptr, cast(addrinfo*)&hints, cast(addrinfo**)&result );
 54
 55	if ( 0 != error )
 56	{
 57		// Error Connecting
 58		Console.putln("getaddrinfo, error", portstr.length, ",",portstr);
 59		//printf("%s\n", gai_strerror(error));
 60		return false;
 61    }
 62
 63	sockVars.m_skt = socket(result.ai_family, result.ai_socktype, result.ai_protocol);
 64
 65	if (sockVars.m_skt == -1)
 66	{
 67		//file an error event
 68		Console.putln("socket, error");
 69		return false;
 70	}
 71
 72	int iResult = connect(sockVars.m_skt, result.ai_addr, result.ai_addrlen);
 73	if (iResult == -1)
 74	{
 75		//file an error event
 76		close(sockVars.m_skt);
 77		sockVars.m_skt = 0;
 78		Console.putln("connect, error");
 79
 80		return false;
 81	}
 82
 83	Console.putln("connected");
 84
 85	return true;
 86}
 87
 88bool SocketBind(ref SocketPlatformVars sockVars, ref ushort port)
 89{
 90	return false;
 91}
 92
 93bool SocketListen(ref SocketPlatformVars sockVars)
 94{
 95	return false;
 96}
 97
 98bool SocketAccept(ref SocketPlatformVars sockVars)
 99{
100	return false;
101}
102
103void SocketClose(ref SocketPlatformVars sockVars)
104{
105	shutdown(sockVars.m_skt, 2);
106	close(sockVars.m_skt);
107}
108
109bool SocketRead(ref SocketPlatformVars sockVars, ubyte* buffer, ulong len)
110{
111	ulong progress = 0;
112	ulong ret = 0;
113	ulong amt = len;
114
115	int cur_amt;
116
117	ubyte* cur = buffer;
118
119	while (progress < len)
120	{
121		cur_amt = cast(int)(amt & 0x7FFFFFFF);
122		ret = recv(sockVars.m_skt, cur, cur_amt, 0);
123
124		if (ret <= 0) { return false; }
125
126		progress += ret;
127		amt -= ret;
128		cur += ret;
129	}
130
131	return true;
132}
133
134ulong SocketReadAvailable(ref SocketPlatformVars sockVars, ubyte* buffer, ulong len)
135{
136	int cur_amt = cast(int)(len & 0x7FFFFFFF);
137	ulong ret = recv(sockVars.m_skt, buffer, cur_amt, 0);
138
139	return ret;
140}
141
142bool SocketWrite(ref SocketPlatformVars sockVars, ubyte* buffer, ulong len)
143{
144	ulong progress = 0;
145	ulong ret = 0;
146	ulong amt = len;
147
148	int cur_amt;
149
150	ubyte* cur = buffer;
151
152	while (progress < len)
153	{
154		cur_amt = cast(int)(amt & 0x7FFFFFFF);
155
156		ret = send(sockVars.m_skt, cur, cur_amt, 0);
157
158		if (ret <= 0) { return false; }
159
160		progress += ret;
161		amt -= ret;
162		cur += ret;
163
164		if (ret <= 0) { return false; }
165	}
166
167	return true;
168}
169