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