Ejemplo n.º 1
0
/* Read all available data from the stream and empty the read buffer. */
int tio_skipall(TFILE *fp, int timeout)
{
  struct timespec deadline = {0, 0};
  int rv;
  size_t len;
  /* clear the read buffer */
  fp->readbuffer.start = 0;
  fp->readbuffer.len = 0;
  fp->read_resettable = 0;
  /* read until we can't read no more */
  len = fp->readbuffer.size;
#ifdef SSIZE_MAX
  if (len > SSIZE_MAX)
    len = SSIZE_MAX;
#endif /* SSIZE_MAX */
  while (1)
  {
    /* wait until we have input */
    if (tio_wait(fp->fd, POLLIN, timeout, &deadline))
      return -1;
    /* read data from the stream */
    rv = read(fp->fd, fp->readbuffer.buffer, len);
    if (rv == 0)
      return 0; /* end-of-file */
    if ((rv < 0) && (errno == EWOULDBLOCK))
      return 0; /* we've ready everything we can without blocking */
    if ((rv < 0) && (errno != EINTR) && (errno != EAGAIN))
      return -1; /* something went wrong with the read */
  }
}
Ejemplo n.º 2
0
/* write all the data in the buffer to the stream */
int tio_flush(TFILE *fp)
{
  struct timespec deadline = {0, 0};
  /* loop until we have written our buffer */
  while (fp->writebuffer.len > 0)
  {
    /* wait until we can write */
    if (tio_wait(fp->fd, POLLOUT, fp->writetimeout, &deadline))
      return -1;
    /* write one block */
    if (tio_writebuf(fp))
      return -1;
  }
  return 0;
}
Ejemplo n.º 3
0
/* write all the data in the buffer to the stream */
int tio_flush(TFILE *fp)
{
  struct timeval deadline;
  /* build a time by which we should be finished */
  tio_get_deadline(&deadline,fp->writetimeout);
  /* loop until we have written our buffer */
  while (fp->writebuffer.len > 0)
  {
    /* wait until we can write */
    if (tio_wait(fp,0,&deadline))
      return -1;
    /* write one block */
    if (tio_writebuf(fp))
      return -1;
  }
  return 0;
}
Ejemplo n.º 4
0
/* do a read on the file descriptor, returning the data in the buffer
   if no data was read in the specified time an error is returned */
int tio_read(TFILE *fp, void *buf, size_t count)
{
  struct timeval deadline;
  int rv;
  uint8_t *tmp;
  size_t newsz;
  size_t len;
  /* have a more convenient storage type for the buffer */
  uint8_t *ptr=(uint8_t *)buf;
  /* build a time by which we should be finished */
  tio_get_deadline(&deadline,fp->readtimeout);
  /* loop until we have returned all the needed data */
  while (1)
  {
    /* check if we have enough data in the buffer */
    if (fp->readbuffer.len >= count)
    {
      if (count>0)
      {
        if (ptr!=NULL)
          memcpy(ptr,fp->readbuffer.buffer+fp->readbuffer.start,count);
        /* adjust buffer position */
        fp->readbuffer.start+=count;
        fp->readbuffer.len-=count;
      }
      return 0;
    }
    /* empty what we have and continue from there */
    if (fp->readbuffer.len>0)
    {
      if (ptr!=NULL)
      {
        memcpy(ptr,fp->readbuffer.buffer+fp->readbuffer.start,fp->readbuffer.len);
        ptr+=fp->readbuffer.len;
      }
      count-=fp->readbuffer.len;
      fp->readbuffer.start+=fp->readbuffer.len;
      fp->readbuffer.len=0;
    }
    /* after this point until the read fp->readbuffer.len is 0 */
    if (!fp->read_resettable)
    {
      /* the stream is not resettable, re-use the buffer */
      fp->readbuffer.start=0;
    }
    else if (fp->readbuffer.start>=(fp->readbuffer.size-4))
    {
      /* buffer is running empty, try to grow buffer */
      if (fp->readbuffer.size<fp->readbuffer.maxsize)
      {
        newsz=fp->readbuffer.size*2;
        if (newsz>fp->readbuffer.maxsize)
          newsz=fp->readbuffer.maxsize;
        tmp=realloc(fp->readbuffer.buffer,newsz);
        if (tmp!=NULL)
        {
          fp->readbuffer.buffer=tmp;
          fp->readbuffer.size=newsz;
        }
      }
      /* if buffer still does not contain enough room, clear resettable */
      if (fp->readbuffer.start>=(fp->readbuffer.size-4))
      {
        fp->readbuffer.start=0;
        fp->read_resettable=0;
      }
    }
    /* wait until we have input */
    if (tio_wait(fp,1,&deadline))
      return -1;
    /* read the input in the buffer */
    len=fp->readbuffer.size-fp->readbuffer.start;
#ifdef SSIZE_MAX
    if (len>SSIZE_MAX)
      len=SSIZE_MAX;
#endif /* SSIZE_MAX */
    rv=read(fp->fd,fp->readbuffer.buffer+fp->readbuffer.start,len);
    /* check for errors */
    if (rv==0)
    {
      errno=ECONNRESET;
      return -1;
    }
    else if ((rv<0)&&(errno!=EINTR)&&(errno!=EAGAIN))
      return -1; /* something went wrong with the read */
    /* skip the read part in the buffer */
    fp->readbuffer.len=rv;
#ifdef DEBUG_TIO_STATS
    fp->bytesread+=rv;
#endif /* DEBUG_TIO_STATS */
  }
}