fread.c revision 90792
190792Sgshapiro/* 290792Sgshapiro * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. 390792Sgshapiro * All rights reserved. 490792Sgshapiro * Copyright (c) 1990, 1993 590792Sgshapiro * The Regents of the University of California. All rights reserved. 690792Sgshapiro * 790792Sgshapiro * This code is derived from software contributed to Berkeley by 890792Sgshapiro * Chris Torek. 990792Sgshapiro * 1090792Sgshapiro * By using this file, you agree to the terms and conditions set 1190792Sgshapiro * forth in the LICENSE file which can be found at the top level of 1290792Sgshapiro * the sendmail distribution. 1390792Sgshapiro */ 1490792Sgshapiro 1590792Sgshapiro#include <sm/gen.h> 1690792SgshapiroSM_RCSID("@(#)$Id: fread.c,v 1.28 2001/09/11 04:04:48 gshapiro Exp $") 1790792Sgshapiro#include <string.h> 1890792Sgshapiro#include <errno.h> 1990792Sgshapiro#include <sm/io.h> 2090792Sgshapiro#include <sm/assert.h> 2190792Sgshapiro#include "local.h" 2290792Sgshapiro 2390792Sgshapiro/* 2490792Sgshapiro** SM_IO_READ -- read data from the file pointer 2590792Sgshapiro** 2690792Sgshapiro** Parameters: 2790792Sgshapiro** fp -- file pointer to read from 2890792Sgshapiro** timeout -- time to complete the read 2990792Sgshapiro** buf -- location to place read data 3090792Sgshapiro** size -- size of each chunk of data 3190792Sgshapiro** 3290792Sgshapiro** Returns: 3390792Sgshapiro** Failure: returns 0 (zero) _and_ sets errno 3490792Sgshapiro** Success: returns the number of whole chunks read. 3590792Sgshapiro** 3690792Sgshapiro** A read returning 0 (zero) is only an indication of error when errno 3790792Sgshapiro** has been set. 3890792Sgshapiro*/ 3990792Sgshapiro 4090792Sgshapirosize_t 4190792Sgshapirosm_io_read(fp, timeout, buf, size) 4290792Sgshapiro SM_FILE_T *fp; 4390792Sgshapiro int timeout; 4490792Sgshapiro void *buf; 4590792Sgshapiro size_t size; 4690792Sgshapiro{ 4790792Sgshapiro register size_t resid = size; 4890792Sgshapiro register char *p; 4990792Sgshapiro register int r; 5090792Sgshapiro 5190792Sgshapiro SM_REQUIRE_ISA(fp, SmFileMagic); 5290792Sgshapiro 5390792Sgshapiro if (fp->f_read == NULL) 5490792Sgshapiro { 5590792Sgshapiro errno = ENODEV; 5690792Sgshapiro return 0; 5790792Sgshapiro } 5890792Sgshapiro 5990792Sgshapiro /* 6090792Sgshapiro ** The ANSI standard requires a return value of 0 for a count 6190792Sgshapiro ** or a size of 0. Peculiarily, it imposes no such requirements 6290792Sgshapiro ** on fwrite; it only requires read to be broken. 6390792Sgshapiro */ 6490792Sgshapiro 6590792Sgshapiro if (resid == 0) 6690792Sgshapiro return 0; 6790792Sgshapiro if (fp->f_r < 0) 6890792Sgshapiro fp->f_r = 0; 6990792Sgshapiro p = buf; 7090792Sgshapiro while ((int) resid > (r = fp->f_r)) 7190792Sgshapiro { 7290792Sgshapiro (void) memcpy((void *) p, (void *) fp->f_p, (size_t) r); 7390792Sgshapiro fp->f_p += r; 7490792Sgshapiro /* fp->f_r = 0 ... done in sm_refill */ 7590792Sgshapiro p += r; 7690792Sgshapiro resid -= r; 7790792Sgshapiro if ((fp->f_flags & SMNOW) != 0 && r > 0) 7890792Sgshapiro { 7990792Sgshapiro /* 8090792Sgshapiro ** Take whatever we have available. Spend no more time 8190792Sgshapiro ** trying to get all that has been requested. 8290792Sgshapiro ** This is needed on some file types (such as 8390792Sgshapiro ** SASL) that would jam when given extra, untimely 8490792Sgshapiro ** reads. 8590792Sgshapiro */ 8690792Sgshapiro 8790792Sgshapiro fp->f_r -= r; 8890792Sgshapiro return size - resid; 8990792Sgshapiro } 9090792Sgshapiro if (sm_refill(fp, timeout) != 0) 9190792Sgshapiro { 9290792Sgshapiro /* no more input: return partial result */ 9390792Sgshapiro return size - resid; 9490792Sgshapiro } 9590792Sgshapiro } 9690792Sgshapiro (void) memcpy((void *) p, (void *) fp->f_p, resid); 9790792Sgshapiro fp->f_r -= resid; 9890792Sgshapiro fp->f_p += resid; 9990792Sgshapiro return size; 10090792Sgshapiro} 101