summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/libsm/fread.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/libsm/fread.c')
-rw-r--r--contrib/sendmail/libsm/fread.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/contrib/sendmail/libsm/fread.c b/contrib/sendmail/libsm/fread.c
new file mode 100644
index 0000000..1e651fd
--- /dev/null
+++ b/contrib/sendmail/libsm/fread.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
+ * All rights reserved.
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * By using this file, you agree to the terms and conditions set
+ * forth in the LICENSE file which can be found at the top level of
+ * the sendmail distribution.
+ */
+
+#include <sm/gen.h>
+SM_RCSID("@(#)$Id: fread.c,v 1.28 2001/09/11 04:04:48 gshapiro Exp $")
+#include <string.h>
+#include <errno.h>
+#include <sm/io.h>
+#include <sm/assert.h>
+#include "local.h"
+
+/*
+** SM_IO_READ -- read data from the file pointer
+**
+** Parameters:
+** fp -- file pointer to read from
+** timeout -- time to complete the read
+** buf -- location to place read data
+** size -- size of each chunk of data
+**
+** Returns:
+** Failure: returns 0 (zero) _and_ sets errno
+** Success: returns the number of whole chunks read.
+**
+** A read returning 0 (zero) is only an indication of error when errno
+** has been set.
+*/
+
+size_t
+sm_io_read(fp, timeout, buf, size)
+ SM_FILE_T *fp;
+ int timeout;
+ void *buf;
+ size_t size;
+{
+ register size_t resid = size;
+ register char *p;
+ register int r;
+
+ SM_REQUIRE_ISA(fp, SmFileMagic);
+
+ if (fp->f_read == NULL)
+ {
+ errno = ENODEV;
+ return 0;
+ }
+
+ /*
+ ** The ANSI standard requires a return value of 0 for a count
+ ** or a size of 0. Peculiarily, it imposes no such requirements
+ ** on fwrite; it only requires read to be broken.
+ */
+
+ if (resid == 0)
+ return 0;
+ if (fp->f_r < 0)
+ fp->f_r = 0;
+ p = buf;
+ while ((int) resid > (r = fp->f_r))
+ {
+ (void) memcpy((void *) p, (void *) fp->f_p, (size_t) r);
+ fp->f_p += r;
+ /* fp->f_r = 0 ... done in sm_refill */
+ p += r;
+ resid -= r;
+ if ((fp->f_flags & SMNOW) != 0 && r > 0)
+ {
+ /*
+ ** Take whatever we have available. Spend no more time
+ ** trying to get all that has been requested.
+ ** This is needed on some file types (such as
+ ** SASL) that would jam when given extra, untimely
+ ** reads.
+ */
+
+ fp->f_r -= r;
+ return size - resid;
+ }
+ if (sm_refill(fp, timeout) != 0)
+ {
+ /* no more input: return partial result */
+ return size - resid;
+ }
+ }
+ (void) memcpy((void *) p, (void *) fp->f_p, resid);
+ fp->f_r -= resid;
+ fp->f_p += resid;
+ return size;
+}
OpenPOWER on IntegriCloud