source: trunk/third/sendmail/libsm/fread.c @ 19204

Revision 19204, 2.3 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19203, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
3 *      All rights reserved.
4 * Copyright (c) 1990, 1993
5 *      The Regents of the University of California.  All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Chris Torek.
9 *
10 * By using this file, you agree to the terms and conditions set
11 * forth in the LICENSE file which can be found at the top level of
12 * the sendmail distribution.
13 */
14
15#include <sm/gen.h>
16SM_RCSID("@(#)$Id: fread.c,v 1.1.1.1 2003-04-08 15:06:04 zacheiss Exp $")
17#include <string.h>
18#include <errno.h>
19#include <sm/io.h>
20#include <sm/assert.h>
21#include "local.h"
22
23/*
24**  SM_IO_READ -- read data from the file pointer
25**
26**      Parameters:
27**              fp -- file pointer to read from
28**              timeout -- time to complete the read
29**              buf -- location to place read data
30**              size -- size of each chunk of data
31**
32**      Returns:
33**              Failure: returns 0 (zero) _and_ sets errno
34**              Success: returns the number of whole chunks read.
35**
36**      A read returning 0 (zero) is only an indication of error when errno
37**      has been set.
38*/
39
40size_t
41sm_io_read(fp, timeout, buf, size)
42        SM_FILE_T *fp;
43        int timeout;
44        void *buf;
45        size_t size;
46{
47        register size_t resid = size;
48        register char *p;
49        register int r;
50
51        SM_REQUIRE_ISA(fp, SmFileMagic);
52
53        if (fp->f_read == NULL)
54        {
55                errno = ENODEV;
56                return 0;
57        }
58
59        /*
60        **  The ANSI standard requires a return value of 0 for a count
61        **  or a size of 0.  Peculiarily, it imposes no such requirements
62        **  on fwrite; it only requires read to be broken.
63        */
64
65        if (resid == 0)
66                return 0;
67        if (fp->f_r < 0)
68                fp->f_r = 0;
69        p = buf;
70        while ((int) resid > (r = fp->f_r))
71        {
72                (void) memcpy((void *) p, (void *) fp->f_p, (size_t) r);
73                fp->f_p += r;
74                /* fp->f_r = 0 ... done in sm_refill */
75                p += r;
76                resid -= r;
77                if ((fp->f_flags & SMNOW) != 0 && r > 0)
78                {
79                        /*
80                        **  Take whatever we have available. Spend no more time
81                        **  trying to get all that has been requested.
82                        **  This is needed on some file types (such as
83                        **  SASL) that would jam when given extra, untimely
84                        **  reads.
85                        */
86
87                        fp->f_r -= r;
88                        return size - resid;
89                }
90                if (sm_refill(fp, timeout) != 0)
91                {
92                        /* no more input: return partial result */
93                        return size - resid;
94                }
95        }
96        (void) memcpy((void *) p, (void *) fp->f_p, resid);
97        fp->f_r -= resid;
98        fp->f_p += resid;
99        return size;
100}
Note: See TracBrowser for help on using the repository browser.