0

I cannot figure out why does this program display only garbage characters when trying to print (at the standard output) some data read from both a file and a pipe. It is interesting that this problem occurs only when I use more than one dup2 instruction within the same process.

#define BSIZE 256

const char in[] = "i.txt";

int main(){
    int id, fd[2];
    pipe(fd);
    id = fork();
    if(id == 0){
        close(fd[0]);
        dup2(fd[1],1);
        printf("blbl");
        close(fd[1]);
    }
    if(id != 0){
        close(fd[1]);
        char tmp[BSIZE];
        int f = open(in,O_RDONLY);
        dup2(f,0);
        fgets(tmp,BSIZE,stdin);
        puts(tmp);
        dup2(fd[0],0);
        fgets(tmp,BSIZE,stdin);
        puts(tmp);
        close(fd[0]);
        close(f);
        wait(NULL);
    }
    return 0;
}
pauk
  • 350
  • 4
  • 15
  • `open(in,O_RDONLY | O_CREAT | O_TRUNC,0777);` is a very odd way to open an input file, since the `O_TRUNC` flag causes the file's contents to be discarded. Normally, you would only use `O_CREAT | O_TRUNC` with an output file, in which case you would probably have `O_WRONLY` rather than `O_RDONLY`. Beyond that, I have no idea what you mean by "it works" or "it doesn't work". What does it do, exactly? What did you expect it to do? – rici Oct 18 '22 at 05:49
  • I expect to receive a reasonable output. To be more specific I want to be able to output both the contents of that specific file and the message sent by the child process. If a do not make one of those dups and one reading is made from the console and the other reading is made either from that pipe or from that file, all goes fine, the process displays those character arrays correctly. But if I keep both dup2s, than I receive only garbage characters on the screen. – pauk Oct 18 '22 at 06:18
  • Indeed, those macros are useless. I removed them in order to keep the code as clean and robust as possible. – pauk Oct 18 '22 at 06:22
  • If you remove `dup2(f, 0)` then you can't possibly print the contents of the file; `stdin` will be read. So the program won't display the contents of the file, which contradicts your statement that they are "displayed correctly". With the `O_TRUNC` macro in place, you couldn't print the file's contents either. So that's not a clear definition. – rici Oct 18 '22 at 06:46
  • It is not important where do I read from. It is important that if I read some data by using dup2 twice, than I get troubles. For example: if I read from the input console (by removing dup2(f,0)) the executable will display on the screen the very chars which I have just introduced. Moreover, If I get rid of the second dup2, than I will get on the screen two lines of chars read from that file. The point is that without using two dup2 all goes fine, the text is read correctly. In return, if I perform two dup2, the chars are not read properly. – pauk Oct 18 '22 at 06:55
  • Yes...that's one reason I removed the O_TRUNC macro. However, the program has the same issue: two dup2s make the readings improperly. Also, I have just modified the post in order to clear the things up. – pauk Oct 18 '22 at 07:20
  • It seems that an fflush(stdin) between the first puts and the second dup2 solved the problem. Moreover, I can see a similar behavior when writing in a file. It seems that a fflush(stdout) between the dup2s must be executed in order to get a correct outcome. – pauk Oct 18 '22 at 12:17
  • [fflush(stdin) is Undefined Behavior.](https://stackoverflow.com/q/2979209/7509065) – Joseph Sible-Reinstate Monica Oct 19 '22 at 02:54
  • It was my fault...It works without that fflush(stdin). The real issue was that O_TRUNC I suppose...In order to check out the behavior of dup2 I wrote some data in two different files. In order to do this I used dup2 twice, for both writings. Then, I noticed that all the data was to be written only in the second file. Thus, I used a fflush(stdout) between the two writings and then all was fine. Consequently, I made a similar change in the previous program and I ascertained that after that moment all was up and running even that previous program. But the real issue was the O_TRUNC... – pauk Oct 19 '22 at 07:53
  • I will correct this topic soon. – pauk Oct 19 '22 at 07:56

0 Answers0