 -          
 -          fprintf(stderr, "\n");
 -          fflush(stderr);
-+- (BOOL) _spawnChild: (WOWatchDogChild *) child
-+{
-+  NGActiveSocket *pair[2];
-+  BOOL isChild;
-+  int childPid;
-+  extern char **environ;
-+
-+  isChild = NO;
-+
-+  if ([NGActiveSocket socketPair: pair]) {
-+    childPid = fork ();
-+    if (childPid == 0) {
-+      setsid ();
-+      // stdin = freopen ("/dev/null", "w+", stdin);
-+      // stderr = freopen ("/dev/null", "w+", stderr);
-+      isChild = YES;
-+      [self _cleanupSignalAndEventHandlers];
-+      [self _runChildWithControlSocket: pair[0]];
-+    } else if (childPid > 0) {
-+      [self logWithFormat: @"child spawned with pid %d", childPid];
-+      [child setPid: childPid];
-+      [child setStatus: WOChildStatusSpawning];
-+      [child setControlSocket: pair[1]];
-+      [child setLastSpawn: [NSCalendarDate date]];
-+      // [self logWithFormat: @"parent ready for child: %d", childPid];
-+    } else {
-+      perror ("fork");
-+    }
-+  }
-+
-+  return isChild;
-+}
-+
-+- (void) _ensureNumberOfChildren
-+{
-+  int currentNumber, delta, count, min, max;
-+  WOWatchDogChild *child;
-+
-+  currentNumber = [children count];
-+  if (currentNumber < numberOfChildren) {
-+      delta = numberOfChildren - currentNumber;
-+      for (count = 0; count < delta; count++) {
-+        child = [WOWatchDogChild watchDogChild];
-+        [child setWatchDog: self];
-+        [children addObject: child];
-+        [downChildren addObject: child];
-+      }
-+      [self logWithFormat: @"preparing %d children", delta];
-+  }
-+  else if (currentNumber > numberOfChildren) {
-+    delta = currentNumber - numberOfChildren;
-+    max = [downChildren count];
-+    if (max > delta)
-+      min = max - delta;
-+    else
-+      min = 0;
-+    for (count = max - 1; count >= min; count--) {
-+      child = [downChildren objectAtIndex: count];
-+      [downChildren removeObjectAtIndex: count];
-+      [children removeObject: child];
-+      delta--;
-+      [self logWithFormat: @"%d processes purged from pool", delta];
-+    }
-+
-+    max = [readyChildren count];
-+    if (max > delta)
-+      max -= delta;
-+    for (count = max - 1; count > -1; count--) {
-+      child = [readyChildren objectAtIndex: count];
-+      [readyChildren removeObjectAtIndex: count];
-+      [child terminate];
-+      [child setStatus: WOChildStatusExcessive];
-+      delta--;
-+    }
-+    [self logWithFormat: @"%d processes left to terminate", delta];
-+  }
-+}
-+
 +- (void) _noop
 +{
 +}

-  if ([ud objectForKey:@"WOUseWatchDog"] != nil) {
-    if (![ud boolForKey:@"WOUseWatchDog"])
-      return WOApplicationMain(appName, argc, argv);
-  }
-  
-  /* watch dog */
-  {

+- (int) run: (NSString *) newAppName
+       argc: (int) newArgC argv: (const char **) newArgV
+{
+  NSAutoreleasePool *pool;
+  NSRunLoop *runLoop;
+  NSDate *limitDate;
+  BOOL listening;
+  int retries;
+
+  willTerminate = NO;
+
+  ASSIGN (appName, newAppName);
+  argc = newArgC;
+  argv = newArgV;
+
+  [self _processArguments];
+
+  listening = NO;
+  retries = 0;
+  while (!listening && retries < 5) {
+    listening = [self _prepareListeningSocket];
+    retries++;
+    if (!listening) {
+      [self warnWithFormat: @"listening socket: attempt %d failed", retries];
+      [NSThread sleepForTimeInterval: 1.0];
+    }
+  }
+  if (listening) {
+    [self _setupSignals];
+    [self _ensureWorkersCount];
+
+    // NSLog (@"ready to process requests");
+    runLoop = [NSRunLoop currentRunLoop];
+    terminate = NO;
+
+    while (!terminate) {
+      pool = [NSAutoreleasePool new];
+
+      // [self logWithFormat: @"watchdog loop"];
+      NS_DURING {
+        terminate = [self _ensureChildren];
