>1. waitpid() ожидает только процесс с указанным в его параметре идентификатором. Какой 
>идентификатор Вы указываете? 
Примерно вот так:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <setjmp.h>
#define MAX_EPRG_ARGS   10
#define MAX_LEN   5000
#define EXT_PRG_TIMEOUT   30 /* Seconds */
/* For signal processing */
pid_t pid_to_kill   = (-1);
jmp_buf env;
void sig_alrm (int dummy)
{
 if (pid_to_kill>0)
  {
   kill (pid_to_kill,9); /* Kill it */
   longjmp (env,1);
  }
}
int execute (char * ext_prg, 
 char * ext_arg, 
 char * ext_output, 
 size_t bufsize)
 {
  int rcode = -1;
  int Pipe [2];
  int status = 0;
  char * ARGUMENTS [MAX_EPRG_ARGS]; 
  char temp_str [5000];
  int i=0;
  int ret_wpd = -1;
  char data [2];
  sig_t prev;
  /* Clear the buffer */
  memset (ext_output,0,bufsize);
  prev=signal (SIGALRM,sig_alrm);
  if (setjmp(env)!=0)
  {
   /* Here returns longjmp */
   if (pid_to_kill>0)
   {
    /* Return the prev sigaction */
    signal (SIGALRM,prev);
    snprintf (temp_str,sizeof(temp_str)-1,"execute(): Timeout waiting external program termination, killing pid: %lu",pid_to_kill);
    write_log (temp_str);
    close (Pipe[0]);
    close (Pipe[1]);
    return (-1);
   }
  }
  if (pipe(Pipe)==-1)
   {
    snprintf (temp_str,sizeof(temp_str)-1,"execute(): Cannot create pipe: '%s' !\n",strerror(errno));
    write_log (temp_str);
    return (-1);
   }
 
  memset (&temp_str,0,sizeof(temp_str));
  if ((rcode=fork ())==0)  /* Child */
   {
    for (i=0;i<=MAX_EPRG_ARGS-1;i++) ARGUMENTS[i]=NULL;
    ARGUMENTS[0]=ext_prg;
    ARGUMENTS[1]=strtok (ext_arg, " \t");    
    if (ARGUMENTS[1]!=NULL)
     {
       for (i=2;i<=MAX_EPRG_ARGS-1;i++)
        {
         ARGUMENTS[i]=strtok (NULL, " \t");    
         if (ARGUMENTS[i]==NULL) break;
        }
     }
    /* First close the read end of the pipe */
    close (Pipe[0]);     
    /* Make a dup */
    if (dup2(Pipe[1],1)==-1)
     {
      snprintf (temp_str,sizeof(temp_str)-1,"execute(): 'Dup2' command failed: '%s' !\n",strerror(errno));
      write_log (temp_str);
      close (Pipe[0]);
      close (Pipe[1]);
      exit (253); 
     }
    
    if (execv(ext_prg,ARGUMENTS)==-1)
     {
      snprintf (temp_str,sizeof(temp_str)-1,"execute(): Cannot execute external programm: '%s', Error: '%s' !\n",ext_prg,strerror(errno));
      write_log (temp_str);
      close (Pipe[0]);
      close (Pipe[1]);
      exit (253); /* Parent will get return status: 253 */
     }
    close (Pipe[1]);
   }
  
  if (rcode==-1)  /* Parent */
   {
    snprintf  (temp_str,sizeof(temp_str)-1,"execute(): 'Fork' command failed: '%s' !\n",strerror(errno));
    write_log (temp_str);
    close (Pipe[0]);
    close (Pipe[1]);
    return -1;
   }
  /* Prepare for signal processing */
  pid_to_kill=rcode;
  
  alarm (EXT_PRG_TIMEOUT);
  if (waitpid (rcode,&status, (WUNTRACED))==-1)
   {
    snprintf (temp_str,sizeof(temp_str)-1,"execute(): 'Waitpid' command failed: '%s' !\n",strerror(errno));
    write_log (temp_str);
    close (Pipe[0]);
    close (Pipe[1]);
    return -1;
   }
  /* First close the write end of the pipe */
  close (Pipe[1]);     
  memset (&data,0,sizeof(data));
  while (read(Pipe[0],data,1)>0)
  {
   if (strlen(ext_output)<(bufsize-1)) strcat (ext_output,data);
   memset (&data,0,sizeof(data));
  } 
  alarm (0); /* Stop the timer */
  
  signal (SIGALRM,prev); /* Return the prev sigaction */
  if (WIFEXITED(status))
   {
    rcode=WEXITSTATUS (status);
    if (rcode==253) goto L1;
    else 
    {
     close (Pipe[0]);
     return (rcode);
    }
   }
 L1:
  snprintf (temp_str,sizeof(temp_str)-1,"execute(): Abnormal child termination !\n");
  write_log (temp_str); 
  close (Pipe[0]);
  close (Pipe[1]);
  return -1;
} 
Данный код прекрасно работает если execute() вызвать в одном процессе. Но стоит сделать fork() и вызвать execute() в childe, waitpid всегда возвращает -1 и  ECHILD.
>2. Как задан обработчик сигнала SIGCHLD? Если SIG_IGN, то Вы будете всегда 
>получать ECHILD. 
Никак. Я вообще нигде его не переопределяю.