Example #1
0
static void
readFromChannel(TConn *       const connectionP,
                bool *        const eofP,
                const char ** const errorP) {
/*----------------------------------------------------------------------------
   Read some data from the channel of Connection *connectionP.

   Iff there is none available to read, return *eofP == true.
-----------------------------------------------------------------------------*/
    uint32_t bytesRead;
    bool readError;

    ChannelRead(connectionP->channelP,
                connectionP->buffer.b + connectionP->buffersize,
                bufferSpace(connectionP) - 1,
                &bytesRead, &readError);

    if (readError)
        xmlrpc_asprintf(errorP, "Error reading from channel");
    else {
        *errorP = NULL;
        if (bytesRead > 0) {
            *eofP = FALSE;
            traceChannelRead(connectionP, bytesRead);
            connectionP->inbytes += bytesRead;
            connectionP->buffersize += bytesRead;
            connectionP->buffer.t[connectionP->buffersize] = '\0';
        } else
            *eofP = TRUE;
    }
}
Example #2
0
/*
 * read specified amount of bytes from given desc/offset to buffer
 * return amount of read bytes or negative error code if call failed
 */
static int32_t ZVMReadHandle(struct NaClApp *nap,
    int ch, char *buffer, int32_t size, int64_t offset)
{
  struct ChannelDesc *channel;
  int64_t tail;
  char *sys_buffer;

  assert(nap != NULL);
  assert(nap->manifest != NULL);
  assert(nap->manifest->channels != NULL);

  /* check the channel number */
  if(ch < 0 || ch >= nap->manifest->channels->len)
  {
    ZLOGS(LOG_DEBUG, "channel_id=%d, buffer=%p, size=%d, offset=%ld",
        ch, buffer, size, offset);
    return -EINVAL;
  }
  channel = CH_CH(nap->manifest, ch);
  ZLOGS(LOG_INSANE, "channel %s, buffer=%p, size=%d, offset=%ld",
      channel->alias, buffer, size, offset);

  /* check buffer and convert address */
  if(CheckRAMAccess(nap, (uintptr_t)buffer, size, PROT_WRITE) == -1) return -EINVAL;
  sys_buffer = (char*)NaClUserToSys(nap, (uintptr_t)buffer);

  /* ignore user offset for sequential access read */
  if(CH_SEQ_READABLE(channel))
    offset = channel->getpos;
  else
  /* prevent reading beyond the end of the random access channels */
    size = MIN(channel->size - offset, size);

  /* check arguments sanity */
  if(size == 0) return 0; /* success. user has read 0 bytes */
  if(size < 0) return -EFAULT;
  if(offset < 0) return -EINVAL;

  /* check for eof */
  if(channel->eof) return 0;

  /* check limits */
  if(channel->counters[GetsLimit] >= channel->limits[GetsLimit])
    return -EDQUOT;
  if(CH_RND_READABLE(channel))
    if(offset >= channel->limits[PutSizeLimit] - channel->counters[PutSizeLimit]
      + channel->size) return -EINVAL;

  /* calculate i/o leftovers */
  tail = channel->limits[GetSizeLimit] - channel->counters[GetSizeLimit];
  if(size > tail) size = tail;
  if(size < 1) return -EDQUOT;

  /* read data */
  return ChannelRead(channel, sys_buffer, (size_t)size, (off_t)offset);
}