3

When the Wine server launches, it creates a Unix socket through open_master_socket(),all Wine processes launched later connects to the Wine server using this socket,here is the code from server/request.c,open_master_socket():

 771     if (!foreground)
 772     {
 773         if (pipe( sync_pipe ) == -1) fatal_perror( "pipe" );
 774         pid = fork();
 775         switch( pid )
 776         {
 777         case 0:  /* child */
 778             setsid();
 779             close( sync_pipe[0] );
 780 
 781             acquire_lock();
 782 
 783             /* close stdin and stdout */
 784             dup2( fd, 0 );
 785             dup2( fd, 1 );
 786 
 787             /* signal parent */
 788             dummy = 0;
 789             write( sync_pipe[1], &dummy, 1 );
 790             close( sync_pipe[1] );
 791             break;
 792 
 793         case -1:
 794             fatal_perror( "fork" );
 795             break;
 796 
 797         default:  /* parent */
 798             close( sync_pipe[1] );
 799 
 800             /* wait for child to signal us and then exit */
 801             if (read( sync_pipe[0], &dummy, 1 ) == 1) _exit(0);
 802 
 803             /* child terminated, propagate exit status */
 804             wait4( pid, &status, 0, NULL );
 805             if (WIFEXITED(status)) _exit( WEXITSTATUS(status) );
 806             _exit(1);
 807         }
 808     }
 809     else  /* remain in the foreground */
 810     {
 811         acquire_lock();
 812     }

acquire_lock() is used to setup the master socket, Question is when run in background,why fork() and let the child process do the work,while the parent just wait and exit()? And why not when run in foreground ?

hello.wjx
  • 239
  • 3
  • 13

2 Answers2

2

"fork() and let the child process do the work" is "run in background".

The pipe is an idiom to let the parent stay around while the child does setup that could fail (in this case, acquiring the lock), and propagate the failure properly if it happens; otherwise, you could not easily find out that the child had failed, but would have to check for its existence or scan log files afterward to see if something had gone wrong.

geekosaur
  • 59,309
  • 11
  • 123
  • 114
  • First thanks for your reply,but I still have something not clear: Do you mean if it run in foregroud,we can see the exit from command line? Why a process can't propagate failure itself?(the child also called exit()). Is this a common trick in server process programming? – hello.wjx Apr 25 '12 at 06:09
  • `exit()` relays its status to the parent. If the process that created it has exited, that parent is pid 1, `init`, which usually has no way to report information about failed processes (aside from, sometimes, `syslog`). In addition, the child has switched to a *daemon*, so it no longer has a connection to the terminal that it could use to report errors (again, it may use `syslog`). During initial startup it can use this idiom to report errors to its parent before it completely detaches from the session that created it so that it can run even after that session exits. – geekosaur Apr 25 '12 at 06:20
1

Yes,Daemon!
Thanks to ninjalj,This is a general method to implement a background running daemon,and let the forked child(the daemon) do the daemon thing. And the parent to use _exit() rather than exit() is to avoid removing temporary file unexpectedly.
For more about daemon,see how to make a process daemon and http://software.clapper.org/daemonize/

And geekosaur explains well why we need wait the child before _exit().

Community
  • 1
  • 1
hello.wjx
  • 239
  • 3
  • 13