summaryrefslogtreecommitdiffstats
path: root/maildrop/mio.C
diff options
context:
space:
mode:
authorSam Varshavchik2013-08-19 16:39:41 -0400
committerSam Varshavchik2013-08-25 14:43:51 -0400
commit9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch)
tree7a81a04cb51efb078ee350859a64be2ebc6b8813 /maildrop/mio.C
parenta9520698b770168d1f33d6301463bb70a19655ec (diff)
downloadcourier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2
Initial checkin
Imported from subversion report, converted to git. Updated all paths in scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'maildrop/mio.C')
-rw-r--r--maildrop/mio.C243
1 files changed, 243 insertions, 0 deletions
diff --git a/maildrop/mio.C b/maildrop/mio.C
new file mode 100644
index 0000000..07ea08d
--- /dev/null
+++ b/maildrop/mio.C
@@ -0,0 +1,243 @@
+#include "config.h"
+#include <sys/types.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#include <errno.h>
+
+#include "mio.h"
+#include "funcs.h"
+#include "buffer.h"
+
+
+int mopen(const char *fname, int flags, mode_t mode)
+{
+int rc;
+
+ while ((rc=open(fname, flags, mode)) < 0 && errno == EINTR)
+ ;
+ return (rc);
+}
+
+int mread(int fd, void *buf, size_t count)
+{
+int n;
+
+ while ((n=read(fd, buf, count)) < 0 && errno == EINTR)
+ ;
+ return (n);
+}
+
+int mwrite(int fd, const void *buf, size_t count)
+{
+int n;
+
+ while ((n=write(fd, buf, count)) < 0 && errno == EINTR)
+ ;
+ return (n);
+}
+
+off_t mseek(int fd, off_t off, int whence)
+{
+off_t n;
+
+ while ((n=lseek(fd, off, whence)) < 0 && errno == EINTR)
+ ;
+ return (n);
+}
+
+int mclose(int fd)
+{
+int n;
+
+ while ((n=close(fd)) < 0 && errno == EINTR)
+ ;
+ return (n);
+}
+
+//-------------------------------------------------------------------------
+
+Mio::Mio() : fd_(-1), readcnt(0), writecnt(0), err(0)
+{
+}
+
+Mio::~Mio() { Close(); }
+
+void Mio::Close()
+{
+ if (fd_ < 0) return;
+ if (writeptr > buf) flush(-1);
+ mclose(fd_);
+ fd_= -1;
+}
+
+int Mio::Open(const char *filename, int flags, mode_t m)
+{
+ fd(mopen(filename, flags, m));
+ return (fd_);
+}
+
+int Mio::fill()
+{
+ readcnt=0;
+ if (fd_ < 0 || err) return (-1);
+ if (writeptr > buf && flush(-1) < 0) return (-1);
+
+ readstartpos=tell();
+ readcnt=mread(fd_, buf, sizeof(buf));
+ readsize=readcnt;
+
+ if (readcnt <= 0)
+ {
+ readcnt=0;
+ readsize=0;
+ err= -1;
+ return (-1);
+ }
+ --readcnt;
+ return (*(readptr=buf)++);
+}
+
+int Mio::flush(int c)
+{
+ if (fd_ < 0 || err) return (-1);
+ if (readcnt && mseek(fd_, -readcnt, SEEK_CUR) < 0) return (-1);
+ readcnt=0;
+ readptr=buf;
+
+ while (writeptr > buf)
+ {
+ int n;
+
+ if ((n=mwrite(fd_, buf, writeptr-buf)) <= 0)
+ {
+ err= -1;
+ return (-1);
+ }
+ memorycopy(buf, buf+n, writeptr-buf-n);
+ writeptr -= n;
+ }
+
+ writecnt=sizeof(buf);
+ if (c >= 0)
+ {
+ --writecnt;
+ *writeptr++ = c;
+ }
+ return (0);
+}
+
+int Mio::Rewind()
+{
+ readstartpos= -1;
+ return ( seek (0L, SEEK_SET) );
+}
+
+int Mio::seek(off_t off, int whence)
+{
+ if (fd_ < 0) return (-1);
+ if (writeptr > buf && flush(-1) < 0) return (-1);
+ if (whence == SEEK_CUR && err == 0) off -= readcnt;
+
+ // Optimize - seek can be satisfied within the read buffer.
+
+ if (whence == SEEK_SET && readstartpos != -1 &&
+ off >= readstartpos && off <= readstartpos + readsize)
+ {
+ readptr = buf + (off - readstartpos);
+ readcnt = readsize - (off - readstartpos);
+ return (0);
+ }
+
+ if (mseek(fd_, off, whence) < 0)
+ {
+ err= -1;
+ return (-1);
+ }
+ err=0;
+ readcnt=0;
+ readptr=buf;
+ return (0);
+}
+
+int Mio::write(const void *p, int cnt)
+{
+const unsigned char *cp=(const unsigned char *)p;
+int done=0;
+
+ if (fd_ < 0 || err) return (-1);
+
+ while (cnt)
+ {
+ int l;
+
+ if (writecnt == 0 && flush() < 0)
+ {
+ if (done == 0) done= -1;
+ break;
+ }
+
+ if (writeptr > buf || cnt <= writecnt)
+ {
+ l=writecnt;
+
+ if (l > cnt) l=cnt;
+ memcpy(writeptr, cp, l);
+ writecnt -= l;
+ writeptr += l;
+ }
+ else
+ {
+ l=mwrite(fd_, cp, cnt);
+ if (l <= 0)
+ {
+ if (done == 0) done= -1;
+ break;
+ }
+ }
+
+ cp += l;
+ done += l;
+ cnt -= l;
+ }
+ return (done);
+}
+
+off_t Mio::tell()
+{
+ if (fd_ < 0) return (0);
+
+off_t p=mseek(fd_, 0L, SEEK_CUR);
+
+ if (p == -1) return (-1);
+ return (p + (writeptr - buf) - readcnt);
+}
+
+Mio &Mio::operator<<(const class Buffer &b)
+{
+ write( (const char *)b, b.Length() );
+ return (*this);
+}
+
+MioStdio mout(1), merr(2);
+
+MioStdio::MioStdio(int f)
+{
+ fd(f);
+}
+
+MioStdio::~MioStdio()
+{
+ fd(-1);
+}
+
+int MioStdio::write(const void *p, int cnt)
+{
+int n;
+
+ n=Mio::write(p, cnt);
+ if (n > 0) Mio::flush();
+ return (n);
+}
+
+extern MioStdio mout, merr;