so in this code snippet a process forked a child process. the child process calculated a random number r, and called linux command 'head -r "file' with an exec function which destroys the process itself, but to send the result back to the parent process the child process first duplicated the writing end of a pipe p, shared with the parent process and then closed both ends of the pipe p and closed the stdout file descriptor too...after execlp the parent process could read the result of the command 'head -r "fil2"' from the pipe p. How is this possible?
if (pid == 0) { /* code of child */ srand(time(NULL)); nr=atoi(argv[(i*2)+2]); r=mia_random(nr); //calc random value close(1); //closing standard output??? dup(p[1]); //duplicating write end of inherited pipe from parent close(p[0]);//closing read end of inherited pipe close(p[1]);//closing write end of inherited pipe //creating a variable to hold an argument for `head` sprintf(option, "-%d", r); //calling head on a file given as argument in main execlp("head", "head", option, argv[(i*2)+1], (char *)0); /* must not be here anymore*/ /* using perror to check for errors since stdout is closed? or connected to the pipe?*/ perror("Problem esecuting head by child process"); exit(-1); } Why wasn't the result of head written to stderr instead? How come it was written to the dup(p[1])???
srand(time(NULL))is not really random at all, it's entirely predictable what those values will be. If actual randomness is important, avoid using that family of functions and use one that's actually random, or read data from/dev/random.dup, it successfully duplicated the write end of the pipe on file descriptor 1. Check the return value ofdup. Also, try running the code without closing stdout before you calldup. Also, try the code withdup2.