Blame src/buffering_write.c

Packit cb6d3d
/*
Packit cb6d3d
  Copyright (C) 2004, 2008 Rocky Bernstein <rocky@gnu.org>
Packit cb6d3d
  Copyright (C) 1998, 1999 Monty <xiphmont@mit.edu>
Packit cb6d3d
*/
Packit cb6d3d
Packit cb6d3d
/* Eliminate teeny little writes.  patch submitted by 
Packit cb6d3d
   Rob Ross <rbross@parl.ces.clemson.edu> --Monty 19991008 */
Packit cb6d3d
Packit cb6d3d
#include <string.h>
Packit cb6d3d
#include <unistd.h>
Packit cb6d3d
#include <errno.h>
Packit cb6d3d
#include <stdio.h>
Packit cb6d3d
Packit cb6d3d
#define OUTBUFSZ 32*1024
Packit cb6d3d
Packit cb6d3d
#include "utils.h"
Packit cb6d3d
#include "buffering_write.h"
Packit cb6d3d
Packit cb6d3d
Packit cb6d3d
/* GLOBALS FOR BUFFERING CALLS */
Packit cb6d3d
static int  bw_fd  = -1;
Packit cb6d3d
static long bw_pos = 0;
Packit cb6d3d
static char bw_outbuf[OUTBUFSZ];
Packit cb6d3d
Packit cb6d3d
Packit cb6d3d
static long int
Packit cb6d3d
blocking_write(int outf, char *buffer, long num){
Packit cb6d3d
  long int words=0,temp;
Packit cb6d3d
Packit cb6d3d
  while(words
Packit cb6d3d
    temp=write(outf,buffer+words,num-words);
Packit cb6d3d
    if(temp==-1){
Packit cb6d3d
      if(errno!=EINTR && errno!=EAGAIN)
Packit cb6d3d
	return(-1);
Packit cb6d3d
      temp=0;
Packit cb6d3d
    }
Packit cb6d3d
    words+=temp;
Packit cb6d3d
  }
Packit cb6d3d
  return(0);
Packit cb6d3d
}
Packit cb6d3d
Packit cb6d3d
/** buffering_write() - buffers data to a specified size before writing.
Packit cb6d3d
 *
Packit cb6d3d
 * Restrictions:
Packit cb6d3d
 * - MUST CALL BUFFERING_CLOSE() WHEN FINISHED!!!
Packit cb6d3d
 *
Packit cb6d3d
 */
Packit cb6d3d
long int 
Packit cb6d3d
buffering_write(int fd, char *buffer, long num)
Packit cb6d3d
{
Packit cb6d3d
  if (fd != bw_fd) {
Packit cb6d3d
    /* clean up after buffering for some other file */
Packit cb6d3d
    if (bw_fd >= 0 && bw_pos > 0) {
Packit cb6d3d
      if (blocking_write(bw_fd, bw_outbuf, bw_pos)) {
Packit cb6d3d
	perror("write (in buffering_write, flushing)");
Packit cb6d3d
      }
Packit cb6d3d
    }
Packit cb6d3d
    bw_fd  = fd;
Packit cb6d3d
    bw_pos = 0;
Packit cb6d3d
  }
Packit cb6d3d
  
Packit cb6d3d
  if (bw_pos + num > OUTBUFSZ) {
Packit cb6d3d
    /* fill our buffer first, then write, then modify buffer and num */
Packit cb6d3d
    memcpy(&bw_outbuf[bw_pos], buffer, OUTBUFSZ - bw_pos);
Packit cb6d3d
    if (blocking_write(fd, bw_outbuf, OUTBUFSZ)) {
Packit cb6d3d
      perror("write (in buffering_write, full buffer)");
Packit cb6d3d
      return(-1);
Packit cb6d3d
    }
Packit cb6d3d
    num -= (OUTBUFSZ - bw_pos);
Packit cb6d3d
    buffer += (OUTBUFSZ - bw_pos);
Packit cb6d3d
    bw_pos = 0;
Packit cb6d3d
  }
Packit cb6d3d
  /* save data */
Packit cb6d3d
  if(buffer && num)
Packit cb6d3d
    memcpy(&bw_outbuf[bw_pos], buffer, num);
Packit cb6d3d
  bw_pos += num;
Packit cb6d3d
  
Packit cb6d3d
  return(0);
Packit cb6d3d
}
Packit cb6d3d
Packit cb6d3d
/** buffering_close() - writes out remaining buffered data before
Packit cb6d3d
 * closing file.
Packit cb6d3d
 *
Packit cb6d3d
 */
Packit cb6d3d
int 
Packit cb6d3d
buffering_close(int fd)
Packit cb6d3d
{
Packit cb6d3d
  if (fd == bw_fd && bw_pos > 0) {
Packit cb6d3d
    /* write out remaining data and clean up */
Packit cb6d3d
    if (blocking_write(fd, bw_outbuf, bw_pos)) {
Packit cb6d3d
      perror("write (in buffering_close)");
Packit cb6d3d
    }
Packit cb6d3d
    bw_fd  = -1;
Packit cb6d3d
    bw_pos = 0;
Packit cb6d3d
  }
Packit cb6d3d
  return(close(fd));
Packit cb6d3d
}