/*
* Copyright (c) 2001-2002 Packet Design, LLC.
* All rights reserved.
*
* Subject to the following obligations and disclaimer of warranty,
* use and redistribution of this software, in source or object code
* forms, with or without modifications are expressly permitted by
* Packet Design; provided, however, that:
*
* (i) Any and all reproductions of the source or object code
* must include the copyright notice above and the following
* disclaimer of warranties; and
* (ii) No rights are granted, in any manner or form, to use
* Packet Design trademarks, including the mark "PACKET DESIGN"
* on advertising, endorsements, or otherwise except as such
* appears in the above copyright notice or in the software.
*
* THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
* THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
* OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
* OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
* OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
* RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE
* LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
* OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
* DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
* USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* Author: Archie Cobbs <archie@freebsd.org>
*/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "structs/structs.h"
#include "structs/type/array.h"
#include "util/typed_mem.h"
#include "io/count_fp.h"
#define MEM_TYPE "count_fp"
/* Our state */
struct count_info {
FILE *fp;
off_t remain;
int closeit;
};
/*
* Internal functions
*/
static int count_read(void *cookie, char *buf, int len);
static int count_close(void *cookie);
/*
* Create a FILE * that reads a limited amount from another FILE *.
*/
FILE *
count_fopen(FILE *fp, off_t count, int closeit)
{
struct count_info *c;
/* Create info */
if ((c = MALLOC(MEM_TYPE, sizeof(*c))) == NULL)
return (NULL);
memset(c, 0, sizeof(*c));
c->fp = fp;
c->remain = count;
c->closeit = closeit;
/* Create new FILE * */
if ((fp = funopen(c, count_read, NULL, NULL, count_close)) == NULL) {
FREE(MEM_TYPE, c);
return (NULL);
}
/* Set to non-buffered so we don't read to much from underlying fp */
setbuf(fp, NULL);
/* Done */
return (fp);
}
/*
* Read from a count_fp.
*/
static int
count_read(void *cookie, char *buf, int len)
{
struct count_info *const c = cookie;
int ret;
if (c->remain == 0)
return (0);
if (len > c->remain)
len = c->remain;
if ((ret = fread(buf, 1, len, c->fp)) != len) {
if (ferror(c->fp))
return (-1);
}
c->remain -= ret;
return (ret);
}
/*
* Close a count_fp.
*/
static int
count_close(void *cookie)
{
struct count_info *const c = cookie;
if (c->closeit)
fclose(c->fp);
FREE(MEM_TYPE, c);
return (0);
}
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>