mmap

Larry McVoy lm at slovax.Eng.Sun.COM
Tue Feb 5 19:16:12 AEST 1991


In article <6991 at alpha.cam.nist.gov> coleman at cam.nist.gov (Sean Sheridan Coleman X5672) writes:
>Does anyone have any examples of mmap for sun's. I am especially
>interested in being able to  open one file and copy it to
>another  one. I also would like to see some examples that 
>utilize the EXEC proto.

Don't have a quickie for EXEC.  Check this out, just some gunk I'm playing
with.


# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# mmapcp.c mmaplib.c

echo x - mmapcp.c
cat > "mmapcp.c" << '//E*O*F mmapcp.c//'
/*
 * a version of copy that maps in the data & writes it with mmap.
 *
 * Both sets of data are synced of memory.  This is designed to move data
 * fairly quickly but still disturb the system as little as possible.
 *
 * @(#)mmapcp.c	1.2
 */

#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>

#define	SYNCSIZ	(256*1024)

main(ac, av)
	char **av;
{
	int	i, bytes;
	int	in, out;
	char	*ibuf, *obuf, *ip, *op;

	if (ac != 3) {
		printf("usage: %s src dest\n", av[0]);
		exit(0);
	}
	if ((in = open(av[1], 0)) == -1) {
		perror(av[1]);
		exit(1);
	}
	if ((out = open(av[2], O_RDWR|O_CREAT, 0644)) == -1) {
		perror(av[2]);
		exit(1);
	}
	if (mmap_init(in, &ibuf, 0, -1, 0) == -1) {
		perror("mmap_init in");
		exit(1);
	}
	if (mmap_init(out, &obuf, 0, size(in), 1) == -1) {
		perror("mmap_init out");
		exit(1);
	}
	ip = ibuf;
	op = obuf;
	for (i = size(in); i > 0; i -= SYNCSIZ) {
		bytes = SYNCSIZ < i ? SYNCSIZ : i;
		bcopy(ip, op, bytes);
		mmap_flush(ip, bytes, 1);
		mmap_flush(op, bytes, 0);	/* 1 takes longer */
		ip += bytes;
		op += bytes;
	}
	close(in);
	close(out);
	exit(0);
}
//E*O*F mmapcp.c//

echo x - mmaplib.c
cat > "mmaplib.c" << '//E*O*F mmaplib.c//'
/*
 * @(#)mmaplib.c	1.3
 */
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>

/*
 * Set things up to do I/O over the indicated range
 *
 * XXX - up to user to be sure that mmap is an OK thing to do (tapes).
 */
mmap_init(fd, basepp, off, bytes, writeable)
	caddr_t	*basepp;
	off_t	bytes;
{
	caddr_t	base;
	int	protbits;

	protbits = PROT_READ;
	if (writeable) {
		protbits |= PROT_WRITE;
	}
	if (!regfile(fd)) {
		return (-1);
	}
	if (bytes == (off_t)-1) {
		bytes = size(fd);
	}
	if (writeable && ftruncate(fd, off + bytes) == -1) {
		return (-1);
	}
	base = mmap((caddr_t)0, bytes, protbits, MAP_SHARED, fd, off);
	if (base == (caddr_t)-1) {
		return (-1);
	}
	madvise(base, bytes, MADV_SEQUENTIAL);
	*basepp = base;
	return (0);
}

/*
 * flush writes
 */
mmap_flush(addr, len, clean)
	caddr_t	addr;
	off_t	len;
{
	msync(addr, len, MS_ASYNC);
	if (clean)
		madvise(addr, len, MADV_DONTNEED);
}

static	struct stat sb;
static	lastfd = -1;

regfile(fd)
{
	if (lastfd != fd) {
		if (fstat(fd, &sb) == -1) {
			return (-1);
		}
		lastfd = fd;
	}
	return (S_ISREG(sb.st_mode));
}

size(fd)
{
	if (lastfd != fd) {
		if (fstat(fd, &sb) == -1) {
			return (-1);
		}
		lastfd = fd;
	}
	return (sb.st_size);
}
//E*O*F mmaplib.c//

echo Possible errors detected by \'wc\' [hopefully none]:
temp=/tmp/shar$$
trap "rm -f $temp; exit" 0 1 2 3 15
cat > $temp <<\!!!
      57     188    1124 mmapcp.c
      78     198    1239 mmaplib.c
     135     386    2363 total
!!!
wc  mmapcp.c mmaplib.c | sed 's=[^ ]*/==' | diff -b $temp -
exit 0
---
Larry McVoy, Sun Microsystems     (415) 336-7627       ...!sun!lm or lm at sun.com



More information about the Comp.unix.internals mailing list