home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Internet MPEG Audio Archive
/
IMAA.mdf
/
util
/
dos
/
l3v100n
/
rsx
/
source
/
sysemx.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-19
|
21KB
|
929 lines
/* This file is SYSEMX.C
**
** contains :
**
** - int21 32bit handler (called from adosx32.asm)
** - int21 emx syscall handler
**
** Copyright (c) Rainer Schnitker 92,93
*/
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <string.h>
#include <malloc.h>
#include <io.h>
#include <time.h>
#include <bios.h>
#include <fcntl.h>
#include <sys/timeb.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef __TURBOC__
#define SH_DENYWR O_DENYWRITE /* for Borland compiler */
#else
#include <share.h>
#endif
#include "DPMI.H"
#include "DPMIDOS.H"
#include "PROCESS.H"
#include "SIGNALS.H"
#include "GNUAOUT.H"
#include "START32.H"
#include "CDOSX32.H"
#include "COPY32.H"
#include "EXCEP32.H"
#include "RSX.H"
#include "PTRACE.H"
#include "TERMIO.H"
#include "DOSERRNO.H"
static DWORD can_run_emx = 0x302e3868; /* ascii = 0.8h */
static int time_reached(unsigned long time)
{
if (time <= time_tic)
return 1;
else
return 0;
}
static void set_ecx_error(int err)
{
EAX = -1L;
if (npz->p_flags & PF_DJGPP_FILE)
err = errno_djgpp(err);
ECX = (long) err;
}
static void set_no_error(void)
{
EAX = ECX = 0L;
}
static void set_eax_return(DWORD reg_eax)
{
EAX = reg_eax;
ECX = 0L;
}
/* oldbrk_eax sbrk(inc_edx) ; err:eax=-1 */
static int sys_emx00_sbrk(void)
{
EAX = getmem(EDX, npz);
return CARRY_NON;
}
/* eax=0 brk(newbrk_edx) ; err:eax=-1 */
static int sys_emx01_brk(void)
{
if (EDX <= npz->brk_value)
EAX = -1L;
else if ((EAX = getmem(EDX - npz->brk_value, npz)) != -1L)
EAX = 0L;
return CARRY_NON;
}
/* maxbrk_eax ulimit(cmd_ecx,newlimit_edx) errno:ecx */
static int sys_emx02_ulimit(void)
{
if (ECX == 3L) {
FREEMEMINFO fm;
GetFreeMemInfo(&fm);
set_eax_return(fm.LargestFree + npz->brk_value);
} else
set_ecx_error(EMX_EINVAL);
return CARRY_NON;
}
/* emx special: void vmstat() */
static int sys_emx03_vmstat(void)
{
return CARRY_NON;
}
/* eax=filepermmask umask(edx) ; err:- */
static int sys_emx04_umask(void)
{
EAX = EDX;
return CARRY_NON;
}
/* eax getpid(void) err:- */
static int sys_emx05_getpid(void)
{
EAX = (DWORD) npz->pid;
return CARRY_NON;
}
/*
** eax = spawnve(proc_env *edx) err:carry errno:eax
*/
static int sys_emx06_spawn(void)
{
int i, ret;
PROCESS_ENV pe;
static char filename[256];
char **argp = NULL, **envp = NULL;
char *envmem = NULL, *argmem = NULL;
/* get process data, check mode */
cpy32_16(DS, EDX, &pe, (DWORD) sizeof(PROCESS_ENV));
pe.mode &= 0xff;
if (pe.mode == P_SESSION || pe.mode == P_DETACH) {
EAX = EMX_EINVAL;
return CARRY_ON;
}
/* get args and env from caller */
if ((argp = (char **) malloc((pe.arg_count + 1) * sizeof(char *))) == NULL
|| (envp = (char **) malloc((pe.env_count + 1) * sizeof(char *))) == NULL
|| (argmem = (char *) malloc((pe.arg_size + 1) & ~1)) == NULL
|| (envmem = (char *) malloc((pe.env_size + 1) & ~1)) == NULL
) {
printf("argmem,envmem to large a:%d e:%d\n", pe.arg_size, pe.env_size);
if (argp != NULL)
free(argp);
if (envp != NULL)
free(envp);
if (argmem != NULL)
free(argmem);
if (envmem != NULL)
free(envmem);
EAX = EMX_E2BIG;
return CARRY_ON;
}
/* get args from user ds, built arg-vector */
cpy32_16(DS, pe.arg_off, argmem, (DWORD) pe.arg_size);
for (i = 0; i < (int) pe.arg_count; i++) {
argmem++; /* skip flag */
argp[i] = argmem;
argmem += (strlen(argp[i]) + 1);
}
argp[i] = NULL;
/* get env from user ds, built env-vector */
cpy32_16(DS, pe.env_off, envmem, (DWORD) pe.env_size);
for (i = 0; i < (int) pe.env_count; i++) {
envp[i] = envmem;
envmem += (strlen(envp[i]) + 1);
}
envp[i] = NULL;
/* get filename */
strcpy32_16(DS, pe.fname_off, filename);
/* load a.out prg */
ret = exec32(pe.mode, filename, pe.arg_count, argp, pe.env_count, envp);
/* if error, try a real-mode prg */
if (ret == EMX_ENOEXEC && pe.mode == P_WAIT)
ret = realmode_prg(filename, argp, envp);
free(argmem);
free(envmem);
free(argp);
free(envp);
/* check error and return */
if (ret) {
EAX = (DWORD) ret;
return CARRY_ON;
} else
return CARRY_OFF;
}
static int sys_emx07_unused(void)
{
return CARRY_NON;
}
/* eax ptrace(ebx,edi,edx,ecx) err:ecx!=0 eax=-1 */
static int sys_emx08_ptrace(void)
{
int ret;
DWORD data;
WORD pid_now = npz->pid;
if ((ret = do_ptrace(BX, DI, EDX, ECX, &data)) != 0)
set_ecx_error(ret);
else if (pid_now == npz->pid) /* save if same process */
set_eax_return(data);
return CARRY_NON;
}
/* eax=child_id wait(status_edx) ; errno:ecx */
static int sys_emx09_wait(void)
{
int ret;
WORD status;
if ((ret = sys_wait(&status)) != -1) {
EDX = (DWORD) status;
set_eax_return((DWORD) (unsigned) ret);
} else
set_ecx_error(EMX_ESRCH);
return CARRY_NON;
}
/* get emx-version ; err:- */
static int sys_emx0a_version(void)
{
EAX = can_run_emx;
if (dpmi10)
EBX = 1L << 8; /* dpmi 0.9 bit */
else
EBX = 1L << 7; /* dpmi 1.0 bit */
ECX = 0L; /* emx revision */
EDX = 0L;
return CARRY_NON;
}
/* eax_pages memavail(void) ; err:- */
static int sys_emx0b_memavail(void)
{
FREEMEMINFO fm;
GetFreeMemInfo(&fm);
EAX = fm.MaxUnlockedPages;
return CARRY_NON;
}
/* (*prevh) signal(signo_ecx,address_edx) err:eax=-1 */
static int sys_emx0c_signal(void)
{
if (ECX >= MAX_SIGNALS || ECX == SIGKILL) {
EAX = SIG_ERR;
return CARRY_NON;
}
EAX = npz->sigs[CX]; /* return prev handler */
if (EDX == SIG_DFL || EDX == SIG_IGN)
npz->sigs[CX] = EDX;
else if (EDX == SIG_ACK)
npz->sig_ack &= ~(1L << CX);
else if (verify_illegal(npz, EDX, 4)) /* user handler */
EAX = SIG_ERR;
else
npz->sigs[CX] = EDX;
return CARRY_NON;
}
/* eax=0 kill(id_edx,signo_ecx) errno:ecx eax=-1 */
static int sys_emx0d_kill(void)
{
NEWPROCESS *p;
if (!(p = find_process(DX))) {
set_ecx_error(EMX_ESRCH);
return CARRY_NON;
} else if (send_signal(p, CX)) {
set_ecx_error(EMX_EINVAL);
return CARRY_NON;
} else
set_no_error();
/* to simulate multitasking, we switch to child */
if (p->pptr->pid == npz->pid) {
npz->p_status = PS_SYS_KILL;
switch_to_process(p);
npz->p_status = PS_RUN;
}
return CARRY_NON;
}
/* eax raise(ecx) errno:ecx eax=-1 */
static int sys_emx0e_raise(void)
{
if (send_signal(npz, CX))
set_ecx_error(EMX_EINVAL);
return CARRY_NON;
}
/* oldflags uflags(mask=ecx,new=edx) */
static int sys_emx0f_uflags(void)
{
return CARRY_NON;
}
/* void unwind(void) err:no */
static int sys_emx10_unwind(void)
{
return CARRY_NON;
}
/* core(handle_ebx) err:carry errno */
static int sys_emx11_core(void)
{
EAX = EMX_EINVAL;
return CARRY_ON;
}
/* portaccess(ecx,edx) ecx=first edx=last, err:cy errno:eax */
static int sys_emx12_portaccess(void)
{
/* dpmi-server must allow this */
ECX = 0L; /* first port *
EDX = 0x3ffL; /* last port */
EAX = 0L;
return CARRY_OFF;
}
/* eax memaccess(ebx,ecx,edx) err:carry errno:eax */
/* under DPMI it's better to used a different segment */
/* memaccess destroy protection -> limit 0xffffffff */
/* must use wrap-around to access memory */
static int sys_emx13_memaccess(void)
{
if (opt_memaccess && ECX <= 0xFFFFFL) {
EAX = EBX - npz->memaddress;
return CARRY_OFF;
} else {
EAX = EMX_EINVAL;
return CARRY_ON;
}
}
/*
** eax = ioctl2(ebx,ecx,edx) errno:ecx eax=-1
*/
static int sys_emx14_ioctl(void)
{
int i, ret;
long temp;
if ((ECX >= TCGETA && ECX <= TCFLSH) || ECX == FIONREAD) {
if (EBX == 0) {
if (!(ret = kbd_ioctl(CX, EDX)))
set_no_error();
else
set_ecx_error(ret);
} else
set_ecx_error(EMX_EBADF);
} else if (ECX == FGETHTYPE) {
tr.eax = 0x4400;
tr.ebx = EBX;
if (realdos())
set_ecx_error(EMX_EBADF);
else {
i = (WORD) tr.edx;
if (!(i & 128))
temp = HT_FILE;
else if (i & 3)
temp = HT_DEV_CON;
else if (i & 4)
temp = HT_DEV_NUL;
else if (i & 8)
temp = HT_DEV_CLK;
else
temp = HT_DEV_OTHER;
set_no_error();
store32(DS, EDX, temp);
}
} else
set_ecx_error(EMX_EINVAL);
return CARRY_NON;
}
/* eax=sec alarm(sec_edx) err:no */
static int sys_emx15_alarm(void)
{
if (time_tic < npz->time_alarm) /* there seconds left */
EAX = (npz->time_alarm - time_tic) * 10 / 182;
else
EAX = 0;
if (EDX == 0) /* clear alarm */
npz->time_alarm = 0;
else /* set alarm */
npz->time_alarm = time_tic + EDX * 182 / 10;
return CARRY_NON;
}
/* no syscall; internal */
static int sys_emx16_internal(void)
{
return CARRY_NON;
}
/* eax=0 sleep(edx) err:no */
static int sys_emx17_sleep(void)
{
unsigned long timel;
timel = time_tic + EDX * 182 / 10;
for (;;)
if (time_reached(timel))
break;
EAX = 0;
return CARRY_NON;
}
/*
** chsize(handle_ebx,lenght_edx) err:carry eax=errno
*/
static int sys_emx18_chsize(void)
{
tr.eax = 0x4200L;
tr.ebx = EBX;
tr.ecx = EDX >> 16;
tr.edx = EDX & 0xFFFF;
tr.flags = FLAGS & ~1;
if (realdos()) {
EAX = (DWORD) doserror_to_errno((WORD) tr.eax);
return CARRY_ON;
}
tr.eax = 0x4000L;
tr.ebx = EBX;
tr.ecx = 0;
tr.edx = (DWORD) (WORD) iobuf;
tr.flags = FLAGS & ~1;
if (realdos()) {
EAX = (DWORD) doserror_to_errno((WORD) tr.eax);
return CARRY_ON;
}
EAX = 0;
return CARRY_OFF;
}
/* eax fcntl(handle ebx,req ecx,arg edx) errno:ecx */
static int sys_emx19_fcntl(void)
{
if (ECX != F_SETFL && (EDX & ~(FCNTL_NDELAY | FCNTL_APPEND)) == 0)
set_ecx_error(EMX_EINVAL);
else if (EBX == 0) {
set_fcntl_flag(DX);
set_no_error();
} else
set_ecx_error(EMX_EBADF);
return CARRY_NON;
}
/* eax pipe(edx,ecx) errno:ecx*/
static int sys_emx1a_pipe(void)
{
set_ecx_error(EMX_EMSDOS);
return CARRY_NON;
}
/* eax fsync(ebx) errno:ecx */
static int sys_emx1b_fsync(void)
{
set_ecx_error(EMX_EMSDOS);
return CARRY_NON;
}
/* eax fork(void) errno:ecx */
static int sys_emx1c_fork(void)
{
int ret;
if ((ret = sys_fork()) != 0)
set_ecx_error(ret);
else {
set_eax_return((DWORD) npz->cptr->pid);
npz->p_status = PS_SYS_FORK;
switch_to_process(npz->cptr);
npz->p_status = PS_RUN;
set_no_error();
}
return CARRY_NON;
}
/* void scrsize(EDX) */
static int sys_emx1d_scrsize(void)
{
store32(DS, EDX + 0, (*(unsigned short far *) (0x0040004a)));
store32(DS, EDX + 4, (*(unsigned char far *) (0x00400084)) + 1);
return CARRY_NON;
}
/* void select(edx) errno:ecx */
static int sys_emx1e_select(void)
{
set_ecx_error(EMX_EMSDOS);
return CARRY_NON;
}
/* eax syserrno(void) */
static int sys_emx1f_syserrno(void)
{
EAX = doserror_to_errno(_doserrno);
return CARRY_NON;
}
/*
** eax stat(name_edx,struc_edi) errno:ecx
*/
static int sys_emx20_stat(void)
{
struct stat st;
long stat32[13];
strcpy32_16(DS, EDX, iobuf);
if (!stat(iobuf, &st)) {
stat32[0] = (long) st.st_dev;
stat32[1] = (long) st.st_ino;
stat32[2] = (long) st.st_mode;
stat32[3] = 1; /* st_nlink */
stat32[4] = 0; /* st_uid */
stat32[5] = 0; /* st_gid */
stat32[6] = 0; /* st_rdev */
stat32[7] = st.st_size;
stat32[8] = st.st_atime;
stat32[9] = st.st_mtime;
stat32[10] = st.st_ctime;
stat32[11] = 0; /* attribut file _A_NORMAL */
stat32[12] = 0;
cpy16_32(DS, EDI, stat32, 13 * sizeof(DWORD));
set_no_error();
} else
set_ecx_error(doserror_to_errno(_doserrno));
return CARRY_NON;
}
/*
** eax fstat(ebx, edi) errno:ecx
*/
static int sys_emx21_fstat(void)
{
struct stat st;
long stat32[13];
if (!fstat(BX, &st)) {
stat32[0] = (long) st.st_dev;
stat32[1] = (long) st.st_ino;
stat32[2] = (long) st.st_mode;
stat32[3] = 1; /* st_nlink */
stat32[4] = 0; /* st_uid */
stat32[5] = 0; /* st_gid */
stat32[6] = 0; /* st_rdev */
stat32[7] = st.st_size;
stat32[8] = st.st_atime;
stat32[9] = st.st_mtime;
stat32[10] = st.st_ctime;
stat32[11] = 0; /* _A_NORMAL attribut file */ ;
stat32[12] = 0;
cpy16_32(DS, EDI, stat32, 13 * 4);
set_no_error();
} else
set_ecx_error(doserror_to_errno(_doserrno));
return CARRY_NON;
}
static int sys_emx22_unused(void)
{
return CARRY_NON;
}
/* filesys(edx,edi,ecx) errno:ecx */
static int sys_emx23_filesys(void)
{
strcpy32_16(DS, EDI, (char *) "FAT");
set_no_error();
return CARRY_NON;
}
/* eax utimes(name_edx,struct tval esi) errno:ecx */
/* set access and modif time of file */
static int sys_emx24_utimes(void)
{
int handle;
struct tm *tm;
unsigned int dostime, dosdate;
long utimes[2];
strcpy32_16(DS, EDX, iobuf);
cpy32_16(DS, ESI, utimes, sizeof(utimes));
handle = sopen(iobuf, O_RDONLY | O_BINARY, SH_DENYWR, S_IREAD | S_IWRITE);
if (handle == -1) {
set_ecx_error(doserror_to_errno(_doserrno));
return CARRY_NON;
}
tm = localtime(&utimes[0]);
dosdate = tm->tm_mday + ((tm->tm_mon + 1) << 5) +
((tm->tm_year - 80) << 9);
dostime = tm->tm_sec / 2 + (tm->tm_min << 5) +
(tm->tm_hour << 11);
(WORD)tr.eax = 0x5701;
(WORD)tr.ebx = handle;
(WORD)tr.ecx = dostime;
(WORD)tr.edx = dosdate;
if (realdos())
set_ecx_error(doserror_to_errno((WORD)tr.eax));
else
set_eax_return(0);
close(handle);
return CARRY_NON;
}
/* eax ftruncate(ebx,edx) errno:ecx */
static int sys_emx25_ftruncate(void)
{
long temp;
if ((temp = filelength(BX)) == -1)
temp = 0; /* bug? -1: if just opened */
if (temp > (long) EDX) {
if (chsize(BX, EDX))
set_ecx_error(doserror_to_errno(_doserrno));
else
set_no_error();
} else
set_no_error();
return CARRY_NON;
}
/* eax clock(void) err:no */
static int sys_emx26_clock(void)
{
/* clk_tck = 100 ; timer 18.2 pre sec */
EAX = (time_tic - npz->time_tic) * 500 / 91;
EDX = 0;
return CARRY_NON;
}
/* void ftime(edx) err:no */
static int sys_emx27_ftime(void)
{
struct timeb my_timeb;
struct emx_timeb {
long time, millitm, timezone, dstflag;
} emx_timeb;
ftime(&my_timeb);
emx_timeb.time = my_timeb.time;
emx_timeb.millitm = (long) my_timeb.millitm;
emx_timeb.timezone = (long) my_timeb.timezone;
emx_timeb.dstflag = (long) my_timeb.dstflag;
cpy16_32(DS, EDX, &emx_timeb, sizeof(emx_timeb));
return CARRY_NON;
}
/* eax umask(edx) err:no */
static int sys_emx28_umask(void)
{
EAX = EDX;
return CARRY_NON;
}
/* eax getppid(void) err:no */
static int sys_emx29_getppid(void)
{
EAX = (DWORD) npz->pptr->pid;
return CARRY_NON;
}
/* void nls_menupr(buf edx,size ecx) err:no */
/* buffer to upper case */
static int sys_emx2a_nlsmemupr(void)
{
return CARRY_NON;
}
/*
** eax open(edx, ecx) errno:ecx
**
** pathname <= sizeof(iobuf) !
** creat: CH = creat file attr
** open: CL = access & sharing mode
*/
static int sys_emx2b_open(void)
{
int i;
strcpy32_16(DS, EDX, iobuf);
i = (int) (ECX >> 16); /* 1 = O_CREAT, 2 = O_EXCL, 4 = O_TRUNC */
if (i & 0x01) {
if (i & 0x02) /* O_CREAT | O_EXCL */
tr.eax = 0x5B00;
else if (i & 4) /* O_CREAT | O_TRUNC */
tr.eax = 0x3C00;
else if (access(iobuf, 4)) /* O_CREAT */
tr.eax = 0x3C00;
else
tr.eax = 0x3D00L | (CX & 0xff);
} else /* not O_CREAT */
tr.eax = 0x3D00L | (CX & 0xff);
tr.ecx = (ECX & 0xFFFF) >> 8;
tr.edx = (DWORD) (WORD) iobuf;
tr.flags = FLAGS & ~1;
if (realdos())
set_ecx_error(doserror_to_errno((WORD) tr.eax));
else {
set_eax_return(tr.eax);
if ((i & 0x05) == 0x4) /* O_TRUNC with open */
if (chsize(AX, 0))
set_ecx_error(doserror_to_errno(_doserrno));
}
return CARRY_NON;
}
/* eax newthread(edx) errno:ecx */
static int sys_emx2c_newthread(void)
{
set_ecx_error(EMX_EMSDOS);
return CARRY_NON;
}
/* eax endthread(void) errno:ecx */
static int sys_emx2d_endthread(void)
{
set_ecx_error(EMX_EMSDOS);
return CARRY_NON;
}
/* waitpid() */
static int sys_emx2e_waitpid(void)
{
set_ecx_error(EMX_EMSDOS);
return CARRY_NON;
}
static int sys_emx2f_readkbd()
{
int key;
if (DX & 2) { /* wait */
while (_bios_keybrd(kready))
_bios_keybrd(kread);
key = _bios_keybrd(kread);
} else
/* no wait */ if ((key = _bios_keybrd(kready)) != 0)
key = _bios_keybrd(kread);
else {
EAX = -1;
return CARRY_NON;
}
if ((key & 0xff) == 0xE0)
key = 0;
if (DX & 1) /* echo */
if ((key & 0xff) >= 32)
putchar(key & 0xff);
if (DX & 4 && (char) key == 3) /* signal */
send_signal(npz, SIGINT);
EAX = (DWORD) (0 | (key & 0xff));
return CARRY_NON;
}
/* sleep2 ; err:-*/
static int sys_emx30_sleep2(void)
{
unsigned long timel;
timel = time_tic + EDX / 55;
for (;;)
if (time_reached(timel))
break;
return CARRY_NON;
}
/* void unwind2(); not DOS */
static int sys_emx31_unwind2(void)
{
return CARRY_NON;
}
/* void pause(); not DOS */
static int sys_emx32_pause(void)
{
return CARRY_NON;
}
/* int execname(edx=buf, ecx=size); err=-1 */
static int sys_emx33_execname(void)
{
EAX = -1;
return CARRY_NON;
}
/* int initthread() ; not DOS */
static int sys_emx34_initthread(void)
{
EAX = -1;
return CARRY_NON;
}
#define EMX_FNCT_MAX 0x35
typedef int (*EMXFNCT)(void);
static EMXFNCT emx_fnct[EMX_FNCT_MAX] = {
sys_emx00_sbrk,
sys_emx01_brk,
sys_emx02_ulimit,
sys_emx03_vmstat,
sys_emx04_umask,
sys_emx05_getpid,
sys_emx06_spawn,
sys_emx07_unused,
sys_emx08_ptrace,
sys_emx09_wait,
sys_emx0a_version,
sys_emx0b_memavail,
sys_emx0c_signal,
sys_emx0d_kill,
sys_emx0e_raise,
sys_emx0f_uflags,
sys_emx10_unwind,
sys_emx11_core,
sys_emx12_portaccess,
sys_emx13_memaccess,
sys_emx14_ioctl,
sys_emx15_alarm,
sys_emx16_internal,
sys_emx17_sleep,
sys_emx18_chsize,
sys_emx19_fcntl,
sys_emx1a_pipe,
sys_emx1b_fsync,
sys_emx1c_fork,
sys_emx1d_scrsize,
sys_emx1e_select,
sys_emx1f_syserrno,
sys_emx20_stat,
sys_emx21_fstat,
sys_emx22_unused,
sys_emx23_filesys,
sys_emx24_utimes,
sys_emx25_ftruncate,
sys_emx26_clock,
sys_emx27_ftime,
sys_emx28_umask,
sys_emx29_getppid,
sys_emx2a_nlsmemupr,
sys_emx2b_open,
sys_emx2c_newthread,
sys_emx2d_endthread,
sys_emx2e_waitpid,
sys_emx2f_readkbd,
sys_emx30_sleep2,
sys_emx31_unwind2,
sys_emx32_pause,
sys_emx33_execname,
sys_emx34_initthread } ;
static int i_21_7f(void)
{
WORD i = AX & 0xFF;
/* emx fnct = al */
if (i < EMX_FNCT_MAX)
return (emx_fnct[i])();
else {
printf("Unknown syscall: %04X\n", i);
send_signal(npz, SIGSEGV);
return CARRY_ON;
}
}
extern int i_21_ff(void);
void int21(void)
{
WORD ret;
if (opt_print_syscalls)
printf("DOS 21h: %04X %08lX %08lX %08lX", AX, EBX, ECX, EDX);
if ((AX & 0xff00) == 0x7f00)/* emx functions */
ret = i_21_7f();
else if ((AX & 0xff00) == 0xff00) /* go32 functions */
ret = i_21_ff();
else { /* DOS functions */
ret = int21normal();
/* if DOS indicates an error (carry-flag set), convert error code */
if (ret == CARRY_NON && (FLAGS & 1)) {
EAX = (DWORD) doserror_to_errno(AX);
ret = CARRY_ON;
}
}
if (ret == CARRY_ON) {
EFLAGS |= 1;
if (npz->p_flags & PF_DJGPP_FILE)
EAX = (DWORD) errno_djgpp(AX);
} else if (ret == CARRY_OFF)
EFLAGS &= ~1L;
if (opt_print_syscalls)
printf(" ret=%lX\n", EAX);
if (npz->time_alarm != 0 && time_reached(npz->time_alarm)) {
npz->time_alarm = 0;
send_signal(npz, SIGALRM);
}
/* stack check */
if (npz->stack_down + 0x1000L >= ESP) {
puts("stack too small!!");
printf("ESP %lX stack : min %lX max %lX\n",
ESP, npz->stack_down, npz->stack_top);
send_signal(npz, SIGKILL);
}
}