home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Portable Patmos 1.1 / patmos-src / src / syscalls.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-01  |  33.7 KB  |  1,355 lines  |  [TEXT/KAHL]

  1. #ifdef THINK_C
  2. #include <LoMem.h>
  3. #include <THINK.h>
  4. #define get_time() TimeLM
  5. #define get_ticks() Ticks
  6. #else
  7. #include <Types.h>
  8. #include <Errors.h>
  9. #include <Memory.h>
  10. #include <OSUtils.h>
  11. #include <SegLoad.h>
  12. #include <Quickdraw.h>
  13. #include <Files.h>
  14. #include <Menus.h>
  15. #include <Fonts.h>
  16. #include <Resources.h>
  17. #include <GestaltEqu.h>
  18. #include <Traps.h>
  19. #include <Aliases.h>
  20. #include <Packages.h>
  21. #include <Processes.h>
  22. #include <AppleEvents.h>
  23. #include <ToolUtils.h>
  24. #include <SysEqu.h>
  25. #define get_time() (*(long *)TimeLM)
  26. #define get_ticks() (*(long *)Ticks)
  27. enum {FALSE,TRUE};
  28. #endif
  29. #include <GestaltEqu.h>
  30. #include <ToolUtils.h>
  31. #include <Retrace.h>
  32. #include <OSUtils.h>
  33. #include <stdio.h>
  34. #include <errno.h>
  35. #include <string.h>
  36. #include <stdlib.h>
  37. #include <dirent.h>
  38. #include <fcntl.h>
  39. #include <utime.h>            
  40. #include <unistd.h>
  41. #include <sys/uio.h>
  42. #include <sys/mman.h>
  43. #include <sys/stat.h>
  44. #include <sys/syscall.h>
  45. #include <sys/ioctl.h>
  46. #include <sys/syslimits.h>
  47. #include <sys/time.h>
  48. #include <sys/resource.h>
  49. #include <sys/signal.h>
  50. #include <sys/signalvar.h>
  51. #include <sys/ptrace.h>
  52. #include <sys/wait.h>
  53. #include <sys/socket.h>
  54. #include "crtlocal.h"
  55. #include "proc_mmu.h"
  56.  
  57. struct mmu *proc_tab[maxproc];
  58.  
  59. void sched(void)
  60.     {
  61.     static long real_time = 0;
  62.     static int proc_no = 0;
  63.     long now = get_ticks();
  64.     int must_swap = 0;
  65.     if (crp) crp->ticks += now-old_ticks;
  66.     do
  67.         {
  68.         int cnt;
  69.         if ((now-real_time > kInterval) || (now < real_time))
  70.             {
  71.             real_time = now;
  72.             must_swap = 1;
  73.             checkevents();
  74.             }
  75.         if (interrupt && (crp->state=='R'))
  76.             {
  77.             interrupt = 0;
  78.             if (crp->trace_me)
  79.                 {
  80.                 crp->state = 'T';
  81.                 crp->result = W_STOPCODE(SIGINT);
  82.                 }
  83.             else
  84.                 {
  85.                 crp->state = 'X';
  86.                 crp->result = SIGINT;
  87.                 }
  88.             must_swap = 1;
  89.             }
  90.         cnt = 2*sizeof(proc_tab)/sizeof(*proc_tab);
  91.         if (must_swap || !crp || (crp->state!='D')) do
  92.             {
  93.             proc_no = (proc_no+1)%(sizeof(proc_tab)/sizeof(*proc_tab));
  94.             }
  95. #if 0
  96.         while (cnt-- && (!proc_tab[proc_no]  || ((cnt > 0*sizeof(proc_tab)/sizeof(*proc_tab)) && ((proc_tab[proc_no]->state=='W')||(proc_tab[proc_no]->state=='Z'))) ));
  97. #else
  98.         while (cnt-- && !proc_tab[proc_no]);
  99. #endif
  100.         if (crp != proc_tab[proc_no])
  101.             {
  102.             if (crp && crp->savestack)
  103.                 {
  104.                 int usp = crp->registers.save[15];
  105.                 crp->savestack = xrealloc(crp->savestack, crp->stack_limit-usp);
  106.                 kumemcpy(crp, crp->savestack, usp, crp->stack_limit-usp);
  107.                 }
  108.             crp = proc_tab[proc_no];
  109.             if (crp && crp->savestack)
  110.                 {
  111.                 int usp = crp->registers.save[15];
  112.                 ukmemcpy(crp, usp, (void *)(crp->savestack), crp->stack_limit-usp);
  113.                 }
  114.             }
  115.         if (crp) switch(crp->state)
  116.             {
  117. #if 1
  118.             case 'W':
  119.                 {
  120.                 int proc_no = 0;
  121.                 int cnt = sizeof(proc_tab)/sizeof(*proc_tab);
  122.                 while (--cnt && (!proc_tab[proc_no] || (proc_tab[proc_no]->parent != crp)))
  123.                     ++proc_no;
  124.                 if (!cnt)
  125.                     {
  126.                     crp->state = 'R';
  127.                     errno = ECHILD;
  128.                     crp->result = -1;
  129.                     }
  130.                 break;
  131.                 }
  132. #endif
  133.             case 'Z':
  134.                 {
  135.                 int arg = OPEN_MAX;
  136.                 while (arg--) if (crp->fd_tab[arg])
  137.                     {
  138.                     int stale = 1;
  139.                     int kfd = crp->fd_tab[arg];
  140.                     int cnt1 = sizeof(proc_tab)/sizeof(*proc_tab);
  141.                     crp->fd_tab[arg] = 0;
  142.                     while (cnt1--)
  143.                         {
  144.                         if (proc_tab[cnt1] && (proc_tab[cnt1]->state != 'Z'))
  145.                             {
  146.                             int cnt2 = OPEN_MAX;
  147.                             while (cnt2--)
  148.                                 {
  149.                                 if (proc_tab[cnt1]->fd_tab[cnt2] == kfd)
  150.                                     {
  151.     //                                kprintf("fd %d still open in proc %d\n", arg, proc_tab[cnt1]->pid);
  152.                                     stale = cnt1 = cnt2 = 0;
  153.                                     }
  154.                                 }
  155.                             }
  156.                         }
  157.                     if (stale) close(kfd);
  158.                     }
  159. #ifdef PROTECTED
  160.                 free_space(crp);
  161. #else
  162.                 if (!crp->sbreak)    /* must be relocatable */
  163.                     {
  164.                     struct mem_chain *storage = crp->storage;
  165.                     while (storage)
  166.                         {
  167.                         struct mem_chain *nxt = storage->nxt;
  168.                         DisposPtr((Ptr)storage);
  169.                         storage = nxt;
  170.                         }
  171.                     }
  172. #endif
  173.                 if (crp->savestack) free(crp->savestack);
  174.                 if (debug)
  175.                     kprintf("Activated pages = %ld\n", activated_pages);
  176.                 free(crp->p_sigacts);
  177.                 free(crp->self);
  178.     //            mstats("MMU");
  179.                 crp = proc_tab[proc_no] = 0;
  180.                     {
  181.                     ParamBlockRec    vol;
  182.                     vol.volumeParam.ioNamePtr = 0;
  183.                     vol.volumeParam.ioVRefNum = crt_ioVRefNum;
  184.                     PBFlushVolSync(&vol);
  185.                     }    
  186.                 break;
  187.                 }
  188.             case 'X':
  189.                 crp->state = 'Z';
  190.             case 'T':
  191.                 {
  192.                 if (crp->parent && (crp->parent->state=='W'))
  193.                     {
  194.                     crp->parent->state = 'D';
  195.                     crp->parent->registers.save[0] = SYS_wait4;
  196.                     }
  197.                 break;
  198.                 }
  199.             case 'D':
  200.                 {
  201.                 system_call();
  202.                 break;
  203.                 }
  204.             }
  205.         else checkevents();
  206.         old_ticks = now = get_ticks();
  207.         must_swap = 1;
  208.         }
  209.     while (!crp || crp->state != 'R');
  210.     }
  211.  
  212. struct args
  213.          {
  214.          void *dummy;
  215.          long arg1,arg2,arg3,arg4,arg5,arg6,arg7;
  216.          };
  217.  
  218. gettimeofday(struct timeval *ktime, struct timezone *kzone)
  219.         {
  220.         memset(kzone, 0, sizeof(*kzone));
  221.         ktime->tv_sec = unixTime(get_time());
  222.         ktime->tv_usec = (get_ticks()%60)*1000000/60;
  223.         }
  224.  
  225. void system_call(void)
  226.     {
  227.      struct args s;
  228.      crp->state = 'R'; /* runnable unless otherwise overridden */
  229.      kumemcpy(crp, &s, crp->registers.save[15], sizeof(s));
  230. #if 1
  231.      if ((unsigned long)s.dummy <= 183)
  232.          {
  233.          crp->registers.save[0] = (long)s.dummy;
  234.          memcpy(&s.arg1, &s.arg2, sizeof(s)-8);
  235.          crp->registers.save[15] += 4;
  236.          }
  237. #endif
  238.     crt_parID = crp->crt_parID;
  239.     root_parID = crp->root_parID;
  240.      if (debug) 
  241.          {
  242.          kprintf("System call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  243.          }
  244.      errno = ENOSYS;
  245.     switch(crp->registers.save[0])
  246.         {
  247.         default:
  248. #ifdef PROTECTED
  249.             if (virtual && !crp->registers.save[0])
  250.                 {
  251.                 crp->registers.pc = crp->header.a_entry;
  252.                 crp->registers.save[15] = crp->stack_limit-256;
  253.                 }
  254.             else
  255. #endif
  256.                 {
  257.                 kprintf("Unimplemented system call %s\n", callname(crp->registers.save[0]));
  258.                 crp->result = -1;
  259.                 }
  260.             break;
  261.         case SYS_exit:
  262.                 {
  263.                 crp->result = (s.arg1&255)<<8;
  264.                 crp->state = 'X';
  265.                 }
  266.             break;
  267.         case SYS_fork:
  268.             if (crp->sbreak)    /* genuine user mem proc. */
  269.                 {
  270.                 newproc(0, NULL, NULL, crp, 0, 0);
  271.                 crp->result = 0;
  272.                 /* save parent->result of system call */
  273.                     {
  274.                     enum {carry=1};
  275.                         {
  276.                         crp->parent->registers.save[0] = crp->pid;
  277.                         crp->parent->registers.flags &= ~carry;
  278.                         }
  279.                     crp->parent->registers.save[1] = 0;    /* is this correct ? */
  280.                     }
  281.                 break;
  282.                 }
  283.         case SYS_vfork:
  284.             {
  285.             newproc(0, NULL, NULL, crp, 0, 0);
  286.             crp->result = 0;
  287.             /* save parent->result of system call */
  288.                 {
  289.                 enum {carry=1};
  290.                     {
  291.                     crp->parent->registers.save[0] = crp->pid;
  292.                     crp->parent->registers.flags &= ~carry;
  293.                     }
  294.                 crp->parent->registers.save[1] = 0;    /* is this correct ? */
  295.                 }
  296.             break;
  297.             }
  298.         case SYS_read:
  299.             {
  300.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  301.             else
  302.                 {
  303.                 char *kbuf = xmalloc(s.arg3);
  304.                 int kfd = crp->fd_tab[s.arg1];
  305.                 if (kfd < 0) 
  306.                     crp->result = s_read(~kfd, kbuf, s.arg3);
  307.                 else
  308.                     crp->result = read(kfd, kbuf, s.arg3);
  309.                 ukmemcpy(crp, s.arg2, kbuf, crp->result);
  310.                 free(kbuf);
  311.                 if ((kfd >= 0) && (crt_fd_tab[kfd].flags & O_PIPE) && !crp->result)
  312.                     {
  313.                     int tot = (crt_fd_tab[kfd].fd&-256) == 100<<8;
  314.                     int cnt = sizeof(proc_tab)/sizeof(*proc_tab);
  315.                     while (cnt--)
  316.                         {
  317.                         if (proc_tab[cnt] && (proc_tab[cnt]->state != 'Z'))
  318.                             {
  319.                             int cnt2 = OPEN_MAX;
  320.                             while (cnt2--)
  321.                                 {
  322.                                 if (proc_tab[cnt]->fd_tab[cnt2] == kfd)
  323.                                     {
  324.                                     ++tot;
  325.                                     }
  326.                                 }
  327.                             }
  328.                         }
  329.                     if (tot > 1) crp->state = 'D';
  330.                     }
  331.                 }
  332.              if ((crp->result==-1))
  333.                  {
  334.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  335.                  }
  336.             break;
  337.             }
  338.         case SYS_write:
  339.             {
  340.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  341.             else
  342.                 {
  343.                 int kfd = crp->fd_tab[s.arg1];
  344.                 char *kbuf = xmalloc(s.arg3);
  345.                 kumemcpy(crp, kbuf, s.arg2, s.arg3);
  346.                 if (kfd < 0)
  347.                     crp->result = s_write(~kfd, kbuf, s.arg3);
  348.                 else
  349.                     crp->result = write(kfd, kbuf, s.arg3);
  350.                 free(kbuf);
  351.                 }
  352.              if ((crp->result==-1))
  353.                  {
  354.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  355.                  }
  356.             break;
  357.             }
  358.         case SYS_open:
  359.             {
  360.             int bufsiz = ustrlen(crp, s.arg1)+1;
  361.             char *kbuf = xmalloc(bufsiz);
  362.             kustrcpy(crp, (void *)kbuf, s.arg1);
  363.             if (debug) kprintf("Open %s\n", kbuf);    
  364.             crp->result = open(kbuf, s.arg2, s.arg3);
  365.             if (crp->result != -1)
  366.                 {
  367.                 int fd = 0;
  368.                 while ((fd <= OPEN_MAX) && crp->fd_tab[fd]) ++fd;
  369.                 if (fd <= OPEN_MAX) 
  370.                     {
  371.                     crp->fd_tab[fd] = crp->result;
  372.                     crp->result = fd;
  373.                     }
  374.                 else
  375.                     {
  376.                     close(crp->result);
  377.                     crp->result = -1;
  378.                     }
  379.                 }    
  380.             free((void *)kbuf);
  381.             break;
  382.             }
  383.         case SYS_close:
  384.             crp->result = -1;
  385.             if ((s.arg1>=0)&&(s.arg1<=OPEN_MAX)&&crp->fd_tab[s.arg1])
  386.                 {
  387.                 int kfd = crp->fd_tab[s.arg1];
  388.                 int cnt = sizeof(proc_tab)/sizeof(*proc_tab);
  389.                 crp->fd_tab[s.arg1] = 0;
  390.                 while (cnt--)
  391.                     {
  392.                     if (proc_tab[cnt] && (proc_tab[cnt]->state != 'Z'))
  393.                         {
  394.                         int cnt2 = OPEN_MAX;
  395.                         while (cnt2--)
  396.                             {
  397.                             if (proc_tab[cnt]->fd_tab[cnt2] == kfd)
  398.                                 {
  399. //                                kprintf("fd %d still open in proc %d\n", s.arg1, proc_tab[cnt]->pid);
  400.                                 crp->result = cnt = cnt2 = 0;
  401.                                 }
  402.                             }
  403.                         }
  404.                     }
  405.                 if (crp->result)
  406.                     {
  407.                     if (kfd < 0)
  408.                         crp->result = s_close(~kfd);
  409.                     else
  410.                         crp->result = close(kfd);
  411.                     }
  412.                 }
  413.             break;
  414.         case SYS_wait4:
  415.             {
  416.             int proc_no = 0;
  417.             int cnt = sizeof(proc_tab)/sizeof(*proc_tab);
  418.             while (--cnt && (!proc_tab[proc_no] || (proc_tab[proc_no]->parent != crp) 
  419.                 || ((s.arg1 != -1) && (s.arg1 != proc_tab[proc_no]->pid))))
  420.                 ++proc_no;
  421.             if (cnt)
  422.                 {
  423.                 if ((proc_tab[proc_no]->state == 'T') || (proc_tab[proc_no]->state == 'Z'))
  424.                         {
  425.                         int waitcode = proc_tab[proc_no]->result;
  426.                         ukmemcpy(crp, s.arg2, &waitcode, sizeof(int)); /* for retcode */
  427.                         crp->result = proc_tab[proc_no]->pid;
  428.                         errno = 0;
  429.                         }
  430.                 else
  431.                         {
  432.                         crp->state = 'W';
  433.                         crp->result = s.arg2;
  434.                         }
  435.                 }
  436.             else    
  437.                 {
  438.                 errno = ECHILD;
  439.                 umemset(crp, s.arg2, 0, sizeof(int));
  440.                 crp->result = -1;
  441.                 }
  442.             break;
  443.             }
  444.         case SYS_link:
  445.             errno = EMLINK;
  446.             crp->result = -1;
  447.             break;
  448.         case SYS_unlink:
  449.             {
  450.             int bufsiz = ustrlen(crp, s.arg1)+1;
  451.             char *kbuf = xmalloc(bufsiz);
  452.             kustrcpy(crp, kbuf, s.arg1);            
  453.             crp->result = unlink(kbuf);
  454.             free(kbuf);
  455.             break;
  456.             }
  457.         case SYS_chdir:
  458.             {
  459.             int bufsiz = ustrlen(crp, s.arg1)+1;
  460.             char *kbuf = xmalloc(bufsiz);
  461.             kustrcpy(crp, kbuf, s.arg1);            
  462.             crp->result = chdir(kbuf);
  463.             if (!crp->result) crp->crt_parID = crt_parID;
  464.             free(kbuf);
  465.             break;
  466.             }
  467.         case SYS_fchdir:
  468.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  469.             else crp->result = fchdir(crp->fd_tab[s.arg1]);
  470.             if (!crp->result) crp->crt_parID = crt_parID;
  471.             break;
  472.         case SYS_mknod:
  473.             {
  474.             int bufsiz = ustrlen(crp, s.arg1)+1;
  475.             char *kbuf = xmalloc(bufsiz);
  476.             kustrcpy(crp, kbuf, s.arg1);            
  477.             crp->result = mknod(kbuf, s.arg2, s.arg3);
  478.             free(kbuf);
  479.             break;
  480.             }            
  481.         case SYS_chmod:
  482.             {
  483.             int bufsiz = ustrlen(crp, s.arg1)+1;
  484.             char *kbuf = xmalloc(bufsiz);
  485.             kustrcpy(crp, kbuf, s.arg1);            
  486.             crp->result = chmod(kbuf, s.arg2);
  487.             free(kbuf);
  488.             break;
  489.             }
  490.         case SYS_chown:
  491.             {
  492.             int bufsiz = ustrlen(crp, s.arg1)+1;
  493.             char *kbuf = xmalloc(bufsiz);
  494.             kustrcpy(crp, kbuf, s.arg1);            
  495.             crp->result = chown(kbuf, s.arg2, s.arg3);
  496.             free(kbuf);
  497.             break;
  498.             }
  499.         case SYS_lseek:
  500.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  501.             else crp->result = lseek(crp->fd_tab[s.arg1], s.arg2, s.arg3);
  502.             break;
  503.         case SYS_getpid:
  504.             crp->result = crp->pid;
  505.             break;
  506.         case SYS_getuid:
  507.             crp->result = 0;
  508.             break;
  509.         case SYS_geteuid:
  510.             crp->result = 0;
  511.             break;
  512.         case SYS_ptrace:
  513.             {
  514.             struct mmu *child = NULL;
  515.             int pid = s.arg2;
  516.             long addr = s.arg3;
  517.             long data = s.arg4;
  518.             int proc_no = 0;
  519.             int cnt = sizeof(proc_tab)/sizeof(*proc_tab);
  520.             while (--cnt && (!proc_tab[proc_no] || (pid != proc_tab[proc_no]->pid)))
  521.                 ++proc_no;
  522.             if (cnt)
  523.                 {
  524.                 child = proc_tab[proc_no];
  525.                 if ((child->state != 'T') || !child->trace_me)
  526.                     {
  527.                     errno = ECHILD;
  528.                     break;
  529.                     }
  530.                 else crp->result = 0;
  531.                 }
  532.             else    
  533.                 errno = ECHILD;
  534.             if (debug) kprintf("ptrace(%d,%d,%08X,%08X)\n", s.arg1, pid, addr, data);
  535.             switch(s.arg1)
  536.                 {
  537.                 case     PT_TRACE_ME    : if (debug) kprintf("child declares it's being traced\n");
  538.                     crp->trace_me = 1; 
  539.                     crp->result = 0;
  540.                     break;
  541.                 case     PT_READ_I    :
  542.                 case     PT_READ_D    : if (debug) kprintf("read word in child's I/D space\n"); 
  543.                     if (child)
  544.                         kumemcpy(child, &(crp->result), addr, sizeof(long));                    
  545.                     break;
  546.                 case     PT_READ_U    : kprintf("read word in child's user structure\n"); 
  547.                     crp->result = -1;
  548.                     break;
  549.                 case     PT_WRITE_I    :
  550.                 case     PT_WRITE_D    : if (debug) kprintf("write word in child's I/D space\n"); 
  551.                     if (child)
  552.                         ukmemcpy(child, addr, &data, sizeof(long));
  553.                     break;
  554.                 case     PT_WRITE_U    : kprintf("write word in child's user structure\n"); 
  555.                     crp->result = -1;
  556.                     break;
  557.                 case     PT_CONTINUE    : if (debug) kprintf("continue the child\n"); 
  558.                     {
  559.                     if (child) 
  560.                         child->state = 'R';
  561.                     break;
  562.                     }
  563.                 case     PT_KILL        : if (debug) kprintf("kill the child process\n"); 
  564.                     if (child) 
  565.                         child->state = 'Z';
  566.                     break;
  567.                 case     PT_STEP        : if (debug) kprintf("single step the child\n"); 
  568.                     if (child)
  569.                         {
  570.                         child->registers.flags |= 0x8000;
  571.                         child->state = 'R';
  572.                         }
  573.                     break;
  574.                 case     PT_ATTACH    : kprintf("attach to running process\n"); 
  575.                     crp->result = -1;
  576.                     break;
  577.                 case     PT_DETACH    : kprintf("detach from running process\n");
  578.                     crp->result = -1;
  579.                     break;
  580.                 case     PT_GETREGS    : if (debug) kprintf("fetch registers\n");
  581.                     if (child)
  582.                         ukmemcpy(crp, addr, &(child->registers), sizeof(struct userregs));
  583.                     break;
  584.                 case     PT_SETREGS    : if (debug) kprintf("set registers\n"); 
  585.                     if (child)
  586.                         kumemcpy(crp, &(child->registers), addr, sizeof(struct userregs));
  587.                     break;
  588.                 default : crp->result = -1;
  589.                 }
  590.             break;
  591.             }
  592. #if 0
  593.         case SYS_recvmsg:
  594.         case SYS_sendmsg:
  595. #endif
  596.         case SYS_recvfrom:
  597.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  598.             else
  599.                 {
  600.                 int kfd = crp->fd_tab[s.arg1];
  601.                 if (kfd < 0) 
  602.                     {
  603.                     int fromlen;
  604.                     struct sockaddr sa_from;
  605.                     char *buffer = xmalloc(s.arg3);
  606.                     kumemcpy(crp, &sa_from, s.arg5, sizeof(sa_from));
  607.                     crp->result = s_sendto (~kfd, buffer, s.arg3, s.arg4, &sa_from, &fromlen);
  608.                     ukmemcpy(crp, s.arg5, &sa_from, sizeof(sa_from));
  609.                     ukmemcpy(crp, s.arg2, buffer, fromlen);
  610.                     ukmemcpy(crp, s.arg6, &fromlen, sizeof(int));
  611.                     free(buffer);
  612.                     }
  613.                 }
  614.              if ((crp->result==-1))
  615.                  {
  616.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  617.                  }
  618.             break;
  619.         case SYS_accept:
  620.             {
  621.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  622.             else
  623.                 {
  624.                 int kfd = crp->fd_tab[s.arg1];
  625.                 if (kfd < 0) 
  626.                     {
  627.                     int addrlen;
  628.                     struct sockaddr sa_addr;
  629.                     kumemcpy(crp, &sa_addr, s.arg2, sizeof(sa_addr));
  630.                     kumemcpy(crp, &addrlen, s.arg3, sizeof(long));
  631.                     crp->result = s_accept(~kfd, &sa_addr, &addrlen);
  632.                     ukmemcpy(crp, s.arg2, &sa_addr, sizeof(sa_addr));
  633.                     ukmemcpy(crp, s.arg3, &addrlen, sizeof(long));
  634.                     }
  635.                 }
  636.              if ((crp->result==-1))
  637.                  {
  638.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  639.                  }
  640.             break;
  641.             }
  642.         case SYS_getpeername:
  643.             {
  644.             break;
  645.             }
  646.         case SYS_getsockname:
  647.             {
  648.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  649.             else
  650.                 {
  651.                 int kfd = crp->fd_tab[s.arg1];
  652.                 if (kfd < 0) 
  653.                     {
  654.                     int addrlen;
  655.                     struct sockaddr sa_addr;
  656.                     kumemcpy(crp, &sa_addr, s.arg2, sizeof(sa_addr));
  657.                     kumemcpy(crp, &addrlen, s.arg3, sizeof(long));
  658.                     crp->result = s_getsockname(~kfd, &sa_addr, &addrlen);
  659.                     ukmemcpy(crp, s.arg2, &sa_addr, sizeof(sa_addr));
  660.                     ukmemcpy(crp, s.arg3, &addrlen, sizeof(long));
  661.                     }
  662.                 }
  663.              if ((crp->result==-1))
  664.                  {
  665.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  666.                  }
  667.             break;
  668.             }
  669.         case SYS_symlink:
  670.             {
  671.             int bufsiz1 = ustrlen(crp, s.arg1)+1;
  672.             char *kbuf1 = xmalloc(bufsiz1);
  673.             int bufsiz2 = ustrlen(crp, s.arg2)+1;
  674.             char *kbuf2 = xmalloc(bufsiz2);
  675.             kustrcpy(crp, kbuf1, s.arg1);            
  676.             kustrcpy(crp, kbuf2, s.arg2);            
  677.             crp->result = symlink(kbuf1, kbuf2);
  678.             free(kbuf1);
  679.             free(kbuf2);
  680.             break;
  681.             }
  682.         case SYS_readlink:
  683.             {
  684.             int bufsiz1 = ustrlen(crp, s.arg1)+1;
  685.             char *kbuf1 = xmalloc(bufsiz1);
  686.             char *kbuf2 = xmalloc(s.arg3);
  687.             kustrcpy(crp, kbuf1, s.arg1);            
  688.             crp->result = readlink(kbuf1, kbuf2, s.arg3);
  689.             ukmemcpy(crp, s.arg2, kbuf2, crp->result+1);
  690.             free(kbuf1);
  691.             free(kbuf2);
  692.             break;
  693.             }
  694.         case SYS_execve:
  695.             {
  696.             extern short nxt_pid;
  697.             int proc;
  698.             int bufsiz = ustrlen(crp, s.arg1)+1;
  699.             struct mmu *parent = crp->parent;
  700.             struct mmu *predecessor = crp;
  701.             char *kbuf = xmalloc(bufsiz);
  702.             enum    {maxargs=2048,maxenv=2048};
  703.             char **argp = (char **)s.arg2;
  704.             char **env = (char **)s.arg3;
  705.             char *ptr;
  706.             char **args = (char **)xmalloc(maxargs*sizeof(char *));
  707.             char **envs = (char **)xmalloc(maxenv*sizeof(char *));
  708.             long argcnt = 0;
  709.             long envcnt = 0;
  710.             do
  711.                 {
  712.                 kumemcpy(parent, &ptr, (long)argp, sizeof(char *));
  713.                 if (ptr)
  714.                     {
  715.                     long bufsiz = ustrlen(parent, (long)ptr)+1;
  716.                     char *kbuf = xmalloc(bufsiz);
  717.                     kustrcpy(parent, kbuf, (long)ptr);
  718.                     args[argcnt] = kbuf;
  719.                     ++argcnt;
  720.                     ++argp;
  721.                     }
  722.                 }
  723.             while (ptr && (argcnt<maxargs));
  724.             do
  725.                 {
  726.                 kumemcpy(parent, &ptr, (long)env, sizeof(char *));
  727.                 if (ptr)
  728.                     {
  729.                     long bufsiz = ustrlen(parent, (long)ptr)+1;
  730.                     char *kbuf = xmalloc(bufsiz);
  731.                     kustrcpy(parent, kbuf, (long)ptr);
  732.                     envs[envcnt] = kbuf;
  733.                     ++envcnt;
  734.                     ++env;
  735.                     }
  736.                 }
  737.             while (ptr && (envcnt<maxenv));
  738.             kustrcpy(crp, kbuf, s.arg1);
  739.             --nxt_pid;
  740.             crp->result = newproc(kbuf, args, envs, crp, argcnt, envcnt);
  741.             free(envs);
  742.             free(args);
  743.             crp->parent = parent;
  744.             free(kbuf);
  745. #if 0
  746.             if (debug)
  747.                 {
  748.                 char debugstr[99];
  749.                 long phys_pc = (long)LTP(crp->registers.pc);
  750.                 ksprintf(debugstr+1, "PC kernel address = %8.8X\n", phys_pc);
  751.                 *debugstr = strlen(debugstr+1);
  752.                 kprintf(debugstr+1);
  753.                 DebugStr(debugstr);
  754.                 }
  755. #endif
  756.             if (crp->trace_me)
  757.                 {
  758.                 crp->state = 'T';
  759.                 crp->result = W_STOPCODE(SIGTRAP);
  760.                 }
  761. #if 0
  762.             if (predecessor->savestack)    /* saved from vfork() */
  763.                 {
  764.                 enum {carry = 1};
  765.                 predecessor->result = crp->pid;
  766.                 predecessor->registers = predecessor->saveregs;
  767.                 ukmemcpy(predecessor, predecessor->registers.save[15], predecessor->savestack, predecessor->stack_limit - predecessor->registers.save[15]);
  768.                 free(predecessor->savestack);
  769.                 predecessor->savestack = 0;
  770.                 predecessor->registers.save[0] = crp->pid;
  771.                 predecessor->registers.flags &= ~carry;
  772.                 predecessor->state = 'W';
  773.                 crp->parent = predecessor;
  774.                 }
  775. #endif
  776.             break;
  777.             }
  778.         case SYS_umask:
  779.             crp->result = 0;
  780.             break;
  781.         case SYS_fstat:
  782.             {
  783.             struct stat kstat;
  784.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  785.             else crp->result = fstat(crp->fd_tab[s.arg1], &kstat);
  786.             ukmemcpy(crp, s.arg2, &kstat, sizeof(struct stat));
  787.             break;
  788.             }
  789.         case SYS_access:
  790.             {
  791.             int bufsiz = ustrlen(crp, s.arg1)+1;
  792.             char *kbuf = xmalloc(bufsiz);
  793.             kustrcpy(crp, kbuf, s.arg1);            
  794.             crp->result = access(kbuf, s.arg2);
  795.             free(kbuf);
  796.             break;
  797.             }
  798.         case SYS_kill:
  799.             crp->result = 0;
  800.             break;
  801.         case SYS_stat:
  802.             {
  803.             int bufsiz = ustrlen(crp, s.arg1)+1;
  804.             struct stat kstat;
  805.             char *kbuf = xmalloc(bufsiz);
  806.             kustrcpy(crp, kbuf, s.arg1);            
  807.             crp->result = stat(kbuf, &kstat);
  808.             ukmemcpy(crp, s.arg2, &kstat, sizeof(struct stat));
  809.             free(kbuf);
  810.             break;
  811.             }
  812.         case SYS_lstat:
  813.             {
  814.             int bufsiz = ustrlen(crp, s.arg1)+1;
  815.             struct stat kstat;
  816.             char *kbuf = xmalloc(bufsiz);
  817.             kustrcpy(crp, kbuf, s.arg1);            
  818.             crp->result = lstat(kbuf, &kstat);
  819.             ukmemcpy(crp, s.arg2, &kstat, sizeof(struct stat));
  820.             free(kbuf);
  821.             break;
  822.             }
  823.         case SYS_getppid:
  824.             crp->result = 1;
  825.             break;
  826.         case SYS_dup:
  827.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  828.             else
  829.                 {
  830.                 int fd = 0;
  831.                 while ((fd <= OPEN_MAX) && crp->fd_tab[fd]) ++fd;
  832.                 if (fd <= OPEN_MAX) 
  833.                     {
  834.                     crp->fd_tab[fd] = s.arg1;
  835.                     crp->result = fd;
  836.                     }
  837.                 else
  838.                     {
  839.                     crp->result = -1;
  840.                     }
  841.                 }    
  842.             break;
  843.         case SYS_pipe:
  844.             {
  845.             int arg[2],i;
  846.             crp->result = pipe(arg);
  847.             if (!crp->result) for (i= 0; i < 2; i++)
  848.                 {
  849.                 int fd = 0;
  850.                 while ((fd <= OPEN_MAX) && crp->fd_tab[fd]) ++fd;
  851.                 if (fd <= OPEN_MAX) 
  852.                     {
  853.                     crp->fd_tab[fd] = arg[1];
  854.                     arg[i] = fd;
  855.                     }
  856.                 else
  857.                     {
  858.                     crp->result = -1;
  859.                     }
  860.                 }    
  861.             ukmemcpy(crp, s.arg1, arg, sizeof(arg));
  862.             if (debug) kprintf("pipe(%x[]={%x,%x}) returned %d\n", s.arg1, arg[0], arg[1], crp->result);
  863.             break;
  864.             }
  865.         case SYS_getegid:
  866.             crp->result = 0;
  867.             break;
  868.         case SYS_sigaction:
  869.             {
  870.             struct sigaction tmp_sig;
  871.             kumemcpy(crp, &tmp_sig, s.arg2, sizeof(struct sigaction));
  872.             crp->result = sigaction(s.arg1, &tmp_sig, &tmp_sig);
  873.             ukmemcpy(crp, s.arg3, &tmp_sig, sizeof(struct sigaction));
  874.             break;
  875.             }
  876.         case SYS_getgid:
  877.             crp->result = 0;
  878.             break;
  879.         case SYS_sigprocmask:
  880.             {
  881. #if 0
  882.             sigset_t mask1,mask2;
  883.             if (s.arg2 > 0) kumemcpy(crp, &mask1, s.arg2, sizeof(sigset_t));
  884.             kumemcpy(crp, &mask2, s.arg3, sizeof(sigset_t));
  885.             crp->result = sigprocmask(s.arg1, &mask1, &mask2);
  886.             ukmemcpy(crp, s.arg3, &mask2, sizeof(sigset_t));
  887. #else
  888.             crp->result = 0;
  889. #endif
  890.             break;
  891.             }
  892.         case SYS_getlogin:
  893.             crp->result = 0;
  894.             break;
  895.         case SYS_setlogin:
  896.             crp->result = -1;
  897.             break;
  898.         case SYS_ioctl:
  899.             {
  900.             void *kbuf = xmalloc(IOCPARM_LEN(s.arg2));
  901.             kumemcpy(crp, kbuf, s.arg3, IOCPARM_LEN(s.arg2));
  902.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  903.             else crp->result = ioctl(crp->fd_tab[s.arg1], s.arg2, kbuf);
  904.             ukmemcpy(crp, s.arg3, kbuf, IOCPARM_LEN(s.arg2));
  905.             free(kbuf);
  906.             break;
  907.             }
  908.         case SYS_getpagesize:
  909.             crp->result = page_size;
  910.             break;
  911.         case SYS_sbrk:
  912.             s.arg1 += crp->sbreak;
  913.             if (!crp->sbreak)    /* supervisor address space relocatable process */
  914.                 {
  915.                 Ptr nxt = NewPtrClear(s.arg1+sizeof(void *));
  916.                 if (!nxt) crp->result = -1;
  917.                 else
  918.                     {
  919.                     struct mem_chain *last = crp->storage;
  920.                     crp->storage = (struct mem_chain *)nxt;
  921.                     crp->storage->nxt = last;
  922.                     crp->result = (long)(crp->storage->storage);
  923. #ifdef PROTECTED
  924.                       supervisor_space(crp, crp->result, crp->result+s.arg1);
  925. #endif
  926.                     }
  927.                 break;
  928.                 }
  929. #ifdef PROTECTED
  930.         case SYS_break:
  931.             if (!crp->sbreak || (s.arg1 > crp->registers.save[15]-8192)) crp->result = -1;
  932.             else
  933.                 {
  934.                 if (s.arg1 > crp->sbreak)
  935.                     {
  936.                     long siz = s.arg1 - crp->sbreak;
  937.                     if (lower_space(crp, s.arg1))
  938.                         crp->result = -1;
  939.                     else 
  940.                         {
  941.                         crp->result = crp->sbreak;
  942.                         crp->sbreak = s.arg1;
  943.                         umemset(crp, crp->result, 0, siz);
  944.                         }
  945.                     }
  946.                 }
  947.             break;
  948.         case SYS_mmap:
  949. //            crp->result = (long)mmap((caddr_t)s.arg1,s.arg2,s.arg3,s.arg4,s.arg5,s.arg6);
  950.             break;
  951.         case SYS_munmap:
  952. //            crp->result = (long)munmap((caddr_t)s.arg1,s.arg2,s.arg3,s.arg4,s.arg5,s.arg6);
  953.             crp->result = 0; /* just pretend to succeed */
  954.             break;
  955. #endif
  956.         case SYS_getgroups:
  957.             {
  958.             int *groups = xmalloc(s.arg1*sizeof(int));
  959.             crp->result = getgroups(s.arg1, groups);
  960.             ukmemcpy(crp, s.arg2, groups, s.arg1*sizeof(int));
  961.             free(groups);
  962.             break;
  963.             }
  964.         case SYS_getpgrp:
  965.             crp->result = 12345;
  966.             break;
  967.         case SYS_setpgid:
  968.             crp->result = 0;
  969.             break;
  970.         case SYS_getdtablesize:
  971.             crp->result = getdtablesize();
  972.             break;
  973.         case SYS_gethostname:
  974.             {
  975.             char *machname = xmalloc(s.arg2);
  976.             crp->result = gethostname( machname, s.arg2);
  977.             ukmemcpy(crp, s.arg1, machname, s.arg2);
  978.             free(machname);
  979.             break;
  980.             }
  981.         case SYS_dup2:
  982.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  983.             else
  984.                 {
  985.                 crp->fd_tab[s.arg2] = crp->fd_tab[s.arg1];
  986.                 crp->result = 0;
  987.                 }
  988.             break;
  989.         case SYS_fcntl:
  990.             if (debug) kprintf("fcntl(%d,%d,%d)\n", s.arg1, s.arg2, s.arg3);
  991.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  992.             else switch(s.arg2)
  993.                  {
  994.                  case F_DUPFD :
  995.                     {
  996.                     int fd = s.arg3;
  997.                     while ((fd <= OPEN_MAX) && crp->fd_tab[fd]) ++fd;
  998.                     if (fd <= OPEN_MAX) 
  999.                         {
  1000.                         crp->fd_tab[fd] = crp->fd_tab[s.arg1];
  1001.                         crp->result = fd;
  1002.                         }
  1003.                     else
  1004.                         {
  1005.                         crp->result = -1;
  1006.                         }
  1007.                      break;
  1008.                      }
  1009.                  case F_SETFD : 
  1010.                      if (debug) kprintf("Set fd flags\n"); 
  1011.                      crp->result = 0; break;
  1012.                 case F_GETFL : 
  1013.                     if (debug) kprintf("Get file status flags\n"); 
  1014.                     crp->result = O_RDWR; break; /* dummy */
  1015.                 case F_SETFL : 
  1016.                     if (debug) kprintf("Set file status flags\n"); 
  1017.                     crp->result = 0; break;
  1018.                  default: kprintf("Unsupported fcntl cmd %d\n", s.arg2);
  1019.                  }
  1020.             break;
  1021.         case SYS_select:
  1022.             {
  1023.             long tab,width,max = 0;
  1024.             fd_set fds[3],kfds[3];
  1025.             struct timeval timeout;
  1026.             if (s.arg2) kumemcpy(crp, &fds[0], s.arg2, sizeof(fd_set));
  1027.             else FD_ZERO(&fds[0]);
  1028.             if (s.arg3) kumemcpy(crp, &fds[1], s.arg3, sizeof(fd_set));
  1029.             else FD_ZERO(&fds[1]);
  1030.             if (s.arg4) kumemcpy(crp, &fds[2], s.arg4, sizeof(fd_set));
  1031.             else FD_ZERO(&fds[2]);
  1032.             kumemcpy(crp, &timeout, s.arg5, sizeof(timeout));
  1033.             for (tab = 3; tab--; )
  1034.                 {
  1035.                 FD_ZERO(&kfds[tab]);
  1036.                 for (width = s.arg1; width--; )
  1037.                     {
  1038.                     if (FD_ISSET(width, &fds[tab]) && crp->fd_tab[width])
  1039.                         {
  1040.                         int kfd = crp->fd_tab[width];
  1041.                         if (kfd < 0)
  1042.                             {
  1043.                             if (~kfd > max) max = ~kfd;
  1044.                             FD_SET(~kfd, &kfds[tab]);
  1045.                             }
  1046.                         }
  1047.                     }
  1048.                 }
  1049.             crp->result = s_select(max+1, &kfds[0], &kfds[1], &kfds[2], &timeout);
  1050.             if (crp->result != -1) for (tab = 3; tab--; )
  1051.                 {
  1052.                 for (width = s.arg1; width--; ) if (FD_ISSET(width, &fds[tab]))
  1053.                     {
  1054.                     if (crp->fd_tab[width])
  1055.                         {
  1056.                         int kfd = crp->fd_tab[width];
  1057.                         if (kfd < 0)
  1058.                             {
  1059.                             if (!FD_ISSET(~kfd, &kfds[tab]))
  1060.                                 {
  1061.                                 FD_CLR(width, &fds[tab]);
  1062.                                 kprintf("Nothing available chan %d fd %d (%d)\n", tab, width, ~kfd);
  1063.                                 }
  1064.                             else kprintf("Data available chan %d fd %d (%d)\n", tab, width, ~kfd);
  1065.                             }
  1066.                         else
  1067.                             {
  1068.                             FD_CLR(width, &fds[tab]);
  1069.                             kprintf("Select on a non-socket\n");
  1070.                             }
  1071.                         }
  1072.                     else
  1073.                         {
  1074.                         FD_CLR(width, &fds[tab]);
  1075.                         kprintf("Select on a closed fd %d\n", width);
  1076.                         }
  1077.                     }
  1078.                 }
  1079.             if (s.arg2) ukmemcpy(crp, s.arg2, &fds[0], sizeof(fd_set));
  1080.             if (s.arg3) ukmemcpy(crp, s.arg3, &fds[1], sizeof(fd_set));
  1081.             if (s.arg4) ukmemcpy(crp, s.arg4, &fds[2], sizeof(fd_set));
  1082.             break;
  1083.             }
  1084.         case SYS_socket:
  1085.             crp->result = s_socket(s.arg1, s.arg2, s.arg3);
  1086.             if (crp->result != -1)
  1087.                 {
  1088.                 int fd = 0;
  1089.                 while ((fd <= OPEN_MAX) && crp->fd_tab[fd]) ++fd;
  1090.                 if (fd <= OPEN_MAX) 
  1091.                     {
  1092.                     crp->fd_tab[fd] = ~crp->result;
  1093.                     crp->result = fd;
  1094.                     }
  1095.                 else
  1096.                     {
  1097.                     s_close(crp->result);
  1098.                     crp->result = -1;
  1099.                     }
  1100.                 }    
  1101.              if ((crp->result==-1))
  1102.                  {
  1103.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  1104.                  }
  1105.             break;
  1106.         case SYS_connect:
  1107.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  1108.             else
  1109.                 {
  1110.                 int kfd = crp->fd_tab[s.arg1];
  1111.                 if (kfd < 0) 
  1112.                     {
  1113.                     struct sockaddr sa_addr;
  1114.                     kumemcpy(crp, &sa_addr, s.arg2, sizeof(sa_addr));
  1115.                     crp->result = s_connect(~kfd, &sa_addr, s.arg3);
  1116.                     ukmemcpy(crp, s.arg2, &sa_addr, sizeof(sa_addr));
  1117.                     }
  1118.                 }
  1119.              if ((crp->result==-1))
  1120.                  {
  1121.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  1122.                  }
  1123.             break;
  1124.         case SYS_getpriority:
  1125.             crp->result = 0;
  1126.             break;
  1127.         case SYS_sigreturn:
  1128.             {
  1129.             struct sigcontext context;
  1130.             kumemcpy(crp, &context, s.arg1, sizeof(struct sigcontext));
  1131.             crp->result = sigreturn(&context);
  1132.             ukmemcpy(crp, s.arg1, &context, sizeof(struct sigcontext));
  1133.             break;
  1134.             }
  1135.         case SYS_bind:
  1136.             {
  1137.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  1138.             else
  1139.                 {
  1140.                 int kfd = crp->fd_tab[s.arg1];
  1141.                 if (kfd < 0) 
  1142.                     {
  1143.                     struct sockaddr sa_addr;
  1144.                     kumemcpy(crp, &sa_addr, s.arg2, sizeof(sa_addr));
  1145.                     crp->result = s_bind(~kfd, &sa_addr, s.arg3);
  1146.                     ukmemcpy(crp, s.arg2, &sa_addr, sizeof(sa_addr));
  1147.                     }
  1148.                 }
  1149.              if ((crp->result==-1))
  1150.                  {
  1151.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  1152.                  }
  1153.             break;
  1154.             }
  1155.         case SYS_setsockopt:
  1156.             errno = EOPNOTSUPP;
  1157.             crp->result = -1;
  1158.             break;
  1159.         case SYS_listen:
  1160.             {
  1161.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  1162.             else
  1163.                 {
  1164.                 int kfd = crp->fd_tab[s.arg1];
  1165.                 if (kfd < 0) 
  1166.                     {
  1167.                     crp->result = s_listen(~kfd, s.arg2);
  1168.                     }
  1169.                 }
  1170.              if ((crp->result==-1))
  1171.                  {
  1172.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  1173.                  }
  1174.             break;
  1175.             }
  1176.         case SYS_sigstack:
  1177.             {
  1178.             struct sigstack stack1,stack2;
  1179.             kumemcpy(crp, &stack1, s.arg1, sizeof(struct sigstack));
  1180.             kumemcpy(crp, &stack2, s.arg2, sizeof(struct sigstack));
  1181.             crp->result = sigstack(&stack1, &stack2);
  1182.             ukmemcpy(crp, s.arg2, &stack2, sizeof(struct sigstack));
  1183.             break;
  1184.             }
  1185.         case SYS_sigsuspend:
  1186.             {
  1187.             sigset_t mask1;
  1188.             kumemcpy(crp, &mask1, s.arg1, sizeof(sigset_t));
  1189.             crp->result = sigsuspend(&mask1);
  1190.             crp->state = 'W';
  1191.             break;
  1192.             }
  1193.         case SYS_gettimeofday:
  1194.             {
  1195.             struct timeval ktime;
  1196.             struct timezone kzone;
  1197.             gettimeofday(&ktime, &kzone);
  1198.             if (s.arg1) ukmemcpy(crp, s.arg1, &ktime, sizeof(ktime));
  1199.             if (s.arg2) ukmemcpy(crp, s.arg2, &kzone, sizeof(kzone));
  1200.             crp->result = 0;
  1201.             break;
  1202.             }
  1203.         case SYS_getsockopt:
  1204.             errno = EOPNOTSUPP;
  1205.             crp->result = -1;
  1206.             break;
  1207.         case SYS_getrusage:
  1208.             {
  1209.             struct rusage kusage;
  1210.             memset(&kusage, 0, sizeof(kusage));
  1211.             crp->result = 0;
  1212.             kusage.ru_utime.tv_usec = (crp->ticks%60)*1000000L/60;
  1213.             kusage.ru_utime.tv_sec = crp->ticks/60;
  1214.             ukmemcpy(crp, s.arg2, &kusage, sizeof(kusage));
  1215.             break;
  1216.             }
  1217.         case SYS_writev:
  1218.             {
  1219.             int i;
  1220.             struct iovec *iov = xmalloc(s.arg3*sizeof(struct iovec));
  1221.             kumemcpy(crp, iov, s.arg2, s.arg3*sizeof(struct iovec));
  1222.             crp->result = 0;
  1223.             for (i = 0; i < s.arg3; i++)        
  1224.                 {
  1225.                 char *kbuf = xmalloc(iov[i].iov_len);
  1226.                 kumemcpy(crp, kbuf, (long)iov[i].iov_base, iov[i].iov_len);
  1227.                 if ((crp->result==-1)||(s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1])
  1228.                     {
  1229.                     i = s.arg3;
  1230.                     crp->result = -1;
  1231.                     }
  1232.                 else crp->result = write(crp->fd_tab[s.arg1], kbuf, iov[i].iov_len);
  1233.                 free(kbuf);
  1234.                 }
  1235.             free(iov);
  1236.             break;
  1237.             }
  1238.         case SYS_rename:
  1239.             {
  1240.             int bufsiz1 = ustrlen(crp, s.arg1)+1;
  1241.             char *kbuf1 = xmalloc(bufsiz1);
  1242.             int bufsiz2 = ustrlen(crp, s.arg2)+1;
  1243.             char *kbuf2 = xmalloc(bufsiz2);
  1244.             kustrcpy(crp, kbuf1, s.arg1);            
  1245.             kustrcpy(crp, kbuf2, s.arg2);            
  1246.             crp->result = rename(kbuf1, kbuf2);
  1247.             free(kbuf1);
  1248.             free(kbuf2);
  1249.             break;
  1250.             }
  1251.         case SYS_ftruncate:
  1252.             {
  1253.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  1254.             else crp->result = ftruncate(crp->fd_tab[s.arg1], s.arg2);
  1255.             break;
  1256.             }
  1257.         case SYS_sendto:
  1258.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  1259.             else
  1260.                 {
  1261.                 int kfd = crp->fd_tab[s.arg1];
  1262.                 if (kfd < 0) 
  1263.                     {
  1264.                     int tolen;
  1265.                     struct sockaddr sa_to;
  1266.                     char *buffer = xmalloc(s.arg3);
  1267.                     kumemcpy(crp, buffer, s.arg2, s.arg3);
  1268.                     kumemcpy(crp, &sa_to, s.arg5, sizeof(sa_to));
  1269.                     crp->result = s_sendto (~kfd, buffer, s.arg3, s.arg4, &sa_to, &tolen);
  1270.                     ukmemcpy(crp, s.arg5, &sa_to, sizeof(sa_to));
  1271.                     ukmemcpy(crp, s.arg6, &tolen, sizeof(int));
  1272.                     free(buffer);
  1273.                     }
  1274.                 }
  1275.              if ((crp->result==-1))
  1276.                  {
  1277.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  1278.                  }
  1279.             break;
  1280.         case SYS_mkdir:
  1281.             {
  1282.             int bufsiz = ustrlen(crp, s.arg1)+1;
  1283.             char *kbuf = xmalloc(bufsiz);
  1284.             kustrcpy(crp, kbuf, s.arg1);            
  1285.             crp->result = mkdir(kbuf, s.arg2);
  1286.             free(kbuf);        
  1287.             break;
  1288.             }
  1289.         case SYS_rmdir:
  1290.             {
  1291.             int bufsiz = ustrlen(crp, s.arg1)+1;
  1292.             char *kbuf = xmalloc(bufsiz);
  1293.             kustrcpy(crp, kbuf, s.arg1);            
  1294.             crp->result = rmdir(kbuf);    
  1295.             free(kbuf);        
  1296.             break;
  1297.             }
  1298.         case SYS_utimes:
  1299.             {
  1300.             struct timeval temps;
  1301.             int bufsiz = ustrlen(crp, s.arg1)+1;
  1302.             char *kbuf = xmalloc(bufsiz);
  1303.             kustrcpy(crp, kbuf, s.arg1);            
  1304.             kumemcpy(crp, &temps, s.arg2, sizeof(temps));
  1305.             crp->result = utimes(kbuf, &temps);
  1306.             break;
  1307.             }
  1308.         case SYS_getrlimit:
  1309.             {
  1310.             struct rlimit klimit;
  1311.             crp->result = getrlimit(s.arg1, &klimit);
  1312.             ukmemcpy(crp, s.arg2, &klimit, sizeof(struct rlimit));
  1313.             break;
  1314.             }
  1315.         case SYS_setrlimit:
  1316.             {
  1317.             struct rlimit klimit;
  1318.             kumemcpy(crp, &klimit, s.arg2, sizeof(struct rlimit));
  1319.             crp->result = setrlimit(s.arg1, &klimit);
  1320.             break;
  1321.             }
  1322.         case SYS_getdirentries:
  1323.             {
  1324.             long actualsize;
  1325.             char *kbuf = xmalloc(s.arg3);
  1326.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  1327.             else crp->result = getdirentries(crp->fd_tab[s.arg1], kbuf, s.arg3, &actualsize);
  1328.             ukmemcpy(crp, s.arg2, kbuf, s.arg3);
  1329.             ukmemcpy(crp, s.arg4, &actualsize, sizeof(long));
  1330.             break;
  1331.             }
  1332.         }
  1333.      if (debug && (crp->result==-1))
  1334.          {
  1335.          kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  1336.          }
  1337.     /* save crp->result of system call */
  1338.     if (crp->state == 'R')
  1339.         {
  1340.         enum {carry=1};
  1341.         if (crp->result==-1)
  1342.             {
  1343.             crp->registers.save[0] = errno;
  1344.             crp->registers.flags |= carry;
  1345.             }
  1346.         else
  1347.             {
  1348.             crp->registers.save[0] = crp->result;
  1349.             crp->registers.flags &= ~carry;
  1350.             }
  1351. //        crp->registers.save[1] = 0;    /* is this correct ? */
  1352.         }
  1353.     }
  1354.  
  1355.