C/C++ linux fork() and exec()

11,454

Remember that stdio(3) is buffered. Always call fflush(NULL); (see fflush(3) for more) before fork. Add a \n (newline) at end of every printf(3) format string (or else, follow them by fflush(NULL); ...).

The function execl(3) (perhaps you want execlp?) can fail (so sets errno on failure).

} else if (pid == 0) {
   printf("Child process\n");
   fflush(NULL);
   execl("/bin/foo", "foo", "arg1", NULL);
   // if we are here execl has failed 
   perror("Launch process fail");
}

On error, fork(2) fails by returning -1 and sets errno(3) (see also perror(3) and strerror(3)). So your last else should be

} else {
    perror("Can't create child process");
    fflush(NULL);
}

You might want to use strace(1) (notably as strace -f yourprog ...) to understand the involved syscalls (see syscalls(2)...)

Your WriteLog should probably use strerror (on the errno value saved at beginning of WriteLog ....). I suggest something like

 void WriteLog(const char* msg) {
   int e = errno;
   if (e) 
     syslog (LOG_ERR, "%s [%s]", msg, strerrno(e));
   else
     syslog (LOG_ERR, "%s", msg);
 }

See syslog(3).

There are limits on the number of fork-ed processes, see setrlimit(2) with RLIMIT_NPROC and the bash ulimit builtin.

Read also Advanced Linux Programming.

Share:
11,454
bm2i
Author by

bm2i

Updated on July 23, 2022

Comments

  • bm2i
    bm2i almost 2 years

    I'm use fork() to create child process. From child process I am use exec() to launch new process. My code as below:

       ......
       pid = fork();
       if (pid > 0) {
           WriteLog("Parent Process");
           //Do something
       } else if (pid == 0) {
           WriteLog("Child process");
           int return = execl(ShellScript);
           if ( return == -1 ) 
              WriteLog("Launch process fail");
       } else {
           WriteLog("Can't create child process");
       }
       ......
    

    Note: WriteLog function will be open file, write log, and close file. (It is flushed) ShellScript will launch new process c/c++.

    I run my program for long run and the code above is called many times. And sometime (rarely) there are problem happen that the new process can't launch successful although the child process is created successfully (I have checked carefully). And one thing is extremely misunderstand when this problem happen that the "Child process" log can't printed although the child process is created successful.

    In normal case (there are not error happen) the number of times print the "Child process" and "Parent process" log are the same.

    In abnormal case, they are not the same although the child process always create successfully.The "Launch process fail" and "Can't create child process" log aren't printed in this case. Please help me for consult.

  • bm2i
    bm2i about 10 years
    I'm sorry for my code is not clearly. I have just updated. I have thinked about fflush everytime write log I also flush. So I have used file to write log. And the log isn't still printed when launch process fail while child process is created successful. (I check this thing based on kill(childid) function
  • bm2i
    bm2i about 10 years
    I will try to use strerror and errno. Current my system also use syslog and log file to print log. I will try use it. Thank you for a good idea.
  • bm2i
    bm2i about 10 years
    At the same time the forked processes are always less than 7. So I think it's not over limit
  • jfs
    jfs about 10 years
    the statement if ( return == -1 ) seems unnecessary: execl doesn't return unless it fails.
  • bm2i
    bm2i about 10 years
    The syslog has not still printed when excel launch new process fail although child process launch success. The errno in syslog is always success. It seem to be the system resource is not enough to do anything more :(. I think that :).
  • Basile Starynkevitch
    Basile Starynkevitch about 10 years
    Use strace and gdb