summaryrefslogtreecommitdiff
path: root/usr/src/lib/libast/common/port/astcopy.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libast/common/port/astcopy.c')
-rw-r--r--usr/src/lib/libast/common/port/astcopy.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/usr/src/lib/libast/common/port/astcopy.c b/usr/src/lib/libast/common/port/astcopy.c
new file mode 100644
index 0000000000..2dbf712ddc
--- /dev/null
+++ b/usr/src/lib/libast/common/port/astcopy.c
@@ -0,0 +1,90 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2007 AT&T Knowledge Ventures *
+* and is licensed under the *
+* Common Public License, Version 1.0 *
+* by AT&T Knowledge Ventures *
+* *
+* A copy of the License is available at *
+* http://www.opensource.org/licenses/cpl1.0.txt *
+* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * copy from rfd to wfd (with conditional mmap hacks)
+ */
+
+#include <ast.h>
+#include <ast_mmap.h>
+
+#if _mmap_worthy > 1
+
+#include <ls.h>
+
+#define MAPSIZE (1024*256)
+
+#endif
+
+#undef BUFSIZ
+#define BUFSIZ 4096
+
+/*
+ * copy n bytes from rfd to wfd
+ * actual byte count returned
+ * if n<=0 then ``good'' size is used
+ */
+
+off_t
+astcopy(int rfd, int wfd, off_t n)
+{
+ register off_t c;
+#ifdef MAPSIZE
+ off_t pos;
+ off_t mapsize;
+ char* mapbuf;
+ struct stat st;
+#endif
+
+ static int bufsiz;
+ static char* buf;
+
+ if (n <= 0 || n >= BUFSIZ * 2)
+ {
+#if MAPSIZE
+ if (!fstat(rfd, &st) && S_ISREG(st.st_mode) && (pos = lseek(rfd, (off_t)0, 1)) != ((off_t)-1))
+ {
+ if (pos >= st.st_size) return(0);
+ mapsize = st.st_size - pos;
+ if (mapsize > MAPSIZE) mapsize = (mapsize > n && n > 0) ? n : MAPSIZE;
+ if (mapsize >= BUFSIZ * 2 && (mapbuf = (char*)mmap(NiL, mapsize, PROT_READ, MAP_SHARED, rfd, pos)) != ((caddr_t)-1))
+ {
+ if (write(wfd, mapbuf, mapsize) != mapsize || lseek(rfd, mapsize, 1) == ((off_t)-1)) return(-1);
+ munmap((caddr_t)mapbuf, mapsize);
+ return(mapsize);
+ }
+ }
+#endif
+ if (n <= 0) n = BUFSIZ;
+ }
+ if (n > bufsiz)
+ {
+ if (buf) free(buf);
+ bufsiz = roundof(n, BUFSIZ);
+ if (!(buf = newof(0, char, bufsiz, 0))) return(-1);
+ }
+ if ((c = read(rfd, buf, (size_t)n)) > 0 && write(wfd, buf, (size_t)c) != c) c = -1;
+ return(c);
+}