xref: /minix/minix/kernel/system/do_diagctl.c (revision 7f5f010b)
1 /* The kernel call implemented in this file:
2  *   m_type:	SYS_DIAGCTL
3  *
4  * The parameters for this kernel call are:
5  * 	m_lsys_krn_sys_diagctl.code	request
6  * and then request-specific arguments in
7  *	m_lsys_krn_sys_diagctl.buf
8  *	m_lsys_krn_sys_diagctl.len
9  *	m_lsys_krn_sys_diagctl.endpt
10  */
11 
12 #include "kernel/system.h"
13 
14 
15 /*===========================================================================*
16  *			        do_diagctl				     *
17  *===========================================================================*/
18 int do_diagctl(struct proc * caller, message * m_ptr)
19 {
20   vir_bytes len, buf;
21   static char mybuf[DIAG_BUFSIZE];
22   int s, i, proc_nr;
23 
24   switch (m_ptr->m_lsys_krn_sys_diagctl.code) {
25     case DIAGCTL_CODE_DIAG:
26         buf = m_ptr->m_lsys_krn_sys_diagctl.buf;
27         len = m_ptr->m_lsys_krn_sys_diagctl.len;
28 	if(len < 1 || len > DIAG_BUFSIZE) {
29 		printf("do_diagctl: diag for %d: len %d out of range\n",
30 			caller->p_endpoint, len);
31 		return EINVAL;
32 	}
33 	if((s=data_copy_vmcheck(caller, caller->p_endpoint, buf, KERNEL,
34 					(vir_bytes) mybuf, len)) != OK) {
35 		printf("do_diagctl: diag for %d: len %d: copy failed: %d\n",
36 			caller->p_endpoint, len, s);
37 		return s;
38 	}
39 	for(i = 0; i < len; i++)
40 		kputc(mybuf[i]);
41 	kputc(END_OF_KMESS);
42 	return OK;
43     case DIAGCTL_CODE_STACKTRACE:
44 	if(!isokendpt(m_ptr->m_lsys_krn_sys_diagctl.endpt, &proc_nr))
45 		return EINVAL;
46 	proc_stacktrace(proc_addr(proc_nr));
47 	return OK;
48     case DIAGCTL_CODE_REGISTER:
49 	if (!(priv(caller)->s_flags & SYS_PROC))
50 		return EPERM;
51 	priv(caller)->s_diag_sig = TRUE;
52 	/* If the message log is not empty, send a first notification
53 	 * immediately. After bootup the log is basically never empty.
54 	 */
55 	if (kmess.km_size > 0 && !kinfo.do_serial_debug)
56 		send_sig(caller->p_endpoint, SIGKMESS);
57 	return OK;
58     case DIAGCTL_CODE_UNREGISTER:
59 	if (!(priv(caller)->s_flags & SYS_PROC))
60 		return EPERM;
61 	priv(caller)->s_diag_sig = FALSE;
62 	return OK;
63     default:
64 	printf("do_diagctl: invalid request %d\n", m_ptr->m_lsys_krn_sys_diagctl.code);
65         return(EINVAL);
66   }
67 }
68 
69