I have two programs: primero.c
andsegundo.c
1. When I run ./primero
I get this output:
Mensaje2\n
Mensaje1Mensaje3\n
Mensaje1Mensaje5Mensaje6
2. When I redirect to a file using ./primero > salida.txt
in file I get a different output:
Mensaje2\n
Mensaje1Mensaje5Mensaje6
I do not understand why this output or why it is different when redirecting to a file.
first C
#include <stdio.h>
main(){
printf("Mensaje1");
write(1,"Mensaje2\n",10);
if (fork()){
printf("Mensaje3\n");
execlp("segundo","segundo",0);
printf("Mensaje4");
}
printf("Mensaje5");
}
second C
#include <stdio.h>
main(){
printf("Mensaje6");
}
UPDATE:
I think doing a exec()
flushes the buffer. When the output is standard, the character \n
empties the buffer and prints it to the screen because it is line-buffered. However when it is redirected to the file it is not printed Mensaje3\n
because it is fully buffered.
The hexadecimal content of the file salida.txt
is:
00000000 4d 65 6e 73 61 6a 65 32 0a 00 4d 65 6e 73 61 6a |Mensaje2..Mensaj|
00000010 65 31 4d 65 6e 73 61 6a 65 35 4d 65 6e 73 61 6a |e1Mensaje5Mensaj|
00000020 65 36 |e6|
00000022
The problem suffered is that when executing the instruction
execlp()
, the program being executed is replaced by another without calling the usual end-of-execution processes that empty the output bufferstdout
if it still contains information to be sent, so if something was pending to be sent to some data stream, it is discarded.When the output is standard, the character
\n
causes the buffer to be emptied (sends the text to the terminal) because it is line buffered, printing everything that is pending on the screen. However, when the output is redirected to the file, nothing is printed pending in the buffer (in this caseMensaje3\n
) because it is fully buffered .More information about the behavior of buffering strategies: https://www.gnu.org/software/libc/manual/html_node/Buffering-Concepts.html
In Spanish:
To solve this, add it
setbuf(stdout, NULL)
to the beginning of the programs to disable the use of the buffer instdout
or cause afflush()
before the call toexeclp()
: