#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <fcntl.h>

#include <sys/mman.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <unistd.h>


void traditional();

void write_xiaohei();

void copy_toheidan();

void mergertoheihei();

void mapping();


int main(void)

{

   traditional();

   mapping();


   return 0;

}

void mapping()

{

   write_xiaohei();

   copy_toheidan();

   mergertoheihei();

}

void traditional()

{

   printf("*****************create a file named xiaohei\n");

   int fw;

   char ch[20];

   fw=open("xiaohei",O_WRONLY|O_CREAT|O_TRUNC,0644);

   if(fw<0){

       perror("create error");

       exit(1);

   }

   sprintf(ch,"hello,world!");

   write(fw,ch,strlen(ch));

   close(fw);


   printf("*****************copy the content from xiaohei to heidan\n");

   int fr,len;

   fr=open("xiaohei",O_RDONLY);

   if(fr<0){

       perror("open xiaohei error");

       exit(1);

   }

   fw=open("heidan",O_WRONLY|O_CREAT|O_TRUNC,0644);

   if(fw<0){

       perror("create heidan error");

       exit(1);

   }

   while((len=read(fr,ch,5))>0)

   {

       write(fw,ch,len);

   }


   close(fr);

   close(fr);


   printf("*****************merger xiaohei and heidan into heihei\n");

   int fd;

   fd=open("xiaohei",O_RDONLY);

   if(fd<0){

       perror("open xiaohei error");

       exit(1);

   }

   fr=open("heidan",O_RDONLY);

   if(fr<0){

       perror("open heidan error");

       exit(1);

   }

   fw=open("heihei",O_WRONLY|O_CREAT|O_TRUNC,0644);

   if(fw<0){

       perror("create heihei error");

       exit(1);

   }

   while((len=read(fr,ch,5))>0)

   {

       write(fw,ch,len);

   }

   while((len=read(fd,ch,5))>0)

   {

       write(fw,ch,len);

   }

   close(fd);

   close(fr);

   close(fw);

}

void write_xiaohei()

{

   printf("*****************create a file named xiaohei\n");

   int fw,size,*p;

   char data[20]="hello  world!";

   fw=open("xiaohei",O_RDWR|O_CREAT|O_TRUNC,0644);

   if(fw<0){

       perror("create xiaohei error");

       exit(1);

   }


   size=strlen(data);


   write(fw,data,size);


   p=mmap(NULL,size,PROT_WRITE|PROT_READ,MAP_SHARED,fw,0);

   if(p==MAP_FAILED){

       perror("error");

       exit(1);

   }


   close(fw);


   munmap(p,size);


}

void copy_toheidan()

{

   printf("*****************copy the content from xiaohei to heidan\n");

   int fr,size,*p,fw,*q;

   

   fr=open("xiaohei",O_RDONLY);

   if(fr<0){

       perror("create xiaohei error");

       exit(1);

   }

   

   fw=open("heidan",O_RDWR|O_CREAT|O_TRUNC,0644);

   if(fw<0){

       perror("create heidan error");

       exit(1);

   


   size=lseek(fr,0,SEEK_END);

   

   p=mmap(NULL,size,PROT_READ,MAP_PRIVATE,fr,0);

   if(p==MAP_FAILED){

       perror("error");

       exit(1);

   }

   

   lseek(fw,size-1,SEEK_END);

   write(fw," ",1);

   

   q=mmap(NULL,size,PROT_WRITE|PROT_READ,MAP_SHARED,fw,0);

   //without the use of MAP_PRIVATE in here

   if(q==MAP_FAILED){

       perror("error");

       exit(1);

   }

   close(fr);

   close(fw);

   

   memcpy(q,p,size);

   

   munmap(p,size);

   munmap(q,size);

}

void mergertoheihei()

{

   printf("*****************merger xiaohei and heidan into heihei\n");

   int fr,size=0,fw,fd,i,len,filenum;

   char *p,*q,*m;

   char *filename[2]={"xiaohei","heidan"};

   filenum=sizeof(filename)/sizeof(filename[0]);

   

   for(i=0;i<filenum;i++)

   {

       fr=open(filename[i],O_RDONLY);

       if(fr<0){

           perror("create error");

           exit(1);

       }

       size+=lseek(fr,0,SEEK_END);

   }


   fw=open("heihei",O_RDWR|O_CREAT|O_TRUNC,0644);

   if(fw<0){

       perror("create heihei error");

       exit(1);

   }


   lseek(fw,size-1,SEEK_END);

   write(fw," ",1);

   

   q=mmap(NULL,size,PROT_WRITE|PROT_READ,MAP_SHARED,fw,0);

   //without the use of MAP_PRIVATE in here

   if(q==MAP_FAILED){

       perror("error");

       exit(1);

   }


   for(i=0;i<filenum;i++)

   {

       fr=open(filename[i],O_RDONLY);

       if(fr<0){

           perror("create error");

           exit(1);

       }

       len=lseek(fr,0,SEEK_END);

       p=mmap(NULL,len,PROT_READ,MAP_PRIVATE,fr,0);

       if(p==MAP_FAILED){

           perror("error");

           exit(1);

       }

       close(fr);

       memcpy(q,p,size);

       q+=len;

       

       munmap(p,len);

   }


   close(fw);

   

   munmap(q,size);

}