-1

I have a problem with dup and dup2.

int copy (char * file1, char * file2) {
        int dr = open(file1, O_RDONLY);
        if (dr == -1) {
                return -1;
        }

        int dw = open(file2, O_WRONLY|O_TRUNC|O_CREAT, 0644); 
        if (dw == -1) {
                return -1;
        }

        int save0 = dup(0); 
        int save1 = dup(1); 

        dup2(dr, 0); 
        close(dr); 

        dup2(dw, 1); 
        close(dw); 

        char c;
        while ((c = getchar()) != EOF) {  
                putchar(c); 
        }

        dup2(save0, 0); 
        dup2(save1, 1); 

        printf("Hi");
        return 0;
}

I don't understand why the data from my file file1 is displayed on the screen because dr is standard input and dw is standard output...

Thanks for the help.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • You didn't flush stdout before you switched out the underlying file descriptor. The call to `putchar` put the data in a buffer. Then you switch the underlying fd to be the original stdout. Then the buffer is flushed. – William Pursell Dec 22 '20 at 22:02
  • And `char c;` is wrong when used in `while ((c = getchar()) != EOF)`. `EOF` is an `int` value that can not match any `char` value, which is why `getchar()` returns and `int` and not a `char`. By cramming the returned value into a `char`, you can not reliably detect `EOF`. You also need to check the return values from all your `dup()` and `dup2()` calls - if you run up against an open file descriptor, they can and will fail. – Andrew Henle Dec 22 '20 at 22:39

1 Answers1

3

You (probably) just need to flush the buffers:

while ((c = getchar()) != EOF) {  
        putchar(c); 
}
fflush(stdout);   /* Actually write to the file */
dup2(save0, 0); 
dup2(save1, 1);

Since you haven't included the full code, it's hard to be certain. Also, make sure you haven't done any read-like functions (eg fread, fgetc, etc) on stdin before this function is called.

William Pursell
  • 204,365
  • 48
  • 270
  • 300