0

I'm trying to copy the contents of a file1 into other file2 through fifo. The first four characters I want to write back in the fifo (during reading, not earlier when writing contents from file1 to fifo) and then copy it in the file2 also. But the first four characters don't get appended at back but they get inserted randomly in the middle. My code is

int main( int argc, char* argv[] ) {

    int fdes,fdes1;
    pid_t pid;
    ssize_t numRead;

    char readBuff[1];
    char writeBuff[1];
    int readCounter;
    int c=0;

    umask(0);

    if (mkfifo("ajjp.e",0666) == -1  /*make the fifo*/
        && errno != EEXIST)
    {}

    if( argc < 3 ) {
        printf( "Atleast need 2 params " );
        exit(1);
    }

    int to_copy = open( argv[1], 0 );/* file from which contents are to be copied */
    int oo = creat(argv[2], 0666);/* file created where we've to write contents*/

    if ( to_copy == -1  ) {
        printf( "Opening file failed " );
        exit(1);
    }
    if ( (pid = fork()) < 0) /* child process is made*/
        perror("fork error");

    /* in parent process,I'm cwriting contents of file1 to fifo character by character */
    else if(pid>0)
    {
        fdes = open("ajjp.e", O_WRONLY);
        while( (readCounter = read( to_copy, readBuff, sizeof( readBuff ) ) > 0 ) )  {

            write( fdes, readBuff, sizeof( readBuff ) );
        }
        close(to_copy);

    }
/* now, in child process, I opened its read end then I'm reading contents from fifo and writing it to file2(i.e copy_to here) but for first four characters( c< 5 here), I'm writing them to fifo also by opening its write end. */
    else
    {
        fdes1 = open("ajjp.e", O_RDONLY);

        fdes = open("ajjp.e", O_WRONLY);

        if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
            printf("signal");

        int copy_to = open( argv[2], 0666);/* opened the file where we've to write*/
        if ( copy_to == -1  ) {
            printf( "Opening file failed " );
            exit(1);
        }


        for(;;) {

            c++;
            numRead = read(fdes1, readBuff, sizeof(readBuff));/* reading from read end of fifo*/

            if (numRead == 0)
                break;

            /* write to the file2*/
            if (write(copy_to, readBuff, numRead) != numRead)
            {}
            /* for first 4 characters, I am rewriting to the back of fifo*/
            if(c<5)
            {
                write(fdes,readBuff,sizeof(readBuff));
            }
            /*after writing those 4 characters, write end I've closed*/
            if(c==5)
                close(fdes);
        }
        close(fdes);
        close(fdes1);

    }//end else

    return 0;    
}

Now, if on terminal, I run

$ ./a.out a.txt b.txt

I want to copy from a.txt to b.txt, b.txt contains a.txt plus first 4 characters inserted randomly between characters.

Lorenzo Belli
  • 1,767
  • 4
  • 25
  • 46
priya_ajju
  • 57
  • 1
  • 8
  • Could you address the formatting of your code? It's really hard to understand what's going on as it is at present. – marko Jan 18 '15 at 17:07
  • I've added some comments. Please tell me if still its not decodable. – priya_ajju Jan 18 '15 at 17:55
  • @marko , actually I also don't know when to use fork() and here whether we should use or not. And also since fifo read end block until other process has not opened it for writing and vice-versa. So, I thought to create a child process so that both the processes (child and parent ) will be able to perform read and write. But I don't know, in child process I'm reading and writing both. – priya_ajju Jan 18 '15 at 18:08
  • It's the inconsistent indentation that's the problem. – marko Jan 18 '15 at 22:17

1 Answers1

0

You've got some logic problems and synchronization problems. Your goal isn't too clear, but it seems like you want to copy a file, say "Hello World" and in the copy, it should have "Hello World" but also have "Hell" sprinkled in. So, maybe "HelHleo llWorld"?

Computers are fast and can buffer and do quite a lot at once. Your child process may not even execute until after the parent is completely done because it takes a bit of time to start a new process. As such you are probably getting "Hello WorldHell". That is, the parent totally copies the file to the FIFO before the child even starts reading. You need to look into some synchronization methods. For example, using the tools you have, you could make another fifo. Have the parent wait until it can read from it. Have the child write to it when it is loaded as a way to tell the parent it is ready to go. Making your file really really large might also give the child time to start or adding sleep statements after each character.

It would be easier to speculate if you had provided your input file as well as your output(the wrong output). But, basically, you have a multi-process/multi-threading problem where you want them to operate together but they really end up running one at a time. Slow down the parent or make it wait for the child.

LawfulEvil
  • 2,267
  • 24
  • 46