xref: /haiku/src/kits/network/libnetapi/Socket.cpp (revision 0dc3ab4f3764a91764b6f5e9938a11f21e1ace38)
10e478f5aSAxel Dörfler /*
20e478f5aSAxel Dörfler  * Copyright 2011, Axel Dörfler, axeld@pinc-software.de.
3c9dd7d0dSRene Gollent  * Copyright 2016, Rene Gollent, rene@gollent.com.
40e478f5aSAxel Dörfler  * Distributed under the terms of the MIT License.
50e478f5aSAxel Dörfler  */
60e478f5aSAxel Dörfler 
70e478f5aSAxel Dörfler 
80e478f5aSAxel Dörfler #include <Socket.h>
90e478f5aSAxel Dörfler 
10*0dc3ab4fSAugustin Cavalier #include <errno.h>
110e478f5aSAxel Dörfler 
120e478f5aSAxel Dörfler //#define TRACE_SOCKET
130e478f5aSAxel Dörfler #ifdef TRACE_SOCKET
140e478f5aSAxel Dörfler #	define TRACE(x...) printf(x)
150e478f5aSAxel Dörfler #else
160e478f5aSAxel Dörfler #	define TRACE(x...) ;
170e478f5aSAxel Dörfler #endif
180e478f5aSAxel Dörfler 
190e478f5aSAxel Dörfler 
200e478f5aSAxel Dörfler BSocket::BSocket()
210e478f5aSAxel Dörfler {
220e478f5aSAxel Dörfler }
230e478f5aSAxel Dörfler 
240e478f5aSAxel Dörfler 
250e478f5aSAxel Dörfler BSocket::BSocket(const BNetworkAddress& peer, bigtime_t timeout)
260e478f5aSAxel Dörfler {
270e478f5aSAxel Dörfler 	Connect(peer, timeout);
280e478f5aSAxel Dörfler }
290e478f5aSAxel Dörfler 
300e478f5aSAxel Dörfler 
310e478f5aSAxel Dörfler BSocket::BSocket(const BSocket& other)
320e478f5aSAxel Dörfler 	:
330e478f5aSAxel Dörfler 	BAbstractSocket(other)
340e478f5aSAxel Dörfler {
350e478f5aSAxel Dörfler }
360e478f5aSAxel Dörfler 
370e478f5aSAxel Dörfler 
380e478f5aSAxel Dörfler BSocket::~BSocket()
390e478f5aSAxel Dörfler {
400e478f5aSAxel Dörfler }
410e478f5aSAxel Dörfler 
420e478f5aSAxel Dörfler 
430e478f5aSAxel Dörfler status_t
44c9dd7d0dSRene Gollent BSocket::Bind(const BNetworkAddress& local, bool reuseAddr)
450e478f5aSAxel Dörfler {
46c9dd7d0dSRene Gollent 	return BAbstractSocket::Bind(local, SOCK_STREAM, reuseAddr);
470e478f5aSAxel Dörfler }
480e478f5aSAxel Dörfler 
490e478f5aSAxel Dörfler 
500e478f5aSAxel Dörfler status_t
510e478f5aSAxel Dörfler BSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout)
520e478f5aSAxel Dörfler {
530e478f5aSAxel Dörfler 	return BAbstractSocket::Connect(peer, SOCK_STREAM, timeout);
540e478f5aSAxel Dörfler }
550e478f5aSAxel Dörfler 
560e478f5aSAxel Dörfler 
57c9dd7d0dSRene Gollent status_t
58c9dd7d0dSRene Gollent BSocket::Accept(BAbstractSocket*& _socket)
59c9dd7d0dSRene Gollent {
60c9dd7d0dSRene Gollent 	int fd = -1;
61c9dd7d0dSRene Gollent 	BNetworkAddress peer;
62c9dd7d0dSRene Gollent 	status_t error = AcceptNext(fd, peer);
63c9dd7d0dSRene Gollent 	if (error != B_OK)
64c9dd7d0dSRene Gollent 		return error;
65c9dd7d0dSRene Gollent 	BSocket* socket = new(std::nothrow) BSocket();
66c9dd7d0dSRene Gollent 	if (socket == NULL) {
67c9dd7d0dSRene Gollent 		close(fd);
68c9dd7d0dSRene Gollent 		return B_NO_MEMORY;
69c9dd7d0dSRene Gollent 	}
70c9dd7d0dSRene Gollent 
71c9dd7d0dSRene Gollent 	socket->_SetTo(fd, fLocal, peer);
72c9dd7d0dSRene Gollent 	_socket = socket;
73c9dd7d0dSRene Gollent 	return B_OK;
74c9dd7d0dSRene Gollent }
75c9dd7d0dSRene Gollent 
76c9dd7d0dSRene Gollent 
770e478f5aSAxel Dörfler //	#pragma mark - BDataIO implementation
780e478f5aSAxel Dörfler 
790e478f5aSAxel Dörfler 
800e478f5aSAxel Dörfler ssize_t
810e478f5aSAxel Dörfler BSocket::Read(void* buffer, size_t size)
820e478f5aSAxel Dörfler {
830e478f5aSAxel Dörfler 	ssize_t bytesReceived = recv(Socket(), buffer, size, 0);
840e478f5aSAxel Dörfler 	if (bytesReceived < 0) {
850e478f5aSAxel Dörfler 		TRACE("%p: BSocket::Read() error: %s\n", this, strerror(errno));
860e478f5aSAxel Dörfler 		return errno;
870e478f5aSAxel Dörfler 	}
880e478f5aSAxel Dörfler 
890e478f5aSAxel Dörfler 	return bytesReceived;
900e478f5aSAxel Dörfler }
910e478f5aSAxel Dörfler 
920e478f5aSAxel Dörfler 
930e478f5aSAxel Dörfler ssize_t
940e478f5aSAxel Dörfler BSocket::Write(const void* buffer, size_t size)
950e478f5aSAxel Dörfler {
960e478f5aSAxel Dörfler 	ssize_t bytesSent = send(Socket(), buffer, size, 0);
970e478f5aSAxel Dörfler 	if (bytesSent < 0) {
980e478f5aSAxel Dörfler 		TRACE("%p: BSocket::Write() error: %s\n", this, strerror(errno));
990e478f5aSAxel Dörfler 		return errno;
1000e478f5aSAxel Dörfler 	}
1010e478f5aSAxel Dörfler 
1020e478f5aSAxel Dörfler 	return bytesSent;
1030e478f5aSAxel Dörfler }
1040e478f5aSAxel Dörfler 
1050e478f5aSAxel Dörfler 
1060e478f5aSAxel Dörfler //	#pragma mark - private
1070e478f5aSAxel Dörfler 
1080e478f5aSAxel Dörfler 
1090e478f5aSAxel Dörfler void
1100e478f5aSAxel Dörfler BSocket::_SetTo(int fd, const BNetworkAddress& local,
1110e478f5aSAxel Dörfler 	const BNetworkAddress& peer)
1120e478f5aSAxel Dörfler {
1130e478f5aSAxel Dörfler 	Disconnect();
1140e478f5aSAxel Dörfler 
1150e478f5aSAxel Dörfler 	fInitStatus = B_OK;
1160e478f5aSAxel Dörfler 	fSocket = fd;
1170e478f5aSAxel Dörfler 	fLocal = local;
1180e478f5aSAxel Dörfler 	fPeer = peer;
119c9dd7d0dSRene Gollent 	fIsConnected = true;
1200e478f5aSAxel Dörfler 
1210e478f5aSAxel Dörfler 	TRACE("%p: accepted from %s to %s\n", this, local.ToString().c_str(),
1220e478f5aSAxel Dörfler 		peer.ToString().c_str());
1230e478f5aSAxel Dörfler }
124