Re: 12.2: fork() causing getline() to repeat stdin endlessly
Hi,
i can reproduce the problem with the given example after changing
int main(int, char **) {
to
int main(int argc, char **argv) {
in order to get it through the compiler.
(There is also a memory leak about line_buf which does not matter now.)
Not only the read offset of stdin seems to get reset by fork() but also
the line_num conter begins again at 0. (Can be an illusion. See surprise
remedy below.)
This does not happen if i watch the program by gdb. Only if i let it
run freely and printf the line_num counter and the lines, i get after
this change
while (-1 < (num_read = getline(&line_buf, &stg_size, stdin))) {
++line_num;
- printf("%s", line_buf);
- if (num_read != 53) {
- printf("num_read: %ld at line %lu\n", num_read, line_num);
- }
+ printf("pid %d , line %d : %s", (int) getpid(), line_num, line_buf);
pid_t pid = fork();
if (0 == pid) {
exit(0);
}
- else if (pid > 0) {
+ printf("fork() = %d\n", (int) pid);
+ if (pid > 0) {
(void) waitpid(pid, NULL, 0);
}
this output
pid 25511 , line 1
pid 25511 , line 1
fork() = 25513
pid 25511 , line 2
pid 25511 , line 1
fork() = 25513
pid 25511 , line 2
fork() = 25514
pid 25511 , line 3
pid 25511 , line 1
fork() = 25513
pid 25511 , line 2
fork() = 25514
pid 25511 , line 3
fork() = 25515
pid 25511 , line 4
...
Riddles:
- Why no "fork() = " after the lines which show their number for the first
time ?
- Why is it always one line more ?
The phenomenon vanishes if i replace printf() by fprintf(stderr).
Total diff of the changes which did this trick:
------------------------------------------------------------------------
--- getline_fork_orig.c 2023-10-23 08:51:58.788992417 +0200
+++ getline_fork_2.c 2023-10-23 10:37:28.025016315 +0200
@@ -7,7 +7,7 @@
#include <sys/wait.h>
#include <unistd.h>
-int main(int, char **) {
+int main(int argc, char **argv) {
char * line_buf = NULL;
size_t stg_size = 0u;
ssize_t num_read = 0;
@@ -15,9 +15,9 @@ int main(int, char **) {
while (-1 < (num_read = getline(&line_buf, &stg_size, stdin))) {
++line_num;
- printf("%s", line_buf);
+ fprintf(stderr,"%s", line_buf);
if (num_read != 53) {
- printf("num_read: %ld at line %lu\n", num_read, line_num);
+ fprintf(stderr,"num_read: %ld at line %lu\n", num_read, line_num);
}
pid_t pid = fork();
------------------------------------------------------------------------
I am still puzzled ...
Have a nice day :)
Thomas
Reply to: