Skip to content

Instantly share code, notes, and snippets.

@mchirico
Last active February 28, 2023 05:29
Show Gist options
  • Save mchirico/5310145 to your computer and use it in GitHub Desktop.
Save mchirico/5310145 to your computer and use it in GitHub Desktop.
An example of mmap where data is modified in the file. This version currently compiles on Mac OSX.
/*
An example of mmap where data is modified in the file. This
version currently compiles on Mac OSX.
References:
Advanced Programming in the UNIX® Environment, Third Edition
By: W. Richard Stevens; Stephen A. Rago
Publisher: Addison-Wesley Professional
Compile:
gcc -o mmap mmap.c
*/
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
#define COPYINCR (1024*1024*1024) /* 1 GB */
void mlog(int fdin,const char *s,off_t offset,size_t copysz)
{
if (offset > copysz)
return;
if (strlen(s) > (copysz - offset))
return;
lseek(fdin,offset,SEEK_SET);
write(fdin,s,strlen(s));
}
int main(int argc, char *argv[])
{
int fdin, fdout;
void *src, *dst;
size_t copysz;
struct stat sbuf;
off_t fsz = 0;
if (argc != 3) {
fprintf(stderr,"\nusage: %s <fromfile> <tofile>\n\n", argv[0]);
fprintf(stderr,"\tNote that your <fromfile> needs to have some size in it.\n\n", argv[0]);
fprintf(stderr,"\tTry this:\n");
fprintf(stderr,"\t\tdd if=/dev/zero of=tpfile count=20480 && ./mmap tpfile junk\n\n");
return 0;
}
if ((fdin = open(argv[1], O_RDWR)) < 0) {
fprintf(stderr,"can't open %s for reading\n", argv[1]);
return 0;
}
if ((fdout = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, FILE_MODE)) < 0)
{
fprintf(stderr,"can't creat %s for writing\n", argv[2]);
return 0;
}
if (fstat(fdin, &sbuf) < 0) /* need size of input file */
{
fprintf(stderr,"fstat error\n");
return 0;
}
if (ftruncate(fdout, sbuf.st_size) < 0) /* set output file size */
{
fprintf(stderr,"ftruncate error\n");
return 0;
}
while (fsz < sbuf.st_size) {
if ((sbuf.st_size - fsz) > COPYINCR)
copysz = COPYINCR;
else
copysz = sbuf.st_size - fsz;
if ((src = mmap(0, copysz, PROT_READ | PROT_WRITE, MAP_SHARED,fdin, fsz)) == MAP_FAILED)
{
fprintf(stderr,"mmap error for input\n");
return 0;
}
if ((dst = mmap(0, copysz, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, fsz)) == MAP_FAILED)
{
fprintf(stderr,"mmap error for output\n");
return 0;
}
//Blank out everything and make 80 length colums
int i=0;
char *t;
t=src;
for(i=0; i < copysz; ++i)
{
if( (i+1) % 81 == 0)
*t++='\n';
else
*t++=' ';
}
// Change some data
mlog(fdin,"Beginning ",0,copysz);
mlog(fdin,"Middle ",150,copysz);
mlog(fdin,"Far out maybe too far ",800,copysz);
memcpy(dst, src, copysz); /* does the file copy */
munmap(src, copysz);
munmap(dst, copysz);
printf("fsz = %d copysz=%d\n",(int) fsz,(int) copysz);
fsz += copysz;
}
exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment