Recovery of release 990110 after disk crash.
See Changelog for changes between 990103 and 990110.

diff --git a/loader/dos/dosmod.c b/loader/dos/dosmod.c
index 75ac48f..b53c8fa 100644
--- a/loader/dos/dosmod.c
+++ b/loader/dos/dosmod.c
@@ -56,6 +56,41 @@
     return -1;
 }
 
+int XREAD(int fd,void*buf,int size) {
+ int res;
+
+ while (1) {
+  res = read(fd, buf, size);
+  if (res==size)
+   return res;
+  if (res==-1) {
+   if (errno==EINTR)
+    continue;
+   perror("dosmod read");
+   return -1;
+  }
+  fprintf(stderr,"dosmod read only %d of %d bytes.\n",res,size);
+  return res;
+ }
+}
+int XWRITE(int fd,void*buf,int size) {
+ int res;
+
+ while (1) {
+  res = write(fd, buf, size);
+  if (res==size)
+   return res;
+  if (res==-1) {
+   if (errno==EINTR)
+    continue;
+   perror("dosmod write");
+   return -1;
+  }
+  fprintf(stderr,"dosmod write only %d of %d bytes.\n",res,size);
+  return res;
+ }
+}
+
 void set_timer(struct timeval*tim)
 {
  struct itimerval cur;
@@ -65,7 +100,15 @@
  setitimer(ITIMER_REAL,&cur,NULL);
 }
 
-volatile int sig_pend,sig_fatal=0;
+void get_timer(struct timeval*tim)
+{
+ struct itimerval cur;
+
+ getitimer(ITIMER_REAL,&cur);
+ *tim=cur.it_value;
+}
+
+volatile int sig_pend,sig_fatal=0,sig_alrm=0;
 void*img;
 struct vm86plus_struct VM86;
 
@@ -84,6 +127,12 @@
  signal(sig,bad_handler);
 }
 
+void alarm_handler(int sig)
+{
+ sig_alrm++;
+ signal(sig,alarm_handler);
+}
+
 int main(int argc,char**argv)
 {
  int mfd=open(argv[0],O_RDWR);
@@ -121,7 +170,7 @@
  signal(SIGINT,sig_handler);
  signal(SIGUSR1,sig_handler);
  signal(SIGUSR2,sig_handler);
- signal(SIGALRM,sig_handler);
+ signal(SIGALRM,alarm_handler);
 
  signal(SIGQUIT,bad_handler);
  signal(SIGILL,bad_handler);
@@ -135,28 +184,33 @@
 #endif
 /* report back to the main program that we're ready */
  ret=1; /* dosmod protocol revision 1 */
- write(1,&ret,sizeof(ret));
+ XWRITE(1,&ret,sizeof(ret));
 /* context exchange loop */
  do {
-  if (read(0,&func,sizeof(func))!=sizeof(func)) return 1;
+  if (XREAD(0,&func,sizeof(func))!=sizeof(func)) return 1;
   if (func<0) break;
   switch (func) {
    case DOSMOD_SET_TIMER:
-    if (read(0,&tim,sizeof(tim))!=sizeof(tim)) return 1;
+    if (XREAD(0,&tim,sizeof(tim))!=sizeof(tim)) return 1;
     set_timer(&tim);
     /* no response */
     break;
+   case DOSMOD_GET_TIMER:
+    get_timer(&tim);
+    if (XWRITE(1,&tim,sizeof(tim))!=sizeof(tim)) return 1;
+    break;
    case DOSMOD_ENTER:
    default:
-    if (read(0,&VM86,sizeof(VM86))!=sizeof(VM86)) return 1;
-    if (sig_pend) ret=DOSMOD_SIGNAL; else
+    if (XREAD(0,&VM86,sizeof(VM86))!=sizeof(VM86)) return 1;
+    if (sig_pend||sig_alrm) ret=DOSMOD_SIGNAL; else
      ret=vm86plus(func,&VM86);
-    if (write(1,&ret,sizeof(ret))!=sizeof(ret)) return 1;
-    if (write(1,&VM86,sizeof(VM86))!=sizeof(VM86)) return 1;
+    if (XWRITE(1,&ret,sizeof(ret))!=sizeof(ret)) return 1;
+    if (XWRITE(1,&VM86,sizeof(VM86))!=sizeof(VM86)) return 1;
     switch (ret&0xff) {
      case DOSMOD_SIGNAL:
       ret=sig_pend; sig_pend=0;
-      if (write(1,&ret,sizeof(ret))!=sizeof(ret)) return 1;
+      if (!ret) { ret=SIGALRM; sig_alrm--; }
+      if (XWRITE(1,&ret,sizeof(ret))!=sizeof(ret)) return 1;
       if (sig_fatal) return 1;
       break;
     }
diff --git a/loader/dos/dosmod.h b/loader/dos/dosmod.h
index 6545620..ee9d9f3 100644
--- a/loader/dos/dosmod.h
+++ b/loader/dos/dosmod.h
@@ -3,6 +3,7 @@
 
 #define DOSMOD_ENTER     0x01 /* VM86_ENTER */
 #define DOSMOD_SET_TIMER 0x10
+#define DOSMOD_GET_TIMER 0x11
 
 #define DOSMOD_SIGNAL 0x00 /* VM86_SIGNAL */
 
diff --git a/loader/dos/dosvm.c b/loader/dos/dosvm.c
index 989b6a9..c493363 100644
--- a/loader/dos/dosvm.c
+++ b/loader/dos/dosvm.c
@@ -295,6 +295,56 @@
  return 0;
 }
 
+void DOSVM_SetTimer( unsigned ticks )
+{
+ TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
+ NE_MODULE *pModule = NE_GetPtr( pTask->hModule );
+ int stat=DOSMOD_SET_TIMER;
+ struct timeval tim;
+
+ GlobalUnlock16( GetCurrentTask() );
+ if (pModule&&pModule->lpDosTask) {
+  /* the PC clocks ticks at 1193180 Hz */
+  tim.tv_sec=0;
+  tim.tv_usec=((unsigned long long)ticks*1000000)/1193180;
+  /* sanity check */
+  if (!tim.tv_usec) tim.tv_usec=1;
+
+  if (write(pModule->lpDosTask->write_pipe,&stat,sizeof(stat))!=sizeof(stat)) {
+   ERR(module,"dosmod sync lost, errno=%d\n",errno);
+   return;
+  }
+  if (write(pModule->lpDosTask->write_pipe,&tim,sizeof(tim))!=sizeof(tim)) {
+   ERR(module,"dosmod sync lost, errno=%d\n",errno);
+   return;
+  }
+  /* there's no return */
+ }
+}
+
+unsigned DOSVM_GetTimer( void )
+{
+ TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
+ NE_MODULE *pModule = NE_GetPtr( pTask->hModule );
+ int stat=DOSMOD_GET_TIMER;
+ struct timeval tim;
+
+ GlobalUnlock16( GetCurrentTask() );
+ if (pModule&&pModule->lpDosTask) {
+  if (write(pModule->lpDosTask->write_pipe,&stat,sizeof(stat))!=sizeof(stat)) {
+   ERR(module,"dosmod sync lost, errno=%d\n",errno);
+   return 0;
+  }
+  /* read response */
+  if (read(pModule->lpDosTask->read_pipe,&tim,sizeof(tim))!=sizeof(tim)) {
+   ERR(module,"dosmod sync lost, errno=%d\n",errno);
+   return 0;
+  }
+  return ((unsigned long long)tim.tv_usec*1193180)/1000000;
+ }
+ return 0;
+}
+
 void MZ_Tick( WORD handle )
 {
  /* find the DOS task that has the right system_timer handle... */
@@ -319,5 +369,7 @@
 }
 
 void MZ_Tick( WORD handle ) {}
+void DOSVM_SetTimer( unsigned ticks ) {}
+unsigned DOSVM_GetTimer( void ) { return 0; }
 
 #endif
diff --git a/loader/dos/module.c b/loader/dos/module.c
index 64feff4..dc01307 100644
--- a/loader/dos/module.c
+++ b/loader/dos/module.c
@@ -45,8 +45,6 @@
 #define SEG16(ptr,seg) ((LPVOID)((BYTE*)ptr+((DWORD)(seg)<<4)))
 #define SEGPTR16(ptr,segptr) ((LPVOID)((BYTE*)ptr+((DWORD)SELECTOROF(segptr)<<4)+OFFSETOF(segptr)))
 
-extern WORD WINAPI SYSTEM_KillSystemTimer( WORD timer );
-
 static void MZ_InitPSP( LPVOID lpPSP, LPCSTR cmdline, WORD env )
 {
  PDB*psp=lpPSP;
@@ -494,7 +492,7 @@
 
 #else /* !MZ_SUPPORTED */
 
-HINSTANCE16 MZ_CreateProcess( LPCSTR name, LPCSTR cmdline, LPCSTR env, 
+HINSTANCE16 MZ_CreateProcess( LPCSTR name, LPCSTR cmdline, LPCSTR env, BOOL32 inherit,
                               LPSTARTUPINFO32A startup, LPPROCESS_INFORMATION info )
 {
  WARN(module,"DOS executables not supported on this architecture\n");