Code:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <wait.h>
#include <sched.h>
#include <unistd.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int fd; //file to be parsed
struct args{
char readfifoname[256],writefifoname[256];
int incdec, startIndex;
};
typedef struct args Args;
int clone_func(void *ar)
{
Args *a=(Args *) ar;
pid_t pid=getpid();
int myindex=a->startIndex,otherindex;
printf("CLONE %d started. I will parse the file from offset %d and add %d at each round. I write on %s and read from %s\n",(int)pid, myindex,a->incdec,a->writefifoname,a->readfifoname);
int fdfiforead=open (a->readfifoname,O_RDONLY), fdfifowrite=open(a->writefifoname,O_WRONLY);
if (fdfiforead==-1||fdfifowrite==-1)
{
printf("BAD OPEN FIFO\n");
return 1;
}
sleep(1); //both clones have to open the fifo before we can start
unsigned char ch;
while (1)
{
write (fdfifowrite,&myindex,sizeof(int));
read (fdfiforead,&otherindex,sizeof(int));
if (a->incdec==-1 && myindex<otherindex) //I am the clone parsing from the bottom upward and i skipped
//the other clone--> end
{
close(fdfiforead);
close(fdfifowrite);
printf("Clone %d has finished\n",(int)pid);
return 1;
}
if (a->incdec==1 && myindex>otherindex) //the contrary
{
close(fdfiforead);
close(fdfifowrite);
printf("Clone %d has finished\n",(int)pid);
return 1;
}
//read from file
lseek(fd,myindex,SEEK_SET);
read(fd,&ch,1);
if (ch==255)
{
printf("Clone %d found a char == 255 in position %d\n",(int)pid,myindex);
lseek(fd,myindex,SEEK_SET);
ch=0;
write(fd,&ch,1);
}
myindex+=a->incdec;
}
close(fdfiforead);
close(fdfifowrite);
return 0; //ERROR
}
void fillfile(int fd, int numbytes)
{
int i;
srand(time(NULL));
unsigned char ch;
lseek (fd,0,SEEK_SET);
for (i=0;i<numbytes;i++)
{
ch=rand()%256;
write(fd,&ch,sizeof(unsigned char));
}
}
void printfilenums(int fd)
{
lseek(fd,0,SEEK_SET);
unsigned char ch;
while ((read(fd,&ch,sizeof(unsigned char)))==sizeof(unsigned char))
{
printf("%d ",ch);
}
printf("\n\n");
}
int main (int argc, char *argv[])
{
if (argc!=2)
{
printf("USAGE: progname filename\n");
return 1;
}
int stack1[1024],stack2[1024];
pid_t pid1,pid2;
int ret=mkfifo("FIFOUPWARD",0666);
if (ret==-1 && errno == EEXIST)
printf("Notice: FIFOUPWARD ALREADY EXISTS\n");
ret=mkfifo("FIFODOWNWARD",0666);
if (ret==-1 && errno == EEXIST)
printf("Notice: FIFODOWNWARD ALREADY EXISTS\n");
else
if (ret==-1)
{
printf("BAD MKFIFO\n");
return 1;
}
fd= open (argv[1],O_CREAT|O_TRUNC|O_RDWR,0666);
if (fd<0)
{
printf("Bad file open\n");
return 1;
}
fillfile(fd,90);
printfilenums(fd);
Args a={"FIFODOWNWARD","FIFOUPWARD",1,0};
int startb=lseek(fd,-1,SEEK_END);
Args b={"FIFOUPWARD","FIFODOWNWARD",-1,startb};
pid1=clone (clone_func,&stack1[1023],CLONE_VM|CLONE_FILES,&a);
if (pid1<0)
{
printf("BAD CLONE\n");
return 1;
}
pid2=clone (clone_func,&stack2[1023],CLONE_VM|CLONE_FILES,&b);
if (pid1<0)
{
printf("BAD CLONE\n");
return 1;
}
pid_t pid= waitpid(-1,NULL,__WCLONE);
pid=waitpid(-1,NULL,__WCLONE);
printf("END\n");
close(fd);
return 0;
}