skip to Main Content

From the manual page I know that:

exit() flushes output buffers while _exit,_Exit,exit_group don’t.

In the code below, the content of test.log will be hellonhellon only if exit() was called in child process, which is the same as I tested.

But when there’s no statements in child process, it will behave like it’s calling exit(), the content of test.log will be hellonhellon too.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{

    int pid;

    FILE *fp = fopen("test.log", "w");
    fprintf(fp, "hellon");
    pid = fork();
    if (pid == 0)
    {
        // do something
        ;
    }
    else
    {
        wait(NULL);
        exit(1);
    }
}

Through ltrace and strace I can see both parent and child called exit_group.

Since I called exit in parent, so it can be judged by using ltrace that exit will call exit_group.

But in the opposite I can’t judge whether child process called exit.

Does gcc called exit in child process implicitly? It may be harmful to call exit in child process as many people said. If not, then why the buffer was flushed?

Testing gcc and glibc version:

  • gcc version 6.3.0 20170516 (Debian 6.3.0-18+deb9u1)
  • GNU C Library (Debian GLIBC 2.24-11+deb9u4) stable release version
    2.24

2

Answers


  1. Promoting PSkocik’s comment to an answer:

    Returning from main is always equivalent to calling exit(). Either way is supposed to represent "normal" termination of a process, where you want for all the data you buffered to actually get written out, all atexit() cleanup functions called, and so on.

    Indeed, the C library’s startup code is often written simply as exit(main(argc, argv));

    If you want the "harsher" effect of _exit() or _Exit() then you have to call them explicitly. And a forked child process is a common instance where this is what you do want.

    Login or Signup to reply.
  2. But when there’s no statements in child process, it will behave like it’s calling exit(), the content of test.log will be hellonhellon too.

    You have a statement in child process (implicit):

    When child process returns from main(), the C runtime makes a call to exit(0); (or better, something equivalent to exit(main(arc, argv, envp));, indeed) that implies the flushing of buffers you are trying to avoid.

    If you want to eliminate one of the hellons, just fflush(fp); before calling to fork() system call, as the call will duplicate fp in both processes, each with a partially full buffer the same way, and this is the reason you get the buffer contents duplicated. Or better flush all output buffers with fflush(NULL);.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search