1/***********************************************************************
2*                                                                      *
3*               This software is part of the ast package               *
4*          Copyright (c) 1985-2010 AT&T Intellectual Property          *
5*                      and is licensed under the                       *
6*                  Common Public License, Version 1.0                  *
7*                    by AT&T Intellectual Property                     *
8*                                                                      *
9*                A copy of the License is available at                 *
10*            http://www.opensource.org/licenses/cpl1.0.txt             *
11*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12*                                                                      *
13*              Information and Software Systems Research               *
14*                            AT&T Research                             *
15*                           Florham Park NJ                            *
16*                                                                      *
17*                 Glenn Fowler <gsf@research.att.com>                  *
18*                  David Korn <dgk@research.att.com>                   *
19*                   Phong Vo <kpv@research.att.com>                    *
20*                                                                      *
21***********************************************************************/
22#pragma prototyped
23/*
24 * Glenn Fowler
25 * AT&T Bell Laboratories
26 *
27 * copy from rfd to wfd (with conditional mmap hacks)
28 */
29
30#include <ast.h>
31#include <ast_mmap.h>
32
33#if _mmap_worthy > 1
34
35#include <ls.h>
36
37#define MAPSIZE		(1024*256)
38
39#endif
40
41#undef	BUFSIZ
42#define BUFSIZ		4096
43
44/*
45 * copy n bytes from rfd to wfd
46 * actual byte count returned
47 * if n<=0 then ``good'' size is used
48 */
49
50off_t
51astcopy(int rfd, int wfd, off_t n)
52{
53	register off_t	c;
54#ifdef MAPSIZE
55	off_t		pos;
56	off_t		mapsize;
57	char*		mapbuf;
58	struct stat	st;
59#endif
60
61	static int	bufsiz;
62	static char*	buf;
63
64	if (n <= 0 || n >= BUFSIZ * 2)
65	{
66#if MAPSIZE
67		if (!fstat(rfd, &st) && S_ISREG(st.st_mode) && (pos = lseek(rfd, (off_t)0, 1)) != ((off_t)-1))
68		{
69			if (pos >= st.st_size) return(0);
70			mapsize = st.st_size - pos;
71			if (mapsize > MAPSIZE) mapsize = (mapsize > n && n > 0) ? n : MAPSIZE;
72			if (mapsize >= BUFSIZ * 2 && (mapbuf = (char*)mmap(NiL, mapsize, PROT_READ, MAP_SHARED, rfd, pos)) != ((caddr_t)-1))
73			{
74				if (write(wfd, mapbuf, mapsize) != mapsize || lseek(rfd, mapsize, 1) == ((off_t)-1)) return(-1);
75				munmap((caddr_t)mapbuf, mapsize);
76				return(mapsize);
77			}
78		}
79#endif
80		if (n <= 0) n = BUFSIZ;
81	}
82	if (n > bufsiz)
83	{
84		if (buf) free(buf);
85		bufsiz = roundof(n, BUFSIZ);
86		if (!(buf = newof(0, char, bufsiz, 0))) return(-1);
87	}
88	if ((c = read(rfd, buf, (size_t)n)) > 0 && write(wfd, buf, (size_t)c) != c) c = -1;
89	return(c);
90}
91