This program shows use of a number of system calls such as how to map a disk file in the virtual memory of a process space, divide it into pages, set access protection code such as read_only, write_only, etc to individual pages, read/write individual pages, and copy the file back to disk page by page.
#include <stdio.h> #include <stdlib.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <string.h> #include <unistd.h> extern int errno; main() { int fid1, fid2; void *address1, *address2; char buf[10], data[10]="edwin c"; char *ptr, *base, data1[10]="baldelomar"; int i, n, pagesize; struct stat statbuf; int inFileSize, outFileSize; if ((fid1 = open("alice29.txt", O_RDWR, 0600)) < 0) {perror("alice open failed"); printf (" errno=%d \n", errno); } if (fstat(fid1, &statbuf)<0) perror("fstat error"); inFileSize = statbuf.st_size; printf("Temp1 file size=%d\n", inFileSize); if ((fid2 = open("temp2", O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) perror("temp2 open failed"); /* temp2 is empty file. It has no space. Let us make it 20000 bytes long by setting pointer to 9999 and then writeing a byte. */ if ((lseek(fid2, 19999, SEEK_SET)) < 0) perror ("lseek error"); if (write(fid2, "X", 1) != 1) //write 'X' at end {perror("write error"); exit(-1);} if (fstat(fid2, &statbuf)<0) perror("fstat error"); outFileSize = statbuf.st_size; printf("Temp2 file size=%d\n", outFileSize);/*prints size=20000*/ /*----------------------------------------------------*/ if ((pagesize=sysconf(_SC_PAGESIZE))<0) perror("sysconf failed"); printf("page size =%d\n", pagesize); /* map source file entirely in memory for reading by possibly multiple processed, who may share all changes. */ if ((address1 = mmap((caddr_t) 0, inFileSize, PROT_READ, MAP_SHARED, fid1, 0))==MAP_FAILED) {perror("mmap failed"); printf("errno=%d\n", errno);} printf("actual mapped address1=0x%x\n", address1); base = ptr = (char *) (address1+500); for (i=0; i< 8; i++) buf[i] = *ptr++; buf[8]='\0'; printf ("Reading Source: %s\n", buf); /* Following attempt to write to source file should cause segmentation error, because of read_prot, although the file is onped RDWR.*/ /* ptr = base; for(i=0; i<8; i++) *ptr++ = data[i]; fprintf(stderr, "Writing to source: %s\n", base); */ /*----------------------------------------------------*/ if ((address2 = mmap((caddr_t) address1, 10000, (PROT_READ | PROT_WRITE), MAP_SHARED, fid2, 0))==MAP_FAILED) {perror("mmap failed"); printf("errno=%d\n", errno);} printf("actual address2=0x%x\n", address2); /* Make first page write only */ if ((mprotect(address2, pagesize, PROT_WRITE))<0) printf("protect write error=%d\n", errno); /* make second page read only. */ if ((mprotect(address2+pagesize, pagesize, PROT_READ))<0) printf("protect read error=%d\n", errno); /* Dump one page of memory space to output file */ if ((msync(address2, pagesize, MS_SYNC))<0) printf("m-sync error=%d\n", errno); munmap(address1, inFileSize);//remove memory space munmap(address2, outFileSize); /* I/O is possible using file descriptor, but not through alloacted space now. */ close(fid1); close(fid2); }