/* wait3() emulation for MiNT. written by Eric R. Smith and placed in
   the public domain
 */

#include <wait.h>
#include <time.h>
#include <resource.h>
#include <mintbind.h>
#include <errno.h>
#include <signal.h>

extern int __mint;

extern long __waitval;		/* in thread.c */
extern long __waittime;		/* ditto */

extern void _ms2tval();		/* in getrusage.c */

int
wait3(status, mode, rusage)
	union wait *status;
	int mode;
	struct rusage *rusage;
{
	long r, rsc[8];
	int exit_status, sig_term, pid;

	if (__mint == 0) {
		r = __waitval;
		__waitval = -ENOENT;
		rsc[0] = __waittime;
		rsc[1] = 0;
	} else
		r = Pwait3(mode, rsc);
	if (r < 0) {
		errno = -r;
		return -1;
	}
	pid = (r & 0xffff0000L) >> 16;
	if (pid) {
		status->_i = 0;

		if ( ((short)r) == -32) {
			sig_term = SIGINT;
			exit_status = 0;
		}
		else {
			exit_status = r & 0x000000ffL;
			sig_term = (r & 0x00007f00L) >> 8;
		}
		if (sig_term && exit_status != 0 && exit_status != 0177)
			sig_term = 0;
		if (exit_status == 0177 && sig_term) {
			status->w_termsig = WSTOPPED;
			status->w_stopsig = sig_term;
		}
		else {
			status->w_termsig = sig_term;
			status->w_retcode = exit_status;
		}
		status->w_coredump = 0;

		if (rusage) {
			_ms2tval(rsc[0], &(rusage->ru_utime));
			_ms2tval(rsc[1], &(rusage->ru_stime));
		}
	}
	return pid;
}
