code: func (c *cmd) startChild(args []string, passStdin, shell bool) error {
  	if c.verbose {
  		c.UI.Info("Starting handler")
  	}
  
  	// Create the command
  	var cmd *osexec.Cmd
  	var err error
  	if !shell {
  		cmd, err = exec.Subprocess(args)
  	} else {
  		cmd, err = exec.Script(strings.Join(args, " "))
  	}
  	if err != nil {
  		c.UI.Error(fmt.Sprintf("Error executing handler: %s", err))
  		return err
  	}
  
  	// Setup the command streams
  	cmd.Env = append(os.Environ(),
  		"CONSUL_LOCK_HELD=true",
  	)
  	if passStdin {
  		if c.verbose {
  			c.UI.Info("Stdin passed to handler process")
  		}
  		cmd.Stdin = os.Stdin
  	} else {
  		cmd.Stdin = nil
  	}
  	cmd.Stdout = os.Stdout
  	cmd.Stderr = os.Stderr
  
  	// Start the child process
  	c.childLock.Lock()
  	if err := cmd.Start(); err != nil {
  		c.UI.Error(fmt.Sprintf("Error starting handler: %s", err))
  		c.childLock.Unlock()
  		return err
  	}
  
  	// Set up signal forwarding.
  	doneCh := make(chan struct{})
  	defer close(doneCh)
  	logFn := func(err error) {
  		c.UI.Error(fmt.Sprintf("Warning, could not forward signal: %s", err))
  	}
  	agent.ForwardSignals(cmd, logFn, doneCh)
  
  	// Setup the child info
  	c.child = cmd.Process
  	c.childLock.Unlock()
  
  	// Wait for the child process
  	if err := cmd.Wait(); err != nil {
  		c.UI.Error(fmt.Sprintf("Error running handler: %s", err))
  		return err
  	}
  	return nil
  }
docs: // startChild is a long running routine used to start and
  // wait for the child process to exit.