#include <time.h>
#ifdef _OS9000
#include <process.h>
#else
#include <procid.h>
#endif
#include <time.h>
#include <unix/os9time.h>
#include <sys/resource.h>
#include <sys/wait.h>


#ifdef _OS9000
int wait3( int *status, int options, struct rusage *use)
{
	pr_desc cproc;			/* current process */
	pr_desc proc_desc;		/* process descriptor pointer */
	u_int32 *chldslot;		/* child slot pointer */
	u_int32 *blkhd;			/* head of storage block list pointer */
	int32 slotcnt;			/* number of slots in current block */
	int pid = getpid();
	struct rusage dummy_use;
	int i, st, clk_tck;
	
	if (!(options & (WNOHANG|WUNTRACED)))
	{
		    return( wait(status) );
	}

	if (!use)
		use = &dummy_use;
	if (!status)
		status = &st;
		
	memset(use, 0, sizeof(struct rusage));

	if (_get_process_desc(pid, (int)sizeof(cproc), &cproc) <= 0)
	{
	   	return(-1);
	}

	/* check for any children */
	if (cproc.p_chldcnt == 0)  return 0;

	/* search process' child-process list(s) for a dead child */
	for (blkhd = (u_int32*)&cproc.p_chldrn[0], slotcnt = CHILDREN; 
															  slotcnt != 0; )  {
		/* search current child block for a dead child */
		for (chldslot = blkhd + 2; --slotcnt >= 0; chldslot += CHILD_SLOTSZ)  {
			
			/* if child present, check its current status */
			if (*chldslot != 0)  {
				if (_get_process_desc(*chldslot, (int)sizeof(proc_desc), &proc_desc) <= 0)
				{
					*chldslot = 0;
				}
				else if (proc_desc.p_state & DEAD)  {
					clk_tck = CLOCKS_PER_SEC;

					use->ru_utime.tv_sec = proc_desc.p_uticks / clk_tck;
					use->ru_utime.tv_usec = (proc_desc.p_uticks % clk_tck) * (1000000 / clk_tck);

					use->ru_stime.tv_sec = proc_desc.p_sticks / clk_tck;
					use->ru_utime.tv_usec = (proc_desc.p_sticks % clk_tck) * (1000000 / clk_tck);

					return( wait(status) );
				}
			}
		}	
		/* move to next child block if there is one & get number of slots */
		slotcnt = (int32)((blkhd = (u_int32*)*(blkhd + 1)) != NULL) ? 
																   CHILDREN : 0;
	}
	return 0 ;
}
#else

#define DEAD 0x0100
/* OS-9 68k */

int wait3( int *status, int options, struct rusage *use)
{
	int pid = getpid();
	struct rusage dummy_use;
	int i, st, clk_tck;
	procid proc;
	
	if (!use)
		use = &dummy_use;
	if (!status)
		status = &st;
		
	memset(use, 0, sizeof(struct rusage));

	if (_get_process_desc(pid, (int)sizeof(procid), &proc) <= 0)
	{
	   	return(-1);
	}

	pid = proc._cid;	/* Erster Child */

	if (pid <= 0)
		return(0);

	clk_tck = CLOCKS_PER_SEC;

	if (options & (WNOHANG|WUNTRACED))
	{
	    do {
		if (_get_process_desc(pid, (int)sizeof(procid), &proc) <= 0)
		{
		   	return(-1);
		}
		
		if (proc._state & DEAD)	/* Test ob Process beendet */
		{
			use->ru_utime.tv_sec = proc._uticks / clk_tck;
			use->ru_utime.tv_usec = (proc._uticks % clk_tck) * (1000000 / clk_tck);

			use->ru_stime.tv_sec = proc._sticks / clk_tck;
			use->ru_utime.tv_usec = (proc._sticks % clk_tck) * (1000000 / clk_tck);

			use->ru_inblock = proc._rbytes;
			use->ru_oublock = proc._wbytes;

			return( wait(status) );
		}

		pid = proc._sid;	/* Brueder vorhanden */
	    } while (pid > 0);

	    return(0);
	}
	else
	    return( wait(status) );

}
#endif

/* Need a different strncmp because of a library but for the X86.
   strncmp("a","a",0); must return 0 in this case, but on a X86 it
   is returning a 1. In PPC and 68k this function returns 0.
   Rewritten strncmp() 27.5.00 KeiT
*/

int strncmp(const char *string1, const char *string2, size_t count)
{
	char *s1 = (char *)string1;
	char *s2 = (char *)string2;
	char a,b;

	if (count == 0) return 0;

	while (count--)
	{
		a = *s1++;
		b = *s2++;

		if (a > b) return 1;
		if (a < b) return -1;
		if (a == 0) return 0;	/* No need to check for b==0 */
	}
	return 0;
}
