1

I have to write a code using fork() function where one file i.e producer will open a DATA.txt file and add a character taken from testfile.txt file and pass the turn to consumer.c file which open the DATA.txt file again and take the character from the file and print it on screen. I know how the logic works but i am stuck with an infinite loop and doesn't know how to get out of it. any help will be appreciated. DATA and TURN cannot have more than one character at a time Following are the file for the program.

output: 
Segmentation fault: 11

...

//main.c file

#include"header.h" //  including the header file

int main(){

FILE* fp = fopen("TURN.txt","w+"); 
if(fp== NULL){
    exit(1); // exit with an error
}
fputc('0',fp) ; // writing to file TURN.txt
fclose(fp); 
// including consumer.c and producer.c files
// now we have access to functions in consumer.c and producer.c

int pid = fork(); 
if(pid == -1) exit(1) ; // Failure exit


if(pid == 0){consumer();}
if(pid != 0){producer();}

return 0 ; // success(Erfolg)}

..

//producer.c file

#include"header.h" 

void producer(){

char t; // for TURN LOOP
char p;

FILE *fp = fopen("testfile.txt", "rt");  

while(!feof(fp)){ 
    do{
        FILE *TURN = fopen("TURN.txt", "rt");  
        t = fgetc(TURN) ; 
        fclose(TUdRN);  // closing turn file
    } while(t!= '0') ; // wait for turn 


    FILE *DATA = fopen("DATA.txt", "w+"); // opening data file to write a  character   in it
    p = fgetc(fp); // getting character from  testfile to write in data file

    fputc(p, DATA); 
    fclose(DATA) ;  // closing data file

    FILE *TURN = fopen("TURN.txt", "r+"); // opening turn file to change the value to 1 and pass the turn to consumer.c

    fputc('1', TURN);  // overwriting 1 in the turn file so now turn as only 1 in it. 
    fp++ ;  // incrementing the file pointer
} // end of the while loop

 fclose(fp);

} ...

#include"header.h" //  including the header file

void consumer (){
char c; 
char t;

while(1){

    do{
        FILE *ft = fopen("TURN.txt","r");  // opening turn file
        t = fgetc(ft) ;  
        fclose(ft) ; // closing the turn file
    } while( t!= '1' ); 

    FILE *dt = fopen("DATA.txt","r");  // opening data file to read from it
    c = fgetc(dt); 
    if(c =='\0'){ 
        break ;  
    }
    //else data file in not empty print the character on the screen in same order as testfile
    printf("%c",c) ; 

    FILE *ft = fopen("TURN.txt","r+"); 
    fputc('0',ft);  // producer.c turn

    //closing both turn and data file
    fclose(dt);  
    fclose(ft) ;
} // end of while loop
} //  end of consumer method

...

// header files for consumer. and producer.c and main.c
#ifndef HEADER_H // Including guards to avoid reimplimentation
#define HEADER_H
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
// function signatures from the producer.c and consumer.c
void producer(); 
void consumer();
#endif // !LIST_H

...

//make file
program: main.o consumer.o producer.o header.h
    gcc -o program main.c consumer.c producer.c
main.o: consumer.c producer.c header.h
    gcc -c consumer.c producer.c
consumer.o: consumer.c header.h
    gcc -c consumer.c
producer.o: producer.c header.h
    gcc -c producer.c
clean:
    rm *.o program.o
Physics3067
  • 57
  • 1
  • 6
  • `fp++; // incrementing the file pointer` This is incorrect. The underlying I/O library takes care of moving the read/write pointers in the file when you do things like `fread(3)` or `fwrite(3)`. A `FILE*` is, from your point of view, an opaque structure which you know nothing about. – bnaecker Dec 01 '17 at 17:29
  • 1
    And if you run your code in a debugger, you should be able to determine the source of the segfault. – bnaecker Dec 01 '17 at 17:30
  • ok thanks for notifying about that. – Physics3067 Dec 01 '17 at 18:28
  • but still the code runs for infinite amount of time . – Physics3067 Dec 01 '17 at 18:39
  • 1
    Also read [Why is “while ( !feof (file) )” always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – pzaenger Dec 01 '17 at 20:57

2 Answers2

1

There are several problems with your code.

First of all, you should check whether your FILE pointers return NULL, because the fopen() function may fail and then returns NULL.

Secondly, your segmentation fault happens because you fp++, but you only fopen()'ed one file at that memory location. Incrementing pointers only works when you are working with pointers to arrays.

Thirdly, while playing around with the source, I noticed you seem to have wrong assumptions about fgetc(). If that function fails, it returns the EOF constant. However, this EOF constant is usually greater than the range of values which valid returned bytes may have, therefore the return value of fgetc() is of type int, to be able to indicate so.

EDIT: I replaced my previous, arguably pretty terrible reseponse. The comments beneath basically refer to my error in copy-pasting where the producer ended up waiting for '1', which gave me a wrong impression about the situation.

mar77i
  • 90
  • 6
  • So what do you advise me to do in that situation because i can't figure out how to resolve that issue ? – Physics3067 Dec 01 '17 at 18:27
  • I thought I had the problem, though it turns out producer is indeed waiting for '0', I somehow came to think it wrongly waited for '1'. However, the problem with the source after trying to build it and running it against valgrind is that there's a meaningless instruction in producer.c: `fp++`. Not only does it do nothing useful, it also causes the segfault you're expriencing. – mar77i Dec 02 '17 at 00:55
  • I also produced a working version from your code you can see here: https://gist.github.com/mar77i/d78fd8728225e3eead1d3645414ecfb5 – mar77i Dec 02 '17 at 01:28
1

You should make your parent process wait for its child. Try this:

pid = fork();
if(pid < 0){
//print some kind of error
} else if(pid == 0){
        producer();
        exit(0);
} else if(pid > 0){
        wait(&childStatus);// wait for the child to finish
        consumer();
}

*childStatus is a normal int variable that is being assigned in the blocking wait function.

orpris12
  • 156
  • 3