coleman@cam.nist.gov (Sean Sheridan Coleman X5672) (02/05/91)
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. I am also looking for examples that use madvise, mcntl, and mlock. Thanks very much Sean Coleman NIST coleman@bldrdoc.gov
lm@slovax.Eng.Sun.COM (Larry McVoy) (02/05/91)
In article <6991@alpha.cam.nist.gov> coleman@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@sun.com