Пример #1
0
static ssize_t ra_neon_body_provider(void *userdata,
                                     char *buffer,
                                     size_t buflen)
{
  body_provider_baton_t *b = userdata;
  svn_ra_neon__request_t *req = b->req;
  apr_file_t *body_file = b->body_file;

  if (req->sess->callbacks &&
      req->sess->callbacks->cancel_func)
    SVN_RA_NEON__REQ_ERR
      (req, (req->sess->callbacks->cancel_func)(req->sess->callback_baton));

  if (req->err)
    return -1;

  svn_pool_clear(req->iterpool);
  if (buflen == 0)
    {
      /* This is the beginning of a new body pull. Rewind the file. */
      apr_off_t offset = 0;
      SVN_RA_NEON__REQ_ERR
        (b->req,
         svn_io_file_seek(body_file, APR_SET, &offset, req->iterpool));
      return (req->err ? -1 : 0);
    }
  else
    {
      apr_size_t nbytes = buflen;
      svn_error_t *err = svn_io_file_read(body_file, buffer, &nbytes,
                                          req->iterpool);
      if (err)
        {
          if (APR_STATUS_IS_EOF(err->apr_err))
            {
              svn_error_clear(err);
              return 0;
            }

          SVN_RA_NEON__REQ_ERR(req, err);
          return -1;
        }
      else
        return nbytes;
    }
}
Пример #2
0
/* Copy FILENAME from SRC_DIR to DST_DIR in byte increments of size
   CHUNKSIZE.  The read/write buffer of size CHUNKSIZE will be
   allocated in POOL.  If ALLOW_MISSING is set, we won't make a fuss
   if FILENAME isn't found in SRC_DIR; otherwise, we will.  */
static svn_error_t *
copy_db_file_safely(const char *src_dir,
                    const char *dst_dir,
                    const char *filename,
                    u_int32_t chunksize,
                    svn_boolean_t allow_missing,
                    apr_pool_t *pool)
{
  apr_file_t *s = NULL, *d = NULL;  /* init to null important for APR */
  const char *file_src_path = svn_dirent_join(src_dir, filename, pool);
  const char *file_dst_path = svn_dirent_join(dst_dir, filename, pool);
  svn_error_t *err;
  char *buf;

  /* Open source file.  If it's missing and that's allowed, there's
     nothing more to do here. */
  err = svn_io_file_open(&s, file_src_path,
                         (APR_READ | APR_LARGEFILE),
                         APR_OS_DEFAULT, pool);
  if (err && APR_STATUS_IS_ENOENT(err->apr_err) && allow_missing)
    {
      svn_error_clear(err);
      return SVN_NO_ERROR;
    }
  SVN_ERR(err);

  /* Open destination file. */
  SVN_ERR(svn_io_file_open(&d, file_dst_path, (APR_WRITE | APR_CREATE |
                                               APR_LARGEFILE),
                           APR_OS_DEFAULT, pool));

  /* Allocate our read/write buffer. */
  buf = apr_palloc(pool, chunksize);

  /* Copy bytes till the cows come home. */
  while (1)
    {
      apr_size_t bytes_this_time = chunksize;
      svn_error_t *read_err, *write_err;

      /* Read 'em. */
      if ((read_err = svn_io_file_read(s, buf, &bytes_this_time, pool)))
        {
          if (APR_STATUS_IS_EOF(read_err->apr_err))
            svn_error_clear(read_err);
          else
            {
              svn_error_clear(svn_io_file_close(s, pool));
              svn_error_clear(svn_io_file_close(d, pool));
              return read_err;
            }
        }

      /* Write 'em. */
      if ((write_err = svn_io_file_write_full(d, buf, bytes_this_time, NULL,
                                              pool)))
        {
          svn_error_clear(svn_io_file_close(s, pool));
          svn_error_clear(svn_io_file_close(d, pool));
          return write_err;
        }

      /* read_err is either NULL, or a dangling pointer - but it is only a
         dangling pointer if it used to be an EOF error. */
      if (read_err)
        {
          SVN_ERR(svn_io_file_close(s, pool));
          SVN_ERR(svn_io_file_close(d, pool));
          break;  /* got EOF on read, all files closed, all done. */
        }
    }

  return SVN_NO_ERROR;
}
Пример #3
0
/* Return a memblock of content, if any is available. *mem will be NULL if
   no further content is available. The memblock should eventually be
   passed to return_buffer() (or stored into buf->out_for_reading which
   will grab that block at the next get_buffer() call). */
static svn_error_t *
read_data(struct memblock_t **mem,
          svn_spillbuf_t *buf,
          apr_pool_t *scratch_pool)
{
  svn_error_t *err;

  /* If we have some in-memory blocks, then return one.  */
  if (buf->head != NULL)
    {
      *mem = buf->head;
      if (buf->tail == *mem)
        buf->head = buf->tail = NULL;
      else
        buf->head = (*mem)->next;

      /* We're using less memory now. If we haven't hit the spill file,
         then we may be able to keep using memory.  */
      buf->memory_size -= (*mem)->size;

      return SVN_NO_ERROR;
    }

  /* No file? Done.  */
  if (buf->spill == NULL)
    {
      *mem = NULL;
      return SVN_NO_ERROR;
    }

  /* Assume that the caller has seeked the spill file to the correct pos.  */

  /* Get a buffer that we can read content into.  */
  *mem = get_buffer(buf);
  /* NOTE: mem's size/next are uninitialized.  */

  if ((apr_uint64_t)buf->spill_size < (apr_uint64_t)buf->blocksize)
    (*mem)->size = (apr_size_t)buf->spill_size;
  else
    (*mem)->size = buf->blocksize;  /* The size of (*mem)->data  */
  (*mem)->next = NULL;

  /* Read some data from the spill file into the memblock.  */
  err = svn_io_file_read(buf->spill, (*mem)->data, &(*mem)->size,
                         scratch_pool);
  if (err)
    {
      return_buffer(buf, *mem);
      return svn_error_trace(err);
    }

  /* Mark the data that we consumed from the spill file.  */
  buf->spill_start += (*mem)->size;

  /* Did we consume all the data from the spill file?  */
  if ((buf->spill_size -= (*mem)->size) == 0)
    {
      /* Close and reset our spill file information.  */
      SVN_ERR(svn_io_file_close(buf->spill, scratch_pool));
      buf->spill = NULL;
      buf->spill_start = 0;
    }

  /* *mem has been initialized. Done.  */
  return SVN_NO_ERROR;
}