0

I am trying a sample program to read the data from the beginning of the file by two processes using the fork().

When fork() is called, kernel creates a child process, and this child process inherits the properties of the parent process. All the open files and the file descriptors. My aim is to read the file from the beginning by both the child and the parent. I tried to create separate descriptors using dup2(), but its not working.

My second question is that is there any way to make the child process to continue processing another task after completing the initial task. (signal has to be send to the parent to ask for another task? and parent will be communicating with the child through pipe or fifo)

 int main(int argc, char* argv[]){
 int fd1,fd2;
 int fd;
 int read_bytes;
 pid_t pid;
 char* buff;

 buff = malloc(sizeof(buff)*5);
 if(argc < 2){
        perror("\nargc: Forgot ip file");
        return 1;
 }

 fd = open(argv[1],O_RDONLY);
 if(-1 == fd){
        perror("\nfd: ");
        return 2;
 }
 pid = fork();
 if(pid == -1){
        perror("\n pid");
        return 1;
 }
 else if(pid == 0){ // CHILD
        dup2(fd1,fd);
        read_bytes = read(fd1,buff,5);
        printf("\n %s \n",buff);
 }
 else{ //PARENT
        wait();
        printf("\n Parent \n");
        dup2(fd2,fd);
        //close(fd);
        read_bytes = read(fd2,buff,5);
        printf("\n %s \n",buff);
 }
 return 0;
}

Please help to understand

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Angus
  • 12,133
  • 29
  • 96
  • 151
  • 1
    You should really, **really** make a shell alias to always compile with as many warnings as possible -- something like "alias gcc='gcc -Wall -Wextra'": this code produces **many** warnings, and listening to them will show at least one^Wthree errors. – loreb Sep 03 '13 at 20:43
  • That being said, the file descriptors are **shared**, which means that actually fd,fd1 and fd2 all refer to the same underlying structure -- reading from one will advance all the others. Fix that and I'm sure someone will come and help you with your second problem :) – loreb Sep 03 '13 at 20:50
  • [`dup()` and `dup2()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.html) create a new file descriptor that references the same open file description as the original file descriptor. If you want separate open file descriptions, open the files separately. That's the way POSIX defines it. See also [`open()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html). – Jonathan Leffler Sep 03 '13 at 21:42
  • `buff = malloc( sizeof buff ...)` is (almost) always an error. You mean `buff = malloc( sizeof *buff ...)`. (I put "almost" in parentheses, but really, it's always an error.) – William Pursell Sep 03 '13 at 22:01

1 Answers1

2

(1) As loreb mention in the comments, dup2 duplicates the file descriptor. To wit from man (2) dup2:

After a successful return from one of these system calls, the old and new file descriptors may be used interchangeably. They refer to the same open file description (see open(2)) and thus share file offset and file status flags; for example, if the file offset is modified by using lseek(2) on one of the descriptors, the offset is also changed for the other.

So you got off to a bad assumption. Just close and open the file second time in the child.

(2) the dup2 signature is int dup2(int oldfd, int newfd). You are doing dup2(fd1, fd) but fd is the descriptor you want to duplicate so you have the parms reversed.

(3) Local variables do not get initialized so

int fd1,fd2;

have random values. When you do dup2(fd1, fd) you are trying to use whatever random value is in fd1 which if it is anything (normally) greater than 1023 is going to cause the call to fail with EBADF.

(4) wait() takes a parameter so it should at least be wait(NULL).

(5) Always check return values on system calls. Your dups, reads, etc., are almost certainly failing.

I would recommend getting this to work and then submitting your second question as a separate post.

Duck
  • 26,924
  • 5
  • 64
  • 92