[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Fork & write stdout, menu, bug 42051



This relates to bug 42051. Menu 2.1.2-1 (update-menus) seems to hang,
when dpgk runs it.

I've putten a discription of this in 
http://joostje.op.het.net/menu/index.html

For those that don't like to browse, here's the lynx -dump output:


The problem is in the code that forks to the background etc.
  * update-menus needs to try to lock a file, and, depending on
    whether that lock failed abort all action, or continue waiting for
    dpkg to finish.
  * This waiting needs to be done in the background, control needs to
    be returned to dpkg. (or the postinst script that called
    update-menus)
    
The following code could be used:
-----------------
if(child=fork())
  /* parent */
  exit(0);
else {
   /* child  */
   if(lock_file()){
     printf("Just locked the file. Will wait for dpkg to finish, then\n");
     printf("write the output to file /tmp/update-menus.%i\n",getpid());
     wait_for_dpkg_and_do_whatever();
     exit(0);
   }
}
----------------
However, the problem with that is that the exit(0) in the parent may
well happen before the child wrote to stdout. So, users will see the
output of the child printed mingled with the output of dpkg. To
prevent that, I made the child send a signal to the parent after it
has printed to stdout, and before it starts waiting for dpkg. The
parent has a signal hadnler for the sent signal that will call
exit(0), and will not exit before it recieves the signal.
----------------
void function exit_on_signal(int signr){
  exit (0);
}

/* ... */

signal(SIGUSR1,exit_on_signal);
parentpid=getpid();
if((child=fork()))
  /* parent */
  sleep(1000);        /*actually a loop */
else {
  /* child */
  if(lock_file()){
     printf("Just locked the file. Will wait for dpkg to finish, then\n");
     printf("write the output to file /tmp/update-menus.%i\n",getpid());
     kill(parentpid,SIGUSR1);
     wait_for_dpkg_and_do_whatever();
     exit(0);
  }
}
----------------
However, this code seems to also have a side-affect: for some reason
it appears that (irreproducably) sometimes the signal isn't sent, or
at least it isn't recieved by the parent. I have no idea why.

If anyone has a better idea to solve the problem, or any hints, please
email me!

joostje


Reply to: