home *** CD-ROM | disk | FTP | other *** search
- #ifdef THINK_C
- #include <LoMem.h>
- #include <THINK.h>
- #define get_time() TimeLM
- #define get_ticks() Ticks
- #else
- #include <Types.h>
- #include <Errors.h>
- #include <Memory.h>
- #include <OSUtils.h>
- #include <SegLoad.h>
- #include <Quickdraw.h>
- #include <Files.h>
- #include <Menus.h>
- #include <Fonts.h>
- #include <Resources.h>
- #include <GestaltEqu.h>
- #include <Traps.h>
- #include <Aliases.h>
- #include <Packages.h>
- #include <Processes.h>
- #include <AppleEvents.h>
- #include <ToolUtils.h>
- #include <SysEqu.h>
- #define get_time() (*(long *)TimeLM)
- #define get_ticks() (*(long *)Ticks)
- enum {FALSE,TRUE};
- #endif
- #include <GestaltEqu.h>
- #include <ToolUtils.h>
- #include <Retrace.h>
- #include <OSUtils.h>
- #include <stdio.h>
- #include <errno.h>
- #include <string.h>
- #include <stdlib.h>
- #include <dirent.h>
- #include <fcntl.h>
- #include <utime.h>
- #include <unistd.h>
- #include <sys/uio.h>
- #include <sys/mman.h>
- #include <sys/stat.h>
- #include <sys/syscall.h>
- #include <sys/ioctl.h>
- #include <sys/syslimits.h>
- #include <sys/time.h>
- #include <sys/resource.h>
- #include <sys/signal.h>
- #include <sys/signalvar.h>
- #include <sys/ptrace.h>
- #include <sys/wait.h>
- #include <sys/socket.h>
- #include "crtlocal.h"
- #include "proc_mmu.h"
-
- struct mmu *proc_tab[maxproc];
-
- void sched(void)
- {
- static long real_time = 0;
- static int proc_no = 0;
- long now = get_ticks();
- int must_swap = 0;
- if (crp) crp->ticks += now-old_ticks;
- do
- {
- int cnt;
- if ((now-real_time > kInterval) || (now < real_time))
- {
- real_time = now;
- must_swap = 1;
- checkevents();
- }
- if (interrupt && (crp->state=='R'))
- {
- interrupt = 0;
- if (crp->trace_me)
- {
- crp->state = 'T';
- crp->result = W_STOPCODE(SIGINT);
- }
- else
- {
- crp->state = 'X';
- crp->result = SIGINT;
- }
- must_swap = 1;
- }
- cnt = 2*sizeof(proc_tab)/sizeof(*proc_tab);
- if (must_swap || !crp || (crp->state!='D')) do
- {
- proc_no = (proc_no+1)%(sizeof(proc_tab)/sizeof(*proc_tab));
- }
- #if 0
- 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'))) ));
- #else
- while (cnt-- && !proc_tab[proc_no]);
- #endif
- if (crp != proc_tab[proc_no])
- {
- if (crp && crp->savestack)
- {
- int usp = crp->registers.save[15];
- crp->savestack = xrealloc(crp->savestack, crp->stack_limit-usp);
- kumemcpy(crp, crp->savestack, usp, crp->stack_limit-usp);
- }
- crp = proc_tab[proc_no];
- if (crp && crp->savestack)
- {
- int usp = crp->registers.save[15];
- ukmemcpy(crp, usp, (void *)(crp->savestack), crp->stack_limit-usp);
- }
- }
- if (crp) switch(crp->state)
- {
- #if 1
- case 'W':
- {
- int proc_no = 0;
- int cnt = sizeof(proc_tab)/sizeof(*proc_tab);
- while (--cnt && (!proc_tab[proc_no] || (proc_tab[proc_no]->parent != crp)))
- ++proc_no;
- if (!cnt)
- {
- crp->state = 'R';
- errno = ECHILD;
- crp->result = -1;
- }
- break;
- }
- #endif
- case 'Z':
- {
- int arg = OPEN_MAX;
- while (arg--) if (crp->fd_tab[arg])
- {
- int stale = 1;
- int kfd = crp->fd_tab[arg];
- int cnt1 = sizeof(proc_tab)/sizeof(*proc_tab);
- crp->fd_tab[arg] = 0;
- while (cnt1--)
- {
- if (proc_tab[cnt1] && (proc_tab[cnt1]->state != 'Z'))
- {
- int cnt2 = OPEN_MAX;
- while (cnt2--)
- {
- if (proc_tab[cnt1]->fd_tab[cnt2] == kfd)
- {
- // kprintf("fd %d still open in proc %d\n", arg, proc_tab[cnt1]->pid);
- stale = cnt1 = cnt2 = 0;
- }
- }
- }
- }
- if (stale) close(kfd);
- }
- #ifdef PROTECTED
- free_space(crp);
- #else
- if (!crp->sbreak) /* must be relocatable */
- {
- struct mem_chain *storage = crp->storage;
- while (storage)
- {
- struct mem_chain *nxt = storage->nxt;
- DisposPtr((Ptr)storage);
- storage = nxt;
- }
- }
- #endif
- if (crp->savestack) free(crp->savestack);
- if (debug)
- kprintf("Activated pages = %ld\n", activated_pages);
- free(crp->p_sigacts);
- free(crp->self);
- // mstats("MMU");
- crp = proc_tab[proc_no] = 0;
- {
- ParamBlockRec vol;
- vol.volumeParam.ioNamePtr = 0;
- vol.volumeParam.ioVRefNum = crt_ioVRefNum;
- PBFlushVolSync(&vol);
- }
- break;
- }
- case 'X':
- crp->state = 'Z';
- case 'T':
- {
- if (crp->parent && (crp->parent->state=='W'))
- {
- crp->parent->state = 'D';
- crp->parent->registers.save[0] = SYS_wait4;
- }
- break;
- }
- case 'D':
- {
- system_call();
- break;
- }
- }
- else checkevents();
- old_ticks = now = get_ticks();
- must_swap = 1;
- }
- while (!crp || crp->state != 'R');
- }
-
- struct args
- {
- void *dummy;
- long arg1,arg2,arg3,arg4,arg5,arg6,arg7;
- };
-
- gettimeofday(struct timeval *ktime, struct timezone *kzone)
- {
- memset(kzone, 0, sizeof(*kzone));
- ktime->tv_sec = unixTime(get_time());
- ktime->tv_usec = (get_ticks()%60)*1000000/60;
- }
-
- void system_call(void)
- {
- struct args s;
- crp->state = 'R'; /* runnable unless otherwise overridden */
- kumemcpy(crp, &s, crp->registers.save[15], sizeof(s));
- #if 1
- if ((unsigned long)s.dummy <= 183)
- {
- crp->registers.save[0] = (long)s.dummy;
- memcpy(&s.arg1, &s.arg2, sizeof(s)-8);
- crp->registers.save[15] += 4;
- }
- #endif
- crt_parID = crp->crt_parID;
- root_parID = crp->root_parID;
- if (debug)
- {
- kprintf("System call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
- }
- errno = ENOSYS;
- switch(crp->registers.save[0])
- {
- default:
- #ifdef PROTECTED
- if (virtual && !crp->registers.save[0])
- {
- crp->registers.pc = crp->header.a_entry;
- crp->registers.save[15] = crp->stack_limit-256;
- }
- else
- #endif
- {
- kprintf("Unimplemented system call %s\n", callname(crp->registers.save[0]));
- crp->result = -1;
- }
- break;
- case SYS_exit:
- {
- crp->result = (s.arg1&255)<<8;
- crp->state = 'X';
- }
- break;
- case SYS_fork:
- if (crp->sbreak) /* genuine user mem proc. */
- {
- newproc(0, NULL, NULL, crp, 0, 0);
- crp->result = 0;
- /* save parent->result of system call */
- {
- enum {carry=1};
- {
- crp->parent->registers.save[0] = crp->pid;
- crp->parent->registers.flags &= ~carry;
- }
- crp->parent->registers.save[1] = 0; /* is this correct ? */
- }
- break;
- }
- case SYS_vfork:
- {
- newproc(0, NULL, NULL, crp, 0, 0);
- crp->result = 0;
- /* save parent->result of system call */
- {
- enum {carry=1};
- {
- crp->parent->registers.save[0] = crp->pid;
- crp->parent->registers.flags &= ~carry;
- }
- crp->parent->registers.save[1] = 0; /* is this correct ? */
- }
- break;
- }
- case SYS_read:
- {
- if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
- else
- {
- char *kbuf = xmalloc(s.arg3);
- int kfd = crp->fd_tab[s.arg1];
- if (kfd < 0)
- crp->result = s_read(~kfd, kbuf, s.arg3);
- else
- crp->result = read(kfd, kbuf, s.arg3);
- ukmemcpy(crp, s.arg2, kbuf, crp->result);
- free(kbuf);
- if ((kfd >= 0) && (crt_fd_tab[kfd].flags & O_PIPE) && !crp->result)
- {
- int tot = (crt_fd_tab[kfd].fd&-256) == 100<<8;
- int cnt = sizeof(proc_tab)/sizeof(*proc_tab);
- while (cnt--)
- {
- if (proc_tab[cnt] && (proc_tab[cnt]->state != 'Z'))
- {
- int cnt2 = OPEN_MAX;
- while (cnt2--)
- {
- if (proc_tab[cnt]->fd_tab[cnt2] == kfd)
- {
- ++tot;
- }
- }
- }
- }
- if (tot > 1) crp->state = 'D';
- }
- }
- if ((crp->result==-1))
- {
- kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
- }
- break;
- }
- case SYS_write:
- {
- if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
- else
- {
- int kfd = crp->fd_tab[s.arg1];
- char *kbuf = xmalloc(s.arg3);
- kumemcpy(crp, kbuf, s.arg2, s.arg3);
- if (kfd < 0)
- crp->result = s_write(~kfd, kbuf, s.arg3);
- else
- crp->result = write(kfd, kbuf, s.arg3);
- free(kbuf);
- }
- if ((crp->result==-1))
- {
- kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
- }
- break;
- }
- case SYS_open:
- {
- int bufsiz = ustrlen(crp, s.arg1)+1;
- char *kbuf = xmalloc(bufsiz);
- kustrcpy(crp, (void *)kbuf, s.arg1);
- if (debug) kprintf("Open %s\n", kbuf);
- crp->result = open(kbuf, s.arg2, s.arg3);
- if (crp->result != -1)
- {
- int fd = 0;
- while ((fd <= OPEN_MAX) && crp->fd_tab[fd]) ++fd;
- if (fd <= OPEN_MAX)
- {
- crp->fd_tab[fd] = crp->result;
- crp->result = fd;
- }
- else
- {
- close(crp->result);
- crp->result = -1;
- }
- }
- free((void *)kbuf);
- break;
- }
- case SYS_close:
- crp->result = -1;
- if ((s.arg1>=0)&&(s.arg1<=OPEN_MAX)&&crp->fd_tab[s.arg1])
- {
- int kfd = crp->fd_tab[s.arg1];
- int cnt = sizeof(proc_tab)/sizeof(*proc_tab);
- crp->fd_tab[s.arg1] = 0;
- while (cnt--)
- {
- if (proc_tab[cnt] && (proc_tab[cnt]->state != 'Z'))
- {
- int cnt2 = OPEN_MAX;
- while (cnt2--)
- {
- if (proc_tab[cnt]->fd_tab[cnt2] == kfd)
- {
- // kprintf("fd %d still open in proc %d\n", s.arg1, proc_tab[cnt]->pid);
- crp->result = cnt = cnt2 = 0;
- }
- }
- }
- }
- if (crp->result)
- {
- if (kfd < 0)
- crp->result = s_close(~kfd);
- else
- crp->result = close(kfd);
- }
- }
- break;
- case SYS_wait4:
- {
- int proc_no = 0;
- int cnt = sizeof(proc_tab)/sizeof(*proc_tab);
- while (--cnt && (!proc_tab[proc_no] || (proc_tab[proc_no]->parent != crp)
- || ((s.arg1 != -1) && (s.arg1 != proc_tab[proc_no]->pid))))
- ++proc_no;
- if (cnt)
- {
- if ((proc_tab[proc_no]->state == 'T') || (proc_tab[proc_no]->state == 'Z'))
- {
- int waitcode = proc_tab[proc_no]->result;
- ukmemcpy(crp, s.arg2, &waitcode, sizeof(int)); /* for retcode */
- crp->result = proc_tab[proc_no]->pid;
- errno = 0;
- }
- else
- {
- crp->state = 'W';
- crp->result = s.arg2;
- }
- }
- else
- {
- errno = ECHILD;
- umemset(crp, s.arg2, 0, sizeof(int));
- crp->result = -1;
- }
- break;
- }
- case SYS_link:
- errno = EMLINK;
- crp->result = -1;
- break;
- case SYS_unlink:
- {
- int bufsiz = ustrlen(crp, s.arg1)+1;
- char *kbuf = xmalloc(bufsiz);
- kustrcpy(crp, kbuf, s.arg1);
- crp->result = unlink(kbuf);
- free(kbuf);
- break;
- }
- case SYS_chdir:
- {
- int bufsiz = ustrlen(crp, s.arg1)+1;
- char *kbuf = xmalloc(bufsiz);
- kustrcpy(crp, kbuf, s.arg1);
- crp->result = chdir(kbuf);
- if (!crp->result) crp->crt_parID = crt_parID;
- free(kbuf);
- break;
- }
- case SYS_fchdir:
- if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
- else crp->result = fchdir(crp->fd_tab[s.arg1]);
- if (!crp->result) crp->crt_parID = crt_parID;
- break;
- case SYS_mknod:
- {
- int bufsiz = ustrlen(crp, s.arg1)+1;
- char *kbuf = xmalloc(bufsiz);
- kustrcpy(crp, kbuf, s.arg1);
- crp->result = mknod(kbuf, s.arg2, s.arg3);
- free(kbuf);
- break;
- }
- case SYS_chmod:
- {
- int bufsiz = ustrlen(crp, s.arg1)+1;
- char *kbuf = xmalloc(bufsiz);
- kustrcpy(crp, kbuf, s.arg1);
- crp->result = chmod(kbuf, s.arg2);
- free(kbuf);
- break;
- }
- case SYS_chown:
- {
- int bufsiz = ustrlen(crp, s.arg1)+1;
- char *kbuf = xmalloc(bufsiz);
- kustrcpy(crp, kbuf, s.arg1);
- crp->result = chown(kbuf, s.arg2, s.arg3);
- free(kbuf);
- break;
- }
- case SYS_lseek:
- if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
- else crp->result = lseek(crp->fd_tab[s.arg1], s.arg2, s.arg3);
- break;
- case SYS_getpid:
- crp->result = crp->pid;
- break;
- case SYS_getuid:
- crp->result = 0;
- break;
- case SYS_geteuid:
- crp->result = 0;
- break;
- case SYS_ptrace:
- {
- struct mmu *child = NULL;
- int pid = s.arg2;
- long addr = s.arg3;
- long data = s.arg4;
- int proc_no = 0;
- int cnt = sizeof(proc_tab)/sizeof(*proc_tab);
- while (--cnt && (!proc_tab[proc_no] || (pid != proc_tab[proc_no]->pid)))
- ++proc_no;
- if (cnt)
- {
- child = proc_tab[proc_no];
- if ((child->state != 'T') || !child->trace_me)
- {
- errno = ECHILD;
- break;
- }
- else crp->result = 0;
- }
- else
- errno = ECHILD;
- if (debug) kprintf("ptrace(%d,%d,%08X,%08X)\n", s.arg1, pid, addr, data);
- switch(s.arg1)
- {
- case PT_TRACE_ME : if (debug) kprintf("child declares it's being traced\n");
- crp->trace_me = 1;
- crp->result = 0;
- break;
- case PT_READ_I :
- case PT_READ_D : if (debug) kprintf("read word in child's I/D space\n");
- if (child)
- kumemcpy(child, &(crp->result), addr, sizeof(long));
- break;
- case PT_READ_U : kprintf("read word in child's user structure\n");
- crp->result = -1;
- break;
- case PT_WRITE_I :
- case PT_WRITE_D : if (debug) kprintf("write word in child's I/D space\n");
- if (child)
- ukmemcpy(child, addr, &data, sizeof(long));
- break;
- case PT_WRITE_U : kprintf("write word in child's user structure\n");
- crp->result = -1;
- break;
- case PT_CONTINUE : if (debug) kprintf("continue the child\n");
- {
- if (child)
- child->state = 'R';
- break;
- }
- case PT_KILL : if (debug) kprintf("kill the child process\n");
- if (child)
- child->state = 'Z';
- break;
- case PT_STEP : if (debug) kprintf("single step the child\n");
- if (child)
- {
- child->registers.flags |= 0x8000;
- child->state = 'R';
- }
- break;
- case PT_ATTACH : kprintf("attach to running process\n");
- crp->result = -1;
- break;
- case PT_DETACH : kprintf("detach from running process\n");
- crp->result = -1;
- break;
- case PT_GETREGS : if (debug) kprintf("fetch registers\n");
- if (child)
- ukmemcpy(crp, addr, &(child->registers), sizeof(struct userregs));
- break;
- case PT_SETREGS : if (debug) kprintf("set registers\n");
- if (child)
- kumemcpy(crp, &(child->registers), addr, sizeof(struct userregs));
- break;
- default : crp->result = -1;
- }
- break;
- }
- #if 0
- case SYS_recvmsg:
- case SYS_sendmsg:
- #endif
- case SYS_recvfrom:
- if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
- else
- {
- int kfd = crp->fd_tab[s.arg1];
- if (kfd < 0)
- {
- int fromlen;
- struct sockaddr sa_from;
- char *buffer = xmalloc(s.arg3);
- kumemcpy(crp, &sa_from, s.arg5, sizeof(sa_from));
- crp->result = s_sendto (~kfd, buffer, s.arg3, s.arg4, &sa_from, &fromlen);
- ukmemcpy(crp, s.arg5, &sa_from, sizeof(sa_from));
- ukmemcpy(crp, s.arg2, buffer, fromlen);
- ukmemcpy(crp, s.arg6, &fromlen, sizeof(int));
- free(buffer);
- }
- }
- if ((crp->result==-1))
- {
- kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
- }
- break;
- case SYS_accept:
- {
- if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
- else
- {
- int kfd = crp->fd_tab[s.arg1];
- if (kfd < 0)
- {
- int addrlen;
- struct sockaddr sa_addr;
- kumemcpy(crp, &sa_addr, s.arg2, sizeof(sa_addr));
- kumemcpy(crp, &addrlen, s.arg3, sizeof(long));
- crp->result = s_accept(~kfd, &sa_addr, &addrlen);
- ukmemcpy(crp, s.arg2, &sa_addr, sizeof(sa_addr));
- ukmemcpy(crp, s.arg3, &addrlen, sizeof(long));
- }
- }
- if ((crp->result==-1))
- {
- kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
- }
- break;
- }
- case SYS_getpeername:
- {
- break;
- }
- case SYS_getsockname:
- {
- if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
- else
- {
- int kfd = crp->fd_tab[s.arg1];
- if (kfd < 0)
- {
- int addrlen;
- struct sockaddr sa_addr;
- kumemcpy(crp, &sa_addr, s.arg2, sizeof(sa_addr));
- kumemcpy(crp, &addrlen, s.arg3, sizeof(long));
- crp->result = s_getsockname(~kfd, &sa_addr, &addrlen);
- ukmemcpy(crp, s.arg2, &sa_addr, sizeof(sa_addr));
- ukmemcpy(crp, s.arg3, &addrlen, sizeof(long));
- }
- }
- if ((crp->result==-1))
- {
- kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
- }
- break;
- }
- case SYS_symlink:
- {
- int bufsiz1 = ustrlen(crp, s.arg1)+1;
- char *kbuf1 = xmalloc(bufsiz1);
- int bufsiz2 = ustrlen(crp, s.arg2)+1;
- char *kbuf2 = xmalloc(bufsiz2);
- kustrcpy(crp, kbuf1, s.arg1);
- kustrcpy(crp, kbuf2, s.arg2);
- crp->result = symlink(kbuf1, kbuf2);
- free(kbuf1);
- free(kbuf2);
- break;
- }
- case SYS_readlink:
- {
- int bufsiz1 = ustrlen(crp, s.arg1)+1;
- char *kbuf1 = xmalloc(bufsiz1);
- char *kbuf2 = xmalloc(s.arg3);
- kustrcpy(crp, kbuf1, s.arg1);
- crp->result = readlink(kbuf1, kbuf2, s.arg3);
- ukmemcpy(crp, s.arg2, kbuf2, crp->result+1);
- free(kbuf1);
- free(kbuf2);
- break;
- }
- case SYS_execve:
- {
- extern short nxt_pid;
- int proc;
- int bufsiz = ustrlen(crp, s.arg1)+1;
- struct mmu *parent = crp->parent;
- struct mmu *predecessor = crp;
- char *kbuf = xmalloc(bufsiz);
- enum {maxargs=2048,maxenv=2048};
- char **argp = (char **)s.arg2;
- char **env = (char **)s.arg3;
- char *ptr;
- char **args = (char **)xmalloc(maxargs*sizeof(char *));
- char **envs = (char **)xmalloc(maxenv*sizeof(char *));
- long argcnt = 0;
- long envcnt = 0;
- do
- {
- kumemcpy(parent, &ptr, (long)argp, sizeof(char *));
- if (ptr)
- {
- long bufsiz = ustrlen(parent, (long)ptr)+1;
- char *kbuf = xmalloc(bufsiz);
- kustrcpy(parent, kbuf, (long)ptr);
- args[argcnt] = kbuf;
- ++argcnt;
- ++argp;
- }
- }
- while (ptr && (argcnt<maxargs));
- do
- {
- kumemcpy(parent, &ptr, (long)env, sizeof(char *));
- if (ptr)
- {
- long bufsiz = ustrlen(parent, (long)ptr)+1;
- char *kbuf = xmalloc(bufsiz);
- kustrcpy(parent, kbuf, (long)ptr);
- envs[envcnt] = kbuf;
- ++envcnt;
- ++env;
- }
- }
- while (ptr && (envcnt<maxenv));
- kustrcpy(crp, kbuf, s.arg1);
- --nxt_pid;
- crp->result = newproc(kbuf, args, envs, crp, argcnt, envcnt);
- free(envs);
- free(args);
- crp->parent = parent;
- free(kbuf);
- #if 0
- if (debug)
- {
- char debugstr[99];
- long phys_pc = (long)LTP(crp->registers.pc);
- ksprintf(debugstr+1, "PC kernel address = %8.8X\n", phys_pc);
- *debugstr = strlen(debugstr+1);
- kprintf(debugstr+1);
- DebugStr(debugstr);
- }
- #endif
- if (crp->trace_me)
- {
- crp->state = 'T';
- crp->result = W_STOPCODE(SIGTRAP);
- }
- #if 0
- if (predecessor->savestack) /* saved from vfork() */
- {
- enum {carry = 1};
- predecessor->result = crp->pid;
- predecessor->registers = predecessor->saveregs;
- ukmemcpy(predecessor, predecessor->registers.save[15], predecessor->savestack, predecessor->stack_limit - predecessor->registers.save[15]);
- free(predecessor->savestack);
- predecessor->savestack = 0;
- predecessor->registers.save[0] = crp->pid;
- predecessor->registers.flags &= ~carry;
- predecessor->state = 'W';
- crp->parent = predecessor;
- }
- #endif
- break;
- }
- case SYS_umask:
- crp->result = 0;
- break;
- case SYS_fstat:
- {
- struct stat kstat;
- if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
- else crp->result = fstat(crp->fd_tab[s.arg1], &kstat);
- ukmemcpy(crp, s.arg2, &kstat, sizeof(struct stat));
- break;
- }
- case SYS_access:
- {
- int bufsiz = ustrlen(crp, s.arg1)+1;
- char *kbuf = xmalloc(bufsiz);
- kustrcpy(crp, kbuf, s.arg1);
- crp->result = access(kbuf, s.arg2);
- free(kbuf);
- break;
- }
- case SYS_kill:
- crp->result = 0;
- break;
- case SYS_stat:
- {
- int bufsiz = ustrlen(crp, s.arg1)+1;
- struct stat kstat;
- char *kbuf = xmalloc(bufsiz);
- kustrcpy(crp, kbuf, s.arg1);
- crp->result = stat(kbuf, &kstat);
- ukmemcpy(crp, s.arg2, &kstat, sizeof(struct stat));
- free(kbuf);
- break;
- }
- case SYS_lstat:
- {
- int bufsiz = ustrlen(crp, s.arg1)+1;
- struct stat kstat;
- char *kbuf = xmalloc(bufsiz);
- kustrcpy(crp, kbuf, s.arg1);
- crp->result = lstat(kbuf, &kstat);
- ukmemcpy(crp, s.arg2, &kstat, sizeof(struct stat));
- free(kbuf);
- break;
- }
- case SYS_getppid:
- crp->result = 1;
- break;
- case SYS_dup:
- if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
- else
- {
- int fd = 0;
- while ((fd <= OPEN_MAX) && crp->fd_tab[fd]) ++fd;
- if (fd <= OPEN_MAX)
- {
- crp->fd_tab[fd] = s.arg1;
- crp->result = fd;
- }
- else
- {
- crp->result = -1;
- }
- }
- break;
- case SYS_pipe:
- {
- int arg[2],i;
- crp->result = pipe(arg);
- if (!crp->result) for (i= 0; i < 2; i++)
- {
- int fd = 0;
- while ((fd <= OPEN_MAX) && crp->fd_tab[fd]) ++fd;
- if (fd <= OPEN_MAX)
- {
- crp->fd_tab[fd] = arg[1];
- arg[i] = fd;
- }
- else
- {
- crp->result = -1;
- }
- }
- ukmemcpy(crp, s.arg1, arg, sizeof(arg));
- if (debug) kprintf("pipe(%x[]={%x,%x}) returned %d\n", s.arg1, arg[0], arg[1], crp->result);
- break;
- }
- case SYS_getegid:
- crp->result = 0;
- break;
- case SYS_sigaction:
- {
- struct sigaction tmp_sig;
- kumemcpy(crp, &tmp_sig, s.arg2, sizeof(struct sigaction));
- crp->result = sigaction(s.arg1, &tmp_sig, &tmp_sig);
- ukmemcpy(crp, s.arg3, &tmp_sig, sizeof(struct sigaction));
- break;
- }
- case SYS_getgid:
- crp->result = 0;
- break;
- case SYS_sigprocmask:
- {
- #if 0
- sigset_t mask1,mask2;
- if (s.arg2 > 0) kumemcpy(crp, &mask1, s.arg2, sizeof(sigset_t));
- kumemcpy(crp, &mask2, s.arg3, sizeof(sigset_t));
- crp->result = sigprocmask(s.arg1, &mask1, &mask2);
- ukmemcpy(crp, s.arg3, &mask2, sizeof(sigset_t));
- #else
- crp->result = 0;
- #endif
- break;
- }
- case SYS_getlogin:
- crp->result = 0;
- break;
- case SYS_setlogin:
- crp->result = -1;
- break;
- case SYS_ioctl:
- {
- void *kbuf = xmalloc(IOCPARM_LEN(s.arg2));
- kumemcpy(crp, kbuf, s.arg3, IOCPARM_LEN(s.arg2));
- if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
- else crp->result = ioctl(crp->fd_tab[s.arg1], s.arg2, kbuf);
- ukmemcpy(crp, s.arg3, kbuf, IOCPARM_LEN(s.arg2));
- free(kbuf);
- break;
- }
- case SYS_getpagesize:
- crp->result = page_size;
- break;
- case SYS_sbrk:
- s.arg1 += crp->sbreak;
- if (!crp->sbreak) /* supervisor address space relocatable process */
- {
- Ptr nxt = NewPtrClear(s.arg1+sizeof(void *));
- if (!nxt) crp->result = -1;
- else
- {
- struct mem_chain *last = crp->storage;
- crp->storage = (struct mem_chain *)nxt;
- crp->storage->nxt = last;
- crp->result = (long)(crp->storage->storage);
- #ifdef PROTECTED
- supervisor_space(crp, crp->result, crp->result+s.arg1);
- #endif
- }
- break;
- }
- #ifdef PROTECTED
- case SYS_break:
- if (!crp->sbreak || (s.arg1 > crp->registers.save[15]-8192)) crp->result = -1;
- else
- {
- if (s.arg1 > crp->sbreak)
- {
- long siz = s.arg1 - crp->sbreak;
- if (lower_space(crp, s.arg1))
- crp->result = -1;
- else
- {
- crp->result = crp->sbreak;
- crp->sbreak = s.arg1;
- umemset(crp, crp->result, 0, siz);
- }
- }
- }
- break;
- case SYS_mmap:
- // crp->result = (long)mmap((caddr_t)s.arg1,s.arg2,s.arg3,s.arg4,s.arg5,s.arg6);
- break;
- case SYS_munmap:
- // crp->result = (long)munmap((caddr_t)s.arg1,s.arg2,s.arg3,s.arg4,s.arg5,s.arg6);
- crp->result = 0; /* just pretend to succeed */
- break;
- #endif
- case SYS_getgroups:
- {
- int *groups = xmalloc(s.arg1*sizeof(int));
- crp->result = getgroups(s.arg1, groups);
- ukmemcpy(crp, s.arg2, groups, s.arg1*sizeof(int));
- free(groups);
- break;
- }
- case SYS_getpgrp:
- crp->result = 12345;
- break;
- case SYS_setpgid:
- crp->result = 0;
- break;
- case SYS_getdtablesize:
- crp->result = getdtablesize();
- break;
- case SYS_gethostname:
- {
- char *machname = xmalloc(s.arg2);
- crp->result = gethostname( machname, s.arg2);
- ukmemcpy(crp, s.arg1, machname, s.arg2);
- free(machname);
- break;
- }
- case SYS_dup2:
- if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
- else
- {
- crp->fd_tab[s.arg2] = crp->fd_tab[s.arg1];
- crp->result = 0;
- }
- break;
- case SYS_fcntl:
- if (debug) kprintf("fcntl(%d,%d,%d)\n", s.arg1, s.arg2, s.arg3);
- if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
- else switch(s.arg2)
- {
- case F_DUPFD :
- {
- int fd = s.arg3;
- while ((fd <= OPEN_MAX) && crp->fd_tab[fd]) ++fd;
- if (fd <= OPEN_MAX)
- {
- crp->fd_tab[fd] = crp->fd_tab[s.arg1];
- crp->result = fd;
- }
- else
- {
- crp->result = -1;
- }
- break;
- }
- case F_SETFD :
- if (debug) kprintf("Set fd flags\n");
- crp->result = 0; break;
- case F_GETFL :
- if (debug) kprintf("Get file status flags\n");
- crp->result = O_RDWR; break; /* dummy */
- case F_SETFL :
- if (debug) kprintf("Set file status flags\n");
- crp->result = 0; break;
- default: kprintf("Unsupported fcntl cmd %d\n", s.arg2);
- }
- break;
- case SYS_select:
- {
- long tab,width,max = 0;
- fd_set fds[3],kfds[3];
- struct timeval timeout;
- if (s.arg2) kumemcpy(crp, &fds[0], s.arg2, sizeof(fd_set));
- else FD_ZERO(&fds[0]);
- if (s.arg3) kumemcpy(crp, &fds[1], s.arg3, sizeof(fd_set));
- else FD_ZERO(&fds[1]);
- if (s.arg4) kumemcpy(crp, &fds[2], s.arg4, sizeof(fd_set));
- else FD_ZERO(&fds[2]);
- kumemcpy(crp, &timeout, s.arg5, sizeof(timeout));
- for (tab = 3; tab--; )
- {
- FD_ZERO(&kfds[tab]);
- for (width = s.arg1; width--; )
- {
- if (FD_ISSET(width, &fds[tab]) && crp->fd_tab[width])
- {
- int kfd = crp->fd_tab[width];
- if (kfd < 0)
- {
- if (~kfd > max) max = ~kfd;
- FD_SET(~kfd, &kfds[tab]);
- }
- }
- }
- }
- crp->result = s_select(max+1, &kfds[0], &kfds[1], &kfds[2], &timeout);
- if (crp->result != -1) for (tab = 3; tab--; )
- {
- for (width = s.arg1; width--; ) if (FD_ISSET(width, &fds[tab]))
- {
- if (crp->fd_tab[width])
- {
- int kfd = crp->fd_tab[width];
- if (kfd < 0)
- {
- if (!FD_ISSET(~kfd, &kfds[tab]))
- {
- FD_CLR(width, &fds[tab]);
- kprintf("Nothing available chan %d fd %d (%d)\n", tab, width, ~kfd);
- }
- else kprintf("Data available chan %d fd %d (%d)\n", tab, width, ~kfd);
- }
- else
- {
- FD_CLR(width, &fds[tab]);
- kprintf("Select on a non-socket\n");
- }
- }
- else
- {
- FD_CLR(width, &fds[tab]);
- kprintf("Select on a closed fd %d\n", width);
- }
- }
- }
- if (s.arg2) ukmemcpy(crp, s.arg2, &fds[0], sizeof(fd_set));
- if (s.arg3) ukmemcpy(crp, s.arg3, &fds[1], sizeof(fd_set));
- if (s.arg4) ukmemcpy(crp, s.arg4, &fds[2], sizeof(fd_set));
- break;
- }
- case SYS_socket:
- crp->result = s_socket(s.arg1, s.arg2, s.arg3);
- if (crp->result != -1)
- {
- int fd = 0;
- while ((fd <= OPEN_MAX) && crp->fd_tab[fd]) ++fd;
- if (fd <= OPEN_MAX)
- {
- crp->fd_tab[fd] = ~crp->result;
- crp->result = fd;
- }
- else
- {
- s_close(crp->result);
- crp->result = -1;
- }
- }
- if ((crp->result==-1))
- {
- kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
- }
- break;
- case SYS_connect:
- if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
- else
- {
- int kfd = crp->fd_tab[s.arg1];
- if (kfd < 0)
- {
- struct sockaddr sa_addr;
- kumemcpy(crp, &sa_addr, s.arg2, sizeof(sa_addr));
- crp->result = s_connect(~kfd, &sa_addr, s.arg3);
- ukmemcpy(crp, s.arg2, &sa_addr, sizeof(sa_addr));
- }
- }
- if ((crp->result==-1))
- {
- kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
- }
- break;
- case SYS_getpriority:
- crp->result = 0;
- break;
- case SYS_sigreturn:
- {
- struct sigcontext context;
- kumemcpy(crp, &context, s.arg1, sizeof(struct sigcontext));
- crp->result = sigreturn(&context);
- ukmemcpy(crp, s.arg1, &context, sizeof(struct sigcontext));
- break;
- }
- case SYS_bind:
- {
- if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
- else
- {
- int kfd = crp->fd_tab[s.arg1];
- if (kfd < 0)
- {
- struct sockaddr sa_addr;
- kumemcpy(crp, &sa_addr, s.arg2, sizeof(sa_addr));
- crp->result = s_bind(~kfd, &sa_addr, s.arg3);
- ukmemcpy(crp, s.arg2, &sa_addr, sizeof(sa_addr));
- }
- }
- if ((crp->result==-1))
- {
- kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
- }
- break;
- }
- case SYS_setsockopt:
- errno = EOPNOTSUPP;
- crp->result = -1;
- break;
- case SYS_listen:
- {
- if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
- else
- {
- int kfd = crp->fd_tab[s.arg1];
- if (kfd < 0)
- {
- crp->result = s_listen(~kfd, s.arg2);
- }
- }
- if ((crp->result==-1))
- {
- kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
- }
- break;
- }
- case SYS_sigstack:
- {
- struct sigstack stack1,stack2;
- kumemcpy(crp, &stack1, s.arg1, sizeof(struct sigstack));
- kumemcpy(crp, &stack2, s.arg2, sizeof(struct sigstack));
- crp->result = sigstack(&stack1, &stack2);
- ukmemcpy(crp, s.arg2, &stack2, sizeof(struct sigstack));
- break;
- }
- case SYS_sigsuspend:
- {
- sigset_t mask1;
- kumemcpy(crp, &mask1, s.arg1, sizeof(sigset_t));
- crp->result = sigsuspend(&mask1);
- crp->state = 'W';
- break;
- }
- case SYS_gettimeofday:
- {
- struct timeval ktime;
- struct timezone kzone;
- gettimeofday(&ktime, &kzone);
- if (s.arg1) ukmemcpy(crp, s.arg1, &ktime, sizeof(ktime));
- if (s.arg2) ukmemcpy(crp, s.arg2, &kzone, sizeof(kzone));
- crp->result = 0;
- break;
- }
- case SYS_getsockopt:
- errno = EOPNOTSUPP;
- crp->result = -1;
- break;
- case SYS_getrusage:
- {
- struct rusage kusage;
- memset(&kusage, 0, sizeof(kusage));
- crp->result = 0;
- kusage.ru_utime.tv_usec = (crp->ticks%60)*1000000L/60;
- kusage.ru_utime.tv_sec = crp->ticks/60;
- ukmemcpy(crp, s.arg2, &kusage, sizeof(kusage));
- break;
- }
- case SYS_writev:
- {
- int i;
- struct iovec *iov = xmalloc(s.arg3*sizeof(struct iovec));
- kumemcpy(crp, iov, s.arg2, s.arg3*sizeof(struct iovec));
- crp->result = 0;
- for (i = 0; i < s.arg3; i++)
- {
- char *kbuf = xmalloc(iov[i].iov_len);
- kumemcpy(crp, kbuf, (long)iov[i].iov_base, iov[i].iov_len);
- if ((crp->result==-1)||(s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1])
- {
- i = s.arg3;
- crp->result = -1;
- }
- else crp->result = write(crp->fd_tab[s.arg1], kbuf, iov[i].iov_len);
- free(kbuf);
- }
- free(iov);
- break;
- }
- case SYS_rename:
- {
- int bufsiz1 = ustrlen(crp, s.arg1)+1;
- char *kbuf1 = xmalloc(bufsiz1);
- int bufsiz2 = ustrlen(crp, s.arg2)+1;
- char *kbuf2 = xmalloc(bufsiz2);
- kustrcpy(crp, kbuf1, s.arg1);
- kustrcpy(crp, kbuf2, s.arg2);
- crp->result = rename(kbuf1, kbuf2);
- free(kbuf1);
- free(kbuf2);
- break;
- }
- case SYS_ftruncate:
- {
- if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
- else crp->result = ftruncate(crp->fd_tab[s.arg1], s.arg2);
- break;
- }
- case SYS_sendto:
- if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
- else
- {
- int kfd = crp->fd_tab[s.arg1];
- if (kfd < 0)
- {
- int tolen;
- struct sockaddr sa_to;
- char *buffer = xmalloc(s.arg3);
- kumemcpy(crp, buffer, s.arg2, s.arg3);
- kumemcpy(crp, &sa_to, s.arg5, sizeof(sa_to));
- crp->result = s_sendto (~kfd, buffer, s.arg3, s.arg4, &sa_to, &tolen);
- ukmemcpy(crp, s.arg5, &sa_to, sizeof(sa_to));
- ukmemcpy(crp, s.arg6, &tolen, sizeof(int));
- free(buffer);
- }
- }
- if ((crp->result==-1))
- {
- kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
- }
- break;
- case SYS_mkdir:
- {
- int bufsiz = ustrlen(crp, s.arg1)+1;
- char *kbuf = xmalloc(bufsiz);
- kustrcpy(crp, kbuf, s.arg1);
- crp->result = mkdir(kbuf, s.arg2);
- free(kbuf);
- break;
- }
- case SYS_rmdir:
- {
- int bufsiz = ustrlen(crp, s.arg1)+1;
- char *kbuf = xmalloc(bufsiz);
- kustrcpy(crp, kbuf, s.arg1);
- crp->result = rmdir(kbuf);
- free(kbuf);
- break;
- }
- case SYS_utimes:
- {
- struct timeval temps;
- int bufsiz = ustrlen(crp, s.arg1)+1;
- char *kbuf = xmalloc(bufsiz);
- kustrcpy(crp, kbuf, s.arg1);
- kumemcpy(crp, &temps, s.arg2, sizeof(temps));
- crp->result = utimes(kbuf, &temps);
- break;
- }
- case SYS_getrlimit:
- {
- struct rlimit klimit;
- crp->result = getrlimit(s.arg1, &klimit);
- ukmemcpy(crp, s.arg2, &klimit, sizeof(struct rlimit));
- break;
- }
- case SYS_setrlimit:
- {
- struct rlimit klimit;
- kumemcpy(crp, &klimit, s.arg2, sizeof(struct rlimit));
- crp->result = setrlimit(s.arg1, &klimit);
- break;
- }
- case SYS_getdirentries:
- {
- long actualsize;
- char *kbuf = xmalloc(s.arg3);
- if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
- else crp->result = getdirentries(crp->fd_tab[s.arg1], kbuf, s.arg3, &actualsize);
- ukmemcpy(crp, s.arg2, kbuf, s.arg3);
- ukmemcpy(crp, s.arg4, &actualsize, sizeof(long));
- break;
- }
- }
- if (debug && (crp->result==-1))
- {
- kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
- }
- /* save crp->result of system call */
- if (crp->state == 'R')
- {
- enum {carry=1};
- if (crp->result==-1)
- {
- crp->registers.save[0] = errno;
- crp->registers.flags |= carry;
- }
- else
- {
- crp->registers.save[0] = crp->result;
- crp->registers.flags &= ~carry;
- }
- // crp->registers.save[1] = 0; /* is this correct ? */
- }
- }
-
-