Esempio n. 1
0
/* write data to the UDP socket s from buf for at most bufSize bytes.
 * answer the number of bytes actually written.
 */ 
sqInt sqSockettoHostportSendDataBufCount(SocketPtr s, sqInt address, sqInt port, char *buf, sqInt bufSize)
{
  if (socketValid(s) && (TCPSocketType != s->socketType))
    {
      struct sockaddr_in saddr;

      FPRINTF((stderr, "sendTo(%d)\n", SOCKET(s)));
      memset(&saddr, 0, sizeof(saddr));
      saddr.sin_family= AF_INET;
      saddr.sin_port= htons((short)port);
      saddr.sin_addr.s_addr= htonl(address);
      {
	int nsent= sendto(SOCKET(s), buf, bufSize, 0, (struct sockaddr *)&saddr, sizeof(saddr));
	if (nsent >= 0)
	  return nsent;
	
	if (errno == EWOULDBLOCK)	/* asynchronous write in progress */
	  return 0;
	FPRINTF((stderr, "UDP send failed\n"));
	SOCKETERROR(s)= errno;
      }
    }
  interpreterProxy->success(false);
  return 0;
}
Esempio n. 2
0
File: IoSocket.c Progetto: BMeph/io
IoObject *IoSocket_asyncStreamRead(IoSocket *self, IoObject *locals, IoMessage *m)
{
	/*doc Socket asyncStreamRead(aSeq, readSize) 
	Reads up to readSize number of bytes into aSeq if data is available. 
	Returns self immediately if successful. Returns an error object on Error. Returns nil if the socket is disconnected.
	*/
	
	IoSeq *bufferSeq = IoMessage_locals_mutableSeqArgAt_(m, locals, 0);
	UArray *buffer = IoSeq_rawUArray(bufferSeq);
	size_t readSize = IoMessage_locals_intArgAt_(m, locals, 1);

	if (Socket_streamRead(SOCKET(self), buffer, readSize))
	{
		return self;
	}

	if (Socket_asyncFailed())
	{
		IoSocket_close(self, locals, m);
		return SOCKETERROR("Socket stream read failed");
	}

	//if (readSize == 0) //SocketErrorStatus() == 0)
	if (SocketErrorStatus() == 0)
	{
		// 0 bytes means the other end disconnected
		//printf("SocketErrorStatus() == 0, closing\n");
		IoSocket_close(self, locals, m);
	}
	
	return IONIL(self);
}
Esempio n. 3
0
File: IoSocket.c Progetto: BMeph/io
IoObject *IoSocket_asyncUdpRead(IoSocket *self, IoObject *locals, IoMessage *m)
{
	/*doc Socket asyncUdpRead(ipAddress, aSeq, readSize) 
	Reads up to readSize number of bytes from ipAddress into aSeq if data is available. 
	Returns self immediately if successful. Returns an error object on Error. Returns nil if the socket is disconnected.
	*/
	
	IoObject *address = IoMessage_locals_addressArgAt_(m, locals, 0);
	UArray *buffer = IoSeq_rawUArray(IoMessage_locals_mutableSeqArgAt_(m, locals, 1));
	size_t readSize = IoMessage_locals_sizetArgAt_(m, locals, 2);
	
	if (Socket_udpRead(SOCKET(self), IoSocket_rawAddressFrom_(address), buffer, readSize))
	{
		return self;
	}
	else
	{
		if (Socket_asyncFailed())
		{
			return SOCKETERROR("Socket udp read failed");
		}
		else
		{
			return IONIL(self);
		}
	}
}
Esempio n. 4
0
/* read data from the UDP socket s into buf for at most bufSize bytes.
   answer the number of bytes actually read.
*/ 
sqInt sqSocketReceiveUDPDataBufCountaddressportmoreFlag(SocketPtr s, char *buf, sqInt bufSize,  sqInt *address,  sqInt *port, sqInt *moreFlag)
{
  if (socketValid(s) && (TCPSocketType != s->socketType))
    {
      struct sockaddr_in saddr;
      socklen_t addrSize= sizeof(saddr);

      FPRINTF((stderr, "recvFrom(%d)\n", SOCKET(s)));
      memset(&saddr, 0, sizeof(saddr));
      { 
	int nread= recvfrom(SOCKET(s), buf, bufSize, 0, (struct sockaddr *)&saddr, &addrSize);
	if (nread >= 0)
	  {
	    *address= ntohl(saddr.sin_addr.s_addr);
	    *port= ntohs(saddr.sin_port);
	    return nread;
	  }
	if (errno == EWOULDBLOCK)	/* asynchronous read in progress */
	  return 0;
	SOCKETERROR(s)= errno;
	FPRINTF((stderr, "receiveData(%d)= %da\n", SOCKET(s), 0));
      }
    }
  interpreterProxy->success(false);
  return 0;
}
Esempio n. 5
0
File: IoSocket.c Progetto: BMeph/io
IoObject *IoSocket_asyncAccept(IoSocket *self, IoObject *locals, IoMessage *m)
{
	//doc Socket asyncAccept(addressObject) Immediately returns a socket for a connection if one is available or nil otherwise. Returns an Error object on error.

	IoObject *address = IoMessage_locals_addressArgAt_(m, locals, 0);
	Socket *socket = Socket_accept(SOCKET(self), IoSocket_rawAddressFrom_(address));

	if (socket)
	{
		IoObject *newSocket = IoSocket_newWithSocket_(IOSTATE, socket);
		newSocket = IoObject_initClone_(self, locals, m, newSocket);
		return IoSocket_rawSetupEvents(newSocket, locals, m);
	}
	else
	{
		if (Socket_asyncFailed())
		{
			return SOCKETERROR("Socket accept failed");
		}
		else
		{
			return IONIL(self);
		}
	}
}
Esempio n. 6
0
/* write data to the socket s from buf for at most bufSize bytes.
   answer the number of bytes actually written.
*/ 
sqInt sqSocketSendDataBufCount(SocketPtr s, char *buf, sqInt bufSize)
{
  int nsent= 0;

  if (!socketValid(s))
    return -1;

  if (TCPSocketType != s->socketType)
    {
      /* --- UDP/RAW --- */
      FPRINTF((stderr, "UDP sendData(%d, %d)\n", SOCKET(s), bufSize));
      if ((nsent= sendto(SOCKET(s), buf, bufSize, 0, (struct sockaddr *)&SOCKETPEER(s), sizeof(SOCKETPEER(s)))) <= 0)
	{
	  if (errno == EWOULDBLOCK)	/* asynchronous write in progress */
	    return 0;
	  FPRINTF((stderr, "UDP send failed\n"));
	  SOCKETERROR(s)= errno;
	  return 0;
	}
    }
  else
    {
      /* --- TCP --- */
      FPRINTF((stderr, "TCP sendData(%d, %d)\n", SOCKET(s), bufSize));
      if ((nsent= write(SOCKET(s), buf, bufSize)) <= 0)
	{
	  if ((nsent == -1) && (errno == EWOULDBLOCK))
	    {
	      FPRINTF((stderr, "TCP sendData(%d, %d) -> %d [blocked]",
		       SOCKET(s), bufSize, nsent));
	      return 0;
	    }
	  else
	    {
	      /* error: most likely "connection closed by peer" */
	      SOCKETSTATE(s)= OtherEndClosed;
	      SOCKETERROR(s)= errno;
	      FPRINTF((stderr, "TCP write failed -> %d", errno));
	      return 0;
	    }
	}
    }
  /* write completed synchronously */
  FPRINTF((stderr, "sendData(%d) done = %d\n", SOCKET(s), nsent));
  return nsent;
}
Esempio n. 7
0
/* read data from the socket s into buf for at most bufSize bytes.
   answer the number actually read.  For UDP, fill in the peer's address
   with the approriate value.
*/
sqInt sqSocketReceiveDataBufCount(SocketPtr s, char *buf, sqInt bufSize)
{
  int nread= 0;

  if (!socketValid(s))
    return -1;
  if (TCPSocketType != s->socketType)
    {
      /* --- UDP/RAW --- */
      socklen_t addrSize= sizeof(SOCKETPEER(s));
      if ((nread= recvfrom(SOCKET(s), buf, bufSize, 0, (struct sockaddr *)&SOCKETPEER(s), &addrSize)) <= 0)
	{
	  if ((nread == -1) && (errno == EWOULDBLOCK))
	    {
	      FPRINTF((stderr, "UDP receiveData(%d) < 1 [blocked]\n", SOCKET(s)));
	      return 0;
	    }
	  SOCKETERROR(s)= errno;
	  FPRINTF((stderr, "UDP receiveData(%d) < 1 [a:%d]\n", SOCKET(s), errno));
	  return 0;
	}
    }
  else
    {
      /* --- TCP --- */
      if ((nread= read(SOCKET(s), buf, bufSize)) <= 0)
	{
	  if ((nread == -1) && (errno == EWOULDBLOCK))
	    {
	      FPRINTF((stderr, "TCP receiveData(%d) < 1 [blocked]\n", SOCKET(s)));
	      return 0;
	    }
	  /* connection reset */
	  SOCKETSTATE(s)= OtherEndClosed;
	  SOCKETERROR(s)= errno;
	  FPRINTF((stderr, "TCP receiveData(%d) < 1 [b:%d]\n", SOCKET(s), errno));
	  notify(PSP(s), CONN_NOTIFY);
	  return 0;
	}
    }
  /* read completed synchronously */
  FPRINTF((stderr, "receiveData(%d) done = %d\n", SOCKET(s), nread));
  return nread;
}
Esempio n. 8
0
/* TCP => open a connection.
 * UDP => set remote address.
 */
void sqSocketConnectToPort(SocketPtr s, sqInt addr, sqInt port)
{
  struct sockaddr_in saddr;

  if (!socketValid(s))
    return;
  FPRINTF((stderr, "connectTo(%d)\n", SOCKET(s)));
  memset(&saddr, 0, sizeof(saddr));
  saddr.sin_family= AF_INET;
  saddr.sin_port= htons((short)port);
  saddr.sin_addr.s_addr= htonl(addr);
  if (TCPSocketType != s->socketType)
    {
      /* --- UDP/RAW --- */
      if (SOCKET(s) >= 0)
	{
	  memcpy((void *)&SOCKETPEER(s), (void *)&saddr, sizeof(SOCKETPEER(s)));
	  SOCKETSTATE(s)= Connected;
	}
    }
  else
    {
      /* --- TCP --- */
      int result;
      aioEnable(SOCKET(s), PSP(s), 0);
      result= connect(SOCKET(s), (struct sockaddr *)&saddr, sizeof(saddr));
      FPRINTF((stderr, "connect() => %d\n", result));
      if (result == 0)
	{
	  /* connection completed synchronously */
	  SOCKETSTATE(s)= Connected;
	  notify(PSP(s), CONN_NOTIFY);
	  setLinger(SOCKET(s), 1);
	}
      else
	{
	  if (errno == EINPROGRESS || errno == EWOULDBLOCK)
	    {
	      /* asynchronous connection in progress */
	      SOCKETSTATE(s)= WaitingForConnection;
	      aioHandle(SOCKET(s), connectHandler, AIO_WX);  /* W => connect() */
	    }
	  else
	    {
	      /* connection error */
	      perror("sqConnectToPort");
	      SOCKETSTATE(s)= Unconnected;
	      SOCKETERROR(s)= errno;
	      notify(PSP(s), CONN_NOTIFY);
	    }
	}
    }
}
Esempio n. 9
0
File: IoSocket.c Progetto: BMeph/io
IoObject *IoSocket_asyncListen(IoSocket *self, IoObject *locals, IoMessage *m)
{
	//doc Socket asyncListen Listens to the socket and returns self immediately or an Error object on error.
	
	if (Socket_listen(SOCKET(self)))
	{
		return self;
	}
	else
	{
		return SOCKETERROR("Socket listen failed");
	}
}
Esempio n. 10
0
File: IoSocket.c Progetto: BMeph/io
IoObject *IoSocket_asyncUdpWrite(IoSocket *self, IoObject *locals, IoMessage *m)
{
	/*doc Socket asyncUdpWrite(ipAddress, aSeq, startIndex, readSize) 
	Writes readsize bytes from aSeq starting at startIndex to ipAddress. 
	Returns self immediately if successful. Returns an error object on Error. Returns nil if the socket is disconnected.
	*/
	
	IoObject *address = IoMessage_locals_addressArgAt_(m, locals, 0);
	UArray *buffer = IoSeq_rawUArray(IoMessage_locals_seqArgAt_(m, locals, 1));
	size_t start = IoMessage_locals_intArgAt_(m, locals, 2);
	size_t writeSize = IoMessage_locals_intArgAt_(m, locals, 3);
	size_t bytesWritten = Socket_udpWrite(SOCKET(self), IoSocket_rawAddressFrom_(address), buffer, start, writeSize);
	
	if (bytesWritten)
	{
		if (bytesWritten < writeSize)
		{
			return SOCKETERROR("Socket udp write failed");
		}
		else
		{
			UArray_removeRange(buffer, start, bytesWritten);
			return self;
		}
	}
	else
	{
		if (Socket_asyncFailed())
		{
			return SOCKETERROR("Socket udp write failed");
		}
		else
		{
			return IONIL(self);
		}
	}
}
Esempio n. 11
0
File: IoSocket.c Progetto: BMeph/io
IoObject *IoSocket_asyncBind(IoSocket *self, IoObject *locals, IoMessage *m)
{
	//doc Socket asyncBind Binds the socket and returns self immediately or an Error object on error.

	IoObject *address = IoMessage_locals_addressArgAt_(m, locals, 0);

	if (Socket_bind(SOCKET(self), IoSocket_rawAddressFrom_(address)))
	{
		return self;
	}
	else
	{
		return SOCKETERROR("Failed to bind socket");
	}
}
Esempio n. 12
0
File: IoSocket.c Progetto: BMeph/io
IoObject *IoSocket_asyncUdpOpen(IoSocket *self, IoObject *locals, IoMessage *m)
{
	//doc Socket asyncUdpOpen Submits an async request to open the socket in UDP mode and returns self immediately or an Error object on error.
	
	Socket *socket = SOCKET(self);

	if (Socket_udpOpen(socket) && Socket_isOpen(socket) && Socket_makeReusable(socket) && Socket_makeAsync(socket))
	{
		IoSocket_rawSetupEvents(self, locals, m);
		return self;
	}
	else
	{
		return SOCKETERROR("Failed to create udp socket");
	}
}
Esempio n. 13
0
File: IoSocket.c Progetto: BMeph/io
IoObject *IoSocket_fromFd(IoSocket *self, IoObject *locals, IoMessage *m)
{
	//doc Socket fromFd(descriptorId, addressFamily) Creates a new Socket with the low-level file descriptor (fd) set to descriptorId and it's address family (AF_INET or AF_UNIX) set to addressFamily.

	Socket *newSocketData = NULL;
	IoObject *newSocket = IoState_doCString_(IOSTATE, "Socket clone");
	
	newSocketData = SOCKET(newSocket);
	newSocketData->fd = IoMessage_locals_intArgAt_(m, locals, 0);
	newSocketData->af = IoMessage_locals_intArgAt_(m, locals, 1);
	
	if(Socket_makeReusable(newSocketData) && Socket_makeAsync(newSocketData)) {
		IoSocket_rawSetupEvents(newSocket, locals, m);
		return newSocket;
	}
	else {
		return SOCKETERROR("Failed to create socket from existing fd");
	}
}
Esempio n. 14
0
File: IoSocket.c Progetto: BMeph/io
IoObject *IoSocket_close(IoSocket *self, IoObject *locals, IoMessage *m)
{
	//doc Socket close Closes the socket and returns self. Returns nil on error.
	
	if (Socket_close(SOCKET(self)))
	{
		IoSocket_rawSetupEvents(self, locals, m);
		return self;
	}
	else
	{
		if (Socket_closeFailed())
		{
			return SOCKETERROR("Failed to close socket");
		}
		else
		{
			return IONIL(self);
		}
	}
}
Esempio n. 15
0
File: IoSocket.c Progetto: BMeph/io
IoObject *IoSocket_asyncConnect(IoSocket *self, IoObject *locals, IoMessage *m)
{
	//doc Socket asyncConnect(addressObject) Connects to the given Address and returns self or an Error object on error.
	
	IoObject *address = IoMessage_locals_addressArgAt_(m, locals, 0);
	
	if (Socket_connectTo(SOCKET(self), IoSocket_rawAddressFrom_(address)))
	{
		return self;
	}
	else
	{
		if (Socket_connectToFailed())
		{
			return SOCKETERROR("Socket connect failed");
		}
		else
		{
			return IONIL(self);
		}
	}
}
Esempio n. 16
0
void sqSocketCloseConnection(SocketPtr s)
{
  int result= 0;

  if (!socketValid(s))
    return;

  FPRINTF((stderr, "closeConnection(%d)\n", SOCKET(s)));

  if (SOCKET(s) < 0)
    return;	/* already closed */

  aioDisable(SOCKET(s));
  SOCKETSTATE(s)= ThisEndClosed;
  result= close(SOCKET(s));
  if ((result == -1) && (errno != EWOULDBLOCK))
    {
      /* error */
      SOCKETSTATE(s)= Unconnected;
      SOCKETERROR(s)= errno;
      notify(PSP(s), CONN_NOTIFY);
      perror("closeConnection");
    }
  else if (0 == result)
    {
      /* close completed synchronously */
      SOCKETSTATE(s)= Unconnected;
      FPRINTF((stderr, "closeConnection: disconnected\n"));
      SOCKET(s)= -1;
    }
  else
    {
      /* asynchronous close in progress */
      SOCKETSTATE(s)= ThisEndClosed;
      aioHandle(SOCKET(s), closeHandler, AIO_RWX);  /* => close() done */
      FPRINTF((stderr, "closeConnection: deferred [aioHandle is set]\n"));
    }
}
Esempio n. 17
0
File: IoSocket.c Progetto: BMeph/io
IoObject *IoSocket_asyncStreamWrite(IoSocket *self, IoObject *locals, IoMessage *m)
{
	/*doc Socket asyncStreamWrite(aSeq, start, writeSize) 
	Writes the slice of aSeq from start to start + writeSize to the socket.
	Returns self immediately if successful, otherwise closes the socket. 
	Returns an error object on Error. 
	Returns nil if the socket is disconnected.
	*/
	
	IoSeq *bufferSeq = IoMessage_locals_seqArgAt_(m, locals, 0);
	UArray *buffer = IoSeq_rawUArray(bufferSeq);
	size_t start = IoMessage_locals_intArgAt_(m, locals, 1);
	size_t writeSize = IoMessage_locals_intArgAt_(m, locals, 2);
	size_t bytesWritten = Socket_streamWrite(SOCKET(self), buffer, start, writeSize);
	
	if (bytesWritten)
	{
		UArray_removeRange(buffer, start, bytesWritten);
		return self;
	}
	else
	{
		if (Socket_asyncFailed())
		{
			IoSocket_close(self, locals, m);
			return SOCKETERROR("Socket stream write failed");
		}
		else
		{
			int errorNumber = SocketErrorStatus();
			
			if (errorNumber == ECONNRESET) IoSocket_close(self, locals, m);
			return IONIL(self);
		}
	}
}
Esempio n. 18
0
sqInt sqSocketError(SocketPtr s)
{
  if (!socketValid(s))
    return -1;
  return SOCKETERROR(s);
}