69 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			69 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* The kernel call implemented in this file:
 | 
						|
 *   m_type:	SYS_DIAGCTL
 | 
						|
 *
 | 
						|
 * The parameters for this kernel call are:
 | 
						|
 * 	m_lsys_krn_sys_diagctl.code	request
 | 
						|
 * and then request-specific arguments in
 | 
						|
 *	m_lsys_krn_sys_diagctl.buf
 | 
						|
 *	m_lsys_krn_sys_diagctl.len
 | 
						|
 *	m_lsys_krn_sys_diagctl.endpt
 | 
						|
 */
 | 
						|
 | 
						|
#include "kernel/system.h"
 | 
						|
 | 
						|
 | 
						|
/*===========================================================================*
 | 
						|
 *			        do_diagctl				     *
 | 
						|
 *===========================================================================*/
 | 
						|
int do_diagctl(struct proc * caller, message * m_ptr)
 | 
						|
{
 | 
						|
  vir_bytes len, buf;
 | 
						|
  static char mybuf[DIAG_BUFSIZE];
 | 
						|
  int s, i, proc_nr;
 | 
						|
 | 
						|
  switch (m_ptr->m_lsys_krn_sys_diagctl.code) {
 | 
						|
    case DIAGCTL_CODE_DIAG:
 | 
						|
        buf = m_ptr->m_lsys_krn_sys_diagctl.buf;
 | 
						|
        len = m_ptr->m_lsys_krn_sys_diagctl.len;
 | 
						|
	if(len < 1 || len > DIAG_BUFSIZE) {
 | 
						|
		printf("do_diagctl: diag for %d: len %d out of range\n",
 | 
						|
			caller->p_endpoint, len);
 | 
						|
		return EINVAL;
 | 
						|
	}
 | 
						|
	if((s=data_copy_vmcheck(caller, caller->p_endpoint, buf, KERNEL,
 | 
						|
					(vir_bytes) mybuf, len)) != OK) {
 | 
						|
		printf("do_diagctl: 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 DIAGCTL_CODE_STACKTRACE:
 | 
						|
	if(!isokendpt(m_ptr->m_lsys_krn_sys_diagctl.endpt, &proc_nr))
 | 
						|
		return EINVAL;
 | 
						|
	proc_stacktrace(proc_addr(proc_nr));
 | 
						|
	return OK;
 | 
						|
    case DIAGCTL_CODE_REGISTER:
 | 
						|
	if (!(priv(caller)->s_flags & SYS_PROC))
 | 
						|
		return EPERM;
 | 
						|
	priv(caller)->s_diag_sig = TRUE;
 | 
						|
	/* If the message log is not empty, send a first notification
 | 
						|
	 * immediately. After bootup the log is basically never empty.
 | 
						|
	 */
 | 
						|
	if (kmess.km_size > 0 && !kinfo.do_serial_debug)
 | 
						|
		send_sig(caller->p_endpoint, SIGKMESS);
 | 
						|
	return OK;
 | 
						|
    case DIAGCTL_CODE_UNREGISTER:
 | 
						|
	if (!(priv(caller)->s_flags & SYS_PROC))
 | 
						|
		return EPERM;
 | 
						|
	priv(caller)->s_diag_sig = FALSE;
 | 
						|
	return OK;
 | 
						|
    default:
 | 
						|
	printf("do_diagctl: invalid request %d\n", m_ptr->m_lsys_krn_sys_diagctl.code);
 | 
						|
        return(EINVAL);
 | 
						|
  }
 | 
						|
}
 | 
						|
 |