Пример #1
0
int ssh_stream_fd_write(void *context, const unsigned char *buf,
			size_t size)
{
  SshFdStream sdata = (SshFdStream)context;
  int len;

  assert(!sdata->destroyed);
  if (sdata->writefd >= 0)
    {
      len = write(sdata->writefd, buf, size);
      if (len >= 0)
	return len;

      if (errno == EAGAIN)
	{
	  /* Cannot write more at this time. */
	  sdata->write_has_failed = TRUE;
	  ssh_stream_fd_request(sdata);
	  return -1;
	}

      /* A real error occurred while writing. */
      sdata->write_has_failed = TRUE;
      ssh_stream_fd_request(sdata);
    }
  return 0;
}
Пример #2
0
int ssh_stream_fd_read(void *context, unsigned char *buf, size_t size)
{
  SshFdStream sdata = (SshFdStream)context;
  int len;

  assert(!sdata->destroyed);
  if (sdata->readfd >= 0)
    {
      len = read(sdata->readfd, buf, size);
      if (len >= 0)
	return len;
      
      if (errno == EAGAIN)
	{
	  /* No more data available at this time. */
	  sdata->read_has_failed = TRUE;
	  ssh_stream_fd_request(sdata);
	  return -1;
	}

      /* A real error occurred while reading. */
      sdata->read_has_failed = TRUE;
      ssh_stream_fd_request(sdata);
    }
  return 0;
}
Пример #3
0
int ssh_stream_fd_write(void *context, const unsigned char *buf, size_t size)
{
  SshFdStream sdata = (SshFdStream)context;
  int len;

  assert(!sdata->destroyed);
  if (sdata->writefd >= 0)
    {
      len = (int)(write(sdata->writefd, buf, size));
      if (len > 0)
        return len;

      /* In NetBSD current (2003/06/10) write() may return 0, and
         the filedescriptor is still valid. */
      if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR ||
          /* Mystical special case. */
          (len == 0 && errno == 0))
        {
          /* Cannot write more at this time. */
          sdata->write_has_failed = TRUE;
          ssh_stream_fd_request(sdata);
          return -1;
        }
      else if (len == 0)
        {
          SSH_DEBUG(4, ("write() returned 0. (and errno does not indicate "
                        "that the fd just couldn't be written at this time)"));
          return 0;
        }
      /* A real error occurred while writing. */
      sdata->write_has_failed = TRUE;
      ssh_stream_fd_request(sdata);
    }
  return 0;
}
Пример #4
0
int ssh_stream_fd_read(void *context, unsigned char *buf, size_t size)
{
  SshFdStream sdata = (SshFdStream)context;
  int len;

  assert(!sdata->destroyed);
  if (sdata->readfd >= 0)
    {
#ifndef VXWORKS
      SSH_HEAVY_DEBUG(99, ("fd %d is %sin non-blocking mode.", sdata->readfd,
                           (fcntl(sdata->readfd, F_GETFL, 0)
                            & (O_NONBLOCK|O_NDELAY)) != 0 ?
                           "" : "not "));
#endif /* VXWORKS */
      len = read(sdata->readfd, buf, size);
      if (len >= 0)
        return len;

      if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
        {
          /* No more data available at this time. */
          sdata->read_has_failed = TRUE;
          ssh_stream_fd_request(sdata);
          return -1;
        }

      /* A real error occurred while reading. */
      sdata->read_has_failed = TRUE;
      ssh_stream_fd_request(sdata);
    }
  return 0;
}
Пример #5
0
void ssh_stream_fd_callback(unsigned int events, void *context)
{
  SshFdStream sdata = (SshFdStream)context;

  /* This might get called by a pending callback, and might have been
     destroyed in the meanwhile.  Thus, we check for destroyed status.
     Note that no such events should come after the generated event that
     actually frees the context. */
  if (sdata->destroyed)
    return;

  /* Convert the event loop callback to a stream callback. */
  if (events & SSH_IO_READ)
    {
      sdata->read_has_failed = FALSE;
      if (sdata->callback)
        (*sdata->callback)(SSH_STREAM_INPUT_AVAILABLE, sdata->context);
    }
  if ((events & SSH_IO_WRITE) && !sdata->destroyed)
    {
      sdata->write_has_failed = FALSE;
      if (sdata->callback)
        (*sdata->callback)(SSH_STREAM_CAN_OUTPUT, sdata->context);
    }

  /* Check if the stream got destroyed in the callbacks. */
  if (sdata->destroyed)
    return;

  /* Recompute the request masks.  Note that the context might have been
     destroyed by one of the earlier callbacks. */
  ssh_stream_fd_request(sdata);
}
Пример #6
0
void ssh_stream_fd_set_callback(void *context, SshStreamCallback callback,
				void *callback_context)
{
  SshFdStream sdata = (SshFdStream)context;

  assert(!sdata->destroyed);
  sdata->callback = callback;
  sdata->context = callback_context;
  sdata->read_has_failed = TRUE;
  sdata->write_has_failed = TRUE;
  ssh_stream_fd_request(sdata);
}
Пример #7
0
void ssh_stream_fd_set_callback(void *context, SshStreamCallback callback,
                                void *callback_context)
{
  SshFdStream sdata = (SshFdStream)context;

  assert(!sdata->destroyed);
  sdata->callback = callback;
  sdata->context = callback_context;
  sdata->read_has_failed = TRUE;
  sdata->write_has_failed = TRUE;
  ssh_stream_fd_request(sdata);
  if (callback != NULL_FNPTR)
    {
      (*callback)(SSH_STREAM_INPUT_AVAILABLE, callback_context);
      /* check that stream was not destroyed in above callback */
      if (!sdata->destroyed)
        (*callback)(SSH_STREAM_CAN_OUTPUT, callback_context);
    }
}