63 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			63 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* The kernel call implemented in this file:
 | |
|  *   m_type:	SYS_SYSCTL
 | |
|  *
 | |
|  * The parameters for this kernel call are:
 | |
|  *  	SYSCTL_CODE	request
 | |
|  * and then request-specific arguments in SYSCTL_ARG1 and SYSCTL_ARG2.
 | |
|  */
 | |
| 
 | |
| #include "../system.h"
 | |
| #include "../vm.h"
 | |
| 
 | |
| 
 | |
| /*===========================================================================*
 | |
|  *			        do_sysctl				     *
 | |
|  *===========================================================================*/
 | |
| PUBLIC int do_sysctl(m_ptr)
 | |
| register message *m_ptr;	/* pointer to request message */
 | |
| {
 | |
|   phys_bytes ph;
 | |
|   vir_bytes len, buf;
 | |
|   static char mybuf[DIAG_BUFSIZE];
 | |
|   struct proc *caller, *target;
 | |
|   int s, i, proc_nr;
 | |
| 
 | |
|   caller = proc_addr(who_p);
 | |
| 
 | |
|   switch (m_ptr->SYSCTL_CODE) {
 | |
|     case SYSCTL_CODE_DIAG:
 | |
|         buf = (vir_bytes) m_ptr->SYSCTL_ARG1;
 | |
|         len = (vir_bytes) m_ptr->SYSCTL_ARG2;
 | |
| 	if(len < 1 || len > DIAG_BUFSIZE) {
 | |
| 		kprintf("do_sysctl: diag for %d: len %d out of range\n",
 | |
| 			caller->p_endpoint, len);
 | |
| 		return EINVAL;
 | |
| 	}
 | |
| 	if((ph=umap_local(caller, D, buf, len)) == 0)
 | |
| 		return EFAULT;
 | |
| 	CHECKRANGE_OR_SUSPEND(caller, ph, len, 1);
 | |
| 	if((s=data_copy(who_e, buf, SYSTEM, (vir_bytes) mybuf, len)) != OK) {
 | |
| 		kprintf("do_sysctl: diag for %d: len %d: copy failed: %d\n",
 | |
| 			caller->p_endpoint, len, s);
 | |
| 		return s;
 | |
| 	}
 | |
| 	for(i = 0; i < len; i++)
 | |
| 		kputc(mybuf[i]);
 | |
| 	kputc(END_OF_KMESS);
 | |
| 	return OK;
 | |
|     case SYSCTL_CODE_STACKTRACE:
 | |
| 	if(!isokendpt(m_ptr->SYSCTL_ARG2, &proc_nr))
 | |
| 		return EINVAL;
 | |
| 	proc_stacktrace(proc_addr(proc_nr));
 | |
| 	return OK;
 | |
|     default:
 | |
| 	kprintf("do_sysctl: invalid request %d\n", m_ptr->SYSCTL_CODE);
 | |
|         return(EINVAL);
 | |
|   }
 | |
| 
 | |
|   minix_panic("do_sysctl: can't happen", NO_NUM);
 | |
| 
 | |
|   return(OK);
 | |
| }
 | |
| 
 | 
