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 via email to