Exemplo n.º 1
0
int32_t
NamedPipeInfo::DoWrite()
{
  MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
  MOZ_ASSERT(!mHasPendingWrite);
  MOZ_ASSERT(mWriteBegin < mWriteEnd);

  DWORD bytesWritten = 0;
  BOOL success = WriteFile(mPipe,
                           &mWriteBuffer[mWriteBegin],
                           mWriteEnd - mWriteBegin,
                           &bytesWritten,
                           IsNonblocking() ? &mWriteOverlapped : nullptr);

  if (success) {
    mWriteBegin += bytesWritten;
    LOG_NPIO_DEBUG("[%s][%p] %d bytes written", __func__, this, bytesWritten);
    return bytesWritten;
  }

  if (GetLastError() != ERROR_IO_PENDING) {
    LOG_NPIO_ERROR("[%s] WriteFile failed (%d)", __func__, GetLastError());
    Disconnect();
    PR_SetError(PR_IO_ERROR, 0);
    return -1;
  }

  mHasPendingWrite = true;

  return 0;
}
Exemplo n.º 2
0
int32_t
NamedPipeInfo::Write(const void* aBuffer, int32_t aSize)
{
  MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
  MOZ_ASSERT(mWriteBegin <= mWriteEnd);

  if (!IsConnected()) {
    // pipe unconnected
    PR_SetError(PR_NOT_CONNECTED_ERROR, 0);
    return -1;
  }

  if (mWriteBegin == mWriteEnd) {
    mWriteBegin = mWriteEnd = 0;
  }

  int32_t bytesToWrite = std::min<int32_t>(aSize,
                                           sizeof(mWriteBuffer) - mWriteEnd);
  MOZ_ASSERT(bytesToWrite >= 0);

  if (bytesToWrite == 0) {
    PR_SetError(IsNonblocking() ? PR_WOULD_BLOCK_ERROR
                                : PR_IO_PENDING_ERROR,
                0);
    return -1;
  }

  memcpy(&mWriteBuffer[mWriteEnd], aBuffer, bytesToWrite);
  mWriteEnd += bytesToWrite;

  /**
   * Triggers internal write operation by calling |GetPollFlags|.
   * This is required for callers that use blocking I/O because they don't call
   * |GetPollFlags| to write data, but this also works for non-blocking I/O.
   */
  int16_t outFlag;
  GetPollFlags(PR_POLL_WRITE, &outFlag);

  return bytesToWrite;
}
Exemplo n.º 3
0
// @return: data has been read and is available
int32_t
NamedPipeInfo::DoRead()
{
  MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
  MOZ_ASSERT(!mHasPendingRead);
  MOZ_ASSERT(mReadBegin == mReadEnd); // the buffer should be empty

  mReadBegin = 0;
  mReadEnd = 0;

  BOOL success = ReadFile(mPipe,
                          mReadBuffer,
                          sizeof(mReadBuffer),
                          &mReadEnd,
                          IsNonblocking() ? &mReadOverlapped : nullptr);

  if (success) {
    LOG_NPIO_DEBUG("[%s][%p] %d bytes read", __func__, this, mReadEnd);
    return mReadEnd;
  }

  switch (GetLastError()) {
    case ERROR_MORE_DATA:   // has more data to read
      mHasPendingRead = true;
      return DoReadContinue();

    case ERROR_IO_PENDING:  // read is pending
      mHasPendingRead = true;
      break;

    default:
      LOG_NPIO_ERROR("[%s] ReadFile failed (%d)", __func__, GetLastError());
      Disconnect();
      PR_SetError(PR_IO_ERROR, 0);
      return -1;
  }

  return 0;
}
Exemplo n.º 4
0
uint32_t
NamedPipeInfo::Peek(void* aBuffer, int32_t aSize)
{
  MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
  MOZ_ASSERT(mReadBegin <= mReadEnd);

  if (!IsConnected()) {
    // pipe unconnected
    PR_SetError(PR_NOT_CONNECTED_ERROR, 0);
    return -1;
  }

  /**
   * If there's nothing in the read buffer, try to trigger internal read
   * operation by calling |GetPollFlags|. This is required for callers that
   * use blocking I/O because they don't call |GetPollFlags| to read data,
   * but this also works for non-blocking I/O.
   */
  if (!Available()) {
    int16_t outFlag;
    GetPollFlags(PR_POLL_READ, &outFlag);

    if (!(outFlag & PR_POLL_READ)) {
      PR_SetError(IsNonblocking() ? PR_WOULD_BLOCK_ERROR
                                  : PR_IO_PENDING_ERROR,
                  0);
      return -1;
    }
  }

  // Available() can't return more than what fits to the buffer at the read offset.
  int32_t bytesRead = std::min<int32_t>(aSize, Available());
  MOZ_ASSERT(bytesRead >= 0);
  MOZ_ASSERT(mReadBegin + bytesRead <= mReadEnd);
  memcpy(aBuffer, &mReadBuffer[mReadBegin], bytesRead);
  return bytesRead;
}
Exemplo n.º 5
0
//------------------------------------------------------------------------------
//
// ConnectTCP() -
//
//------------------------------------------------------------------------------
bool TDSocket::ConnectTCP(const char *pAddr, i16 nPort)
{
	bool           bRetVal = false;
	struct in_addr stIpAddress;

	//------------------------------------------------------------------
	// Preconnection setup that must be preformed					 
	//------------------------------------------------------------------
	memset(&m_stServerSockaddr, 0, sizeof(m_stServerSockaddr));
	m_stServerSockaddr.sin_family = AF_INET;

	hostent * pHE = NULL;
	if ((pHE = GETHOSTBYNAME(pAddr)) == NULL)
	{
#ifdef WIN32
		TranslateSocketError();
#else
		if (h_errno == HOST_NOT_FOUND)
		{
			SetSocketError(SocketInvalidAddress);
		}
#endif
		return bRetVal;
	}

	memcpy(&stIpAddress, pHE->h_addr_list[0], pHE->h_length);
	m_stServerSockaddr.sin_addr.s_addr = stIpAddress.s_addr;

	if ((i32)m_stServerSockaddr.sin_addr.s_addr == TDSocket::SocketError)
	{
		TranslateSocketError();
		return bRetVal;
	}

	m_stServerSockaddr.sin_port = htons(nPort);

	//------------------------------------------------------------------
	// Connect to address "xxx.xxx.xxx.xxx"	(IPv4) address only.  
	// 
	//------------------------------------------------------------------

	if (connect(m_socket, (struct sockaddr*)&m_stServerSockaddr, sizeof(m_stServerSockaddr)) ==
		TDSocket::SocketError)
	{
		//--------------------------------------------------------------
		// Get error value this might be a non-blocking socket so we 
		// must first check.
		//--------------------------------------------------------------
		TranslateSocketError();

		//--------------------------------------------------------------
		// If the socket is non-blocking and the current socket error
		// is SocketEinprogress or SocketEwouldblock then poll connection 
		// with select for designated timeout period.
		// Linux returns EINPROGRESS and Windows returns WSAEWOULDBLOCK.
		//--------------------------------------------------------------
		if ((IsNonblocking()) &&
			((GetSocketError() == TDSocket::SocketEwouldblock) ||
			(GetSocketError() == TDSocket::SocketEinprogress)))
		{
			bRetVal = Select(GetConnectTimeoutSec(), GetConnectTimeoutUSec());
		}
	}
	else
	{
		TranslateSocketError();
		bRetVal = true;
	}


	return bRetVal;
}