/* This file is part of Lcrzo.
*/

int lcrzo_priv_wait_process_wait(lcrzo_process *pprocess, 
                                 lcrzo_time *pmaxwaitingtime, 
                                 lcrzo_bool *pevent)
#if defined LCRZODEF_SYSTEM_Unix
{ int ret, status;

  /* parameter verification */
  if (pprocess==NULL) return(LCRZO_ERR_PANULLPTR);
  if (pmaxwaitingtime==NULL) return(LCRZO_ERR_PANULLPTR);

  /* immediate exit */
  if (pprocess->hasended)
  { if (pevent!=NULL) *pevent=LCRZO_TRUE;
    return(LCRZO_ERR_OK);
  }

  /* wait for it */
  if ( pmaxwaitingtime->sec==LCRZO_WAIT_INFINITE_VAL && 
       pmaxwaitingtime->usec==LCRZO_WAIT_INFINITE_VAL )
  { /* infinite wait */
    ret=waitpid(pprocess->processid, &status, 0);
    if (ret==-1) return(LCRZO_ERR_FUWAITPID);
    /* should return the pid */
    if (ret!=(int)pprocess->processid) return(LCRZO_ERR_FUWAITPID);
  }
  else
  { /* nodelay wait (don't know how to wait for a specified amount of time) */
    ret=waitpid(pprocess->processid, &status, WNOHANG);
    if (ret==-1) return(LCRZO_ERR_FUWAITPID);
    if (ret==0)
    { /* no child end */
      if (pevent!=NULL) *pevent=LCRZO_FALSE;
      return(LCRZO_ERR_OK);
    }
  }

  /* the child exited */
  if (pevent!=NULL) *pevent=LCRZO_TRUE;
  pprocess->hasended=LCRZO_TRUE;

  /*printf("Status : normalexit(%d)->return%d signalexit(%d)->received%d\n",
	 WIFEXITED(status), WEXITSTATUS(status), 
	 WIFSIGNALED(status), WTERMSIG(status));*/
  if (WIFEXITED(status))
  { pprocess->returnedvalue=WEXITSTATUS(status);
  }
  else
  { pprocess->returnedvalue=LCRZO_ERR_OKPROCESSABRUPTTERM;
  }

  return(LCRZO_ERR_OK);
}
#elif defined LCRZODEF_SYSTEM_Windows
{ DWORD err, msec, threadreturn;
  lcrzo_bool event;

  /* immediate exit */
  if (pprocess->hasended)
  { if (pevent!=NULL) *pevent=LCRZO_TRUE;
    return(LCRZO_ERR_OK);
  }

  /* wait during the specified time */
  lcrzo_er(lcrzo_priv_wait_winmsec_init_time(pmaxwaitingtime, &msec));
  err=WaitForSingleObject(pprocess->threadhandle, msec);

  /* no data to read */
  if (err==WAIT_TIMEOUT)
  { event=LCRZO_FALSE;
  }
  else if (err!=WAIT_OBJECT_0)
  { return(LCRZO_ERR_FUWAITFORSINGLEOBJECT);
  }

  /* try to get exit code */
  if ( ! GetExitCodeThread(pprocess->threadhandle, &threadreturn) )
  { return(LCRZO_ERR_FUGETEXITCODETHREAD);
  }

  if (threadreturn==STILL_ACTIVE)
  { event=LCRZO_FALSE;
  }
  else
  { event=LCRZO_TRUE;
    pprocess->hasended=LCRZO_TRUE;
    pprocess->returnedvalue=threadreturn;
  }

  if (pevent!=NULL) *pevent=event;
  return(LCRZO_ERR_OK);
}
#else
 #error "Unknown value for LCRZODEF_SYSTEM"
#endif

