📄 system.c
字号:
14961
14962 register struct proc *rp;
14963 phys_bytes dst_phys;
14964 int caller; /* where the map has to be stored */
14965 int k; /* process whose map is to be loaded */
14966 struct mem_map *map_ptr; /* virtual address of map inside caller (MM) */
14967
14968 /* Extract message parameters and copy new memory map to MM. */
14969 caller = m_ptr->m_source;
14970 k = m_ptr->PROC1;
14971 map_ptr = (struct mem_map *) m_ptr->MEM_PTR;
14972
14973 if (!isokprocn(k))
14974 panic("do_getmap got bad proc: ", m_ptr->PROC1);
14975
14976 rp = proc_addr(k); /* ptr to entry of the map */
14977
14978 /* Copy the map to MM. */
14979 dst_phys = umap(proc_addr(caller), D, (vir_bytes) map_ptr, sizeof(rp->p_map));
14980 if (dst_phys == 0) panic("bad call to sys_getmap", NO_NUM);
14981 phys_copy(vir2phys(rp->p_map), dst_phys, sizeof(rp->p_map));
14982
14983 return(OK);
14984 }
14987 /*===========================================================================*
14988 * do_exec *
14989 *===========================================================================*/
14990 PRIVATE int do_exec(m_ptr)
14991 register message *m_ptr; /* pointer to request message */
14992 {
14993 /* Handle sys_exec(). A process has done a successful EXEC. Patch it up. */
14994
14995 register struct proc *rp;
14996 reg_t sp; /* new sp */
14997 phys_bytes phys_name;
14998 char *np;
14999 #define NLEN (sizeof(rp->p_name)-1)
15000
15001 if (!isoksusern(m_ptr->PROC1)) return E_BAD_PROC;
15002 /* PROC2 field is used as flag to indicate process is being traced */
15003 if (m_ptr->PROC2) cause_sig(m_ptr->PROC1, SIGTRAP);
15004 sp = (reg_t) m_ptr->STACK_PTR;
15005 rp = proc_addr(m_ptr->PROC1);
15006 rp->p_reg.sp = sp; /* set the stack pointer */
15007 rp->p_reg.pc = (reg_t) m_ptr->IP_PTR; /* set pc */
15008 rp->p_alarm = 0; /* reset alarm timer */
15009 rp->p_flags &= ~RECEIVING; /* MM does not reply to EXEC call */
15010 if (rp->p_flags == 0) lock_ready(rp);
15011
15012 /* Save command name for debugging, ps(1) output, etc. */
15013 phys_name = numap(m_ptr->m_source, (vir_bytes) m_ptr->NAME_PTR,
15014 (vir_bytes) NLEN);
15015 if (phys_name != 0) {
15016 phys_copy(phys_name, vir2phys(rp->p_name), (phys_bytes) NLEN);
15017 for (np = rp->p_name; (*np & BYTE) >= ' '; np++) {}
15018 *np = 0;
15019 }
15020 return(OK);
15021 }
15024 /*===========================================================================*
15025 * do_xit *
15026 *===========================================================================*/
15027 PRIVATE int do_xit(m_ptr)
15028 message *m_ptr; /* pointer to request message */
15029 {
15030 /* Handle sys_xit(). A process has exited. */
15031
15032 register struct proc *rp, *rc;
15033 struct proc *np, *xp;
15034 int parent; /* number of exiting proc's parent */
15035 int proc_nr; /* number of process doing the exit */
15036 phys_clicks base, size;
15037
15038 parent = m_ptr->PROC1; /* slot number of parent process */
15039 proc_nr = m_ptr->PROC2; /* slot number of exiting process */
15040 if (!isoksusern(parent) || !isoksusern(proc_nr)) return(E_BAD_PROC);
15041 rp = proc_addr(parent);
15042 rc = proc_addr(proc_nr);
15043 lock();
15044 rp->child_utime += rc->user_time + rc->child_utime; /* accum child times */
15045 rp->child_stime += rc->sys_time + rc->child_stime;
15046 unlock();
15047 rc->p_alarm = 0; /* turn off alarm timer */
15048 if (rc->p_flags == 0) lock_unready(rc);
15049
15050 strcpy(rc->p_name, "<noname>"); /* process no longer has a name */
15051
15052 /* If the process being terminated happens to be queued trying to send a
15053 * message (i.e., the process was killed by a signal, rather than it doing an
15054 * EXIT), then it must be removed from the message queues.
15055 */
15056 if (rc->p_flags & SENDING) {
15057 /* Check all proc slots to see if the exiting process is queued. */
15058 for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) {
15059 if (rp->p_callerq == NIL_PROC) continue;
15060 if (rp->p_callerq == rc) {
15061 /* Exiting process is on front of this queue. */
15062 rp->p_callerq = rc->p_sendlink;
15063 break;
15064 } else {
15065 /* See if exiting process is in middle of queue. */
15066 np = rp->p_callerq;
15067 while ( ( xp = np->p_sendlink) != NIL_PROC)
15068 if (xp == rc) {
15069 np->p_sendlink = xp->p_sendlink;
15070 break;
15071 } else {
15072 np = xp;
15073 }
15074 }
15075 }
15076 }
15077
15078 if (rc->p_flags & PENDING) --sig_procs;
15079 sigemptyset(&rc->p_pending);
15080 rc->p_pendcount = 0;
15081 rc->p_flags = P_SLOT_FREE;
15082 return(OK);
15083 }
15086 /*===========================================================================*
15087 * do_getsp *
15088 *===========================================================================*/
15089 PRIVATE int do_getsp(m_ptr)
15090 register message *m_ptr; /* pointer to request message */
15091 {
15092 /* Handle sys_getsp(). MM wants to know what sp is. */
15093
15094 register struct proc *rp;
15095
15096 if (!isoksusern(m_ptr->PROC1)) return(E_BAD_PROC);
15097 rp = proc_addr(m_ptr->PROC1);
15098 m_ptr->STACK_PTR = (char *) rp->p_reg.sp; /* return sp here (bad type) */
15099 return(OK);
15100 }
15103 /*===========================================================================*
15104 * do_times *
15105 *===========================================================================*/
15106 PRIVATE int do_times(m_ptr)
15107 register message *m_ptr; /* pointer to request message */
15108 {
15109 /* Handle sys_times(). Retrieve the accounting information. */
15110
15111 register struct proc *rp;
15112
15113 if (!isoksusern(m_ptr->PROC1)) return E_BAD_PROC;
15114 rp = proc_addr(m_ptr->PROC1);
15115
15116 /* Insert the times needed by the TIMES system call in the message. */
15117 lock(); /* halt the volatile time counters in rp */
15118 m_ptr->USER_TIME = rp->user_time;
15119 m_ptr->SYSTEM_TIME = rp->sys_time;
15120 unlock();
15121 m_ptr->CHILD_UTIME = rp->child_utime;
15122 m_ptr->CHILD_STIME = rp->child_stime;
15123 m_ptr->BOOT_TICKS = get_uptime();
15124 return(OK);
15125 }
15128 /*===========================================================================*
15129 * do_abort *
15130 *===========================================================================*/
15131 PRIVATE int do_abort(m_ptr)
15132 message *m_ptr; /* pointer to request message */
15133 {
15134 /* Handle sys_abort. MINIX is unable to continue. Terminate operation. */
15135 char monitor_code[64];
15136 phys_bytes src_phys;
15137
15138 if (m_ptr->m1_i1 == RBT_MONITOR) {
15139 /* The monitor is to run user specified instructions. */
15140 src_phys = numap(m_ptr->m_source, (vir_bytes) m_ptr->m1_p1,
15141 (vir_bytes) sizeof(monitor_code));
15142 if (src_phys == 0) panic("bad monitor code from", m_ptr->m_source);
15143 phys_copy(src_phys, vir2phys(monitor_code),
15144 (phys_bytes) sizeof(monitor_code));
15145 reboot_code = vir2phys(monitor_code);
15146 }
15147 wreboot(m_ptr->m1_i1);
15148 return(OK); /* pro-forma (really EDISASTER) */
15149 }
15154 /*===========================================================================*
15155 * do_sendsig *
15156 *===========================================================================*/
15157 PRIVATE int do_sendsig(m_ptr)
15158 message *m_ptr; /* pointer to request message */
15159 {
15160 /* Handle sys_sendsig, POSIX-style signal */
15161
15162 struct sigmsg smsg;
15163 register struct proc *rp;
15164 phys_bytes src_phys, dst_phys;
15165 struct sigcontext sc, *scp;
15166 struct sigframe fr, *frp;
15167
15168 if (!isokusern(m_ptr->PROC1)) return(E_BAD_PROC);
15169 rp = proc_addr(m_ptr->PROC1);
15170
15171 /* Get the sigmsg structure into our address space. */
15172 src_phys = umap(proc_addr(MM_PROC_NR), D, (vir_bytes) m_ptr->SIG_CTXT_PTR,
15173 (vir_bytes) sizeof(struct sigmsg));
15174 if (src_phys == 0)
15175 panic("do_sendsig can't signal: bad sigmsg address from MM", NO_NUM);
15176 phys_copy(src_phys, vir2phys(&smsg), (phys_bytes) sizeof(struct sigmsg));
15177
15178 /* Compute the usr stack pointer value where sigcontext will be stored. */
15179 scp = (struct sigcontext *) smsg.sm_stkptr - 1;
15180
15181 /* Copy the registers to the sigcontext structure. */
15182 memcpy(&sc.sc_regs, &rp->p_reg, sizeof(struct sigregs));
15183
15184 /* Finish the sigcontext initialization. */
15185 sc.sc_flags = SC_SIGCONTEXT;
15186
15187 sc.sc_mask = smsg.sm_mask;
15188
15189 /* Copy the sigcontext structure to the user's stack. */
15190 dst_phys = umap(rp, D, (vir_bytes) scp,
15191 (vir_bytes) sizeof(struct sigcontext));
15192 if (dst_phys == 0) return(EFAULT);
15193 phys_copy(vir2phys(&sc), dst_phys, (phys_bytes) sizeof(struct sigcontext));
15194
15195 /* Initialize the sigframe structure. */
15196 frp = (struct sigframe *) scp - 1;
15197 fr.sf_scpcopy = scp;
15198 fr.sf_retadr2= (void (*)()) rp->p_reg.pc;
15199 fr.sf_fp = rp->p_reg.fp;
15200 rp->p_reg.fp = (reg_t) &frp->sf_fp;
15201 fr.sf_scp = scp;
15202 fr.sf_code = 0; /* XXX - should be used for type of FP exception */
15203 fr.sf_signo = smsg.sm_signo;
15204 fr.sf_retadr = (void (*)()) smsg.sm_sigreturn;
15205
15206 /* Copy the sigframe structure to the user's stack. */
15207 dst_phys = umap(rp, D, (vir_bytes) frp, (vir_bytes) sizeof(struct sigframe));
15208 if (dst_phys == 0) return(EFAULT);
15209 phys_copy(vir2phys(&fr), dst_phys, (phys_bytes) sizeof(struct sigframe));
15210
15211 /* Reset user registers to execute the signal handler. */
15212 rp->p_reg.sp = (reg_t) frp;
15213 rp->p_reg.pc = (reg_t) smsg.sm_sighandler;
15214
15215 return(OK);
15216 }
15218 /*===========================================================================*
15219 * do_sigreturn *
15220 *===========================================================================*/
15221 PRIVATE int do_sigreturn(m_ptr)
15222 register message *m_ptr;
15223 {
15224 /* POSIX style signals require sys_sigreturn to put things in order before the
15225 * signalled process can resume execution
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -