xref: /minix3/minix/lib/libc/sys/__sysctl.c (revision e4e21ee1b2710f3d411514741ce10d80156f4b5d)
1*e4e21ee1SDavid van Moolenbroek #include <sys/cdefs.h>
2*e4e21ee1SDavid van Moolenbroek #include <lib.h>
3*e4e21ee1SDavid van Moolenbroek #include "namespace.h"
4*e4e21ee1SDavid van Moolenbroek #include "extern.h"
5*e4e21ee1SDavid van Moolenbroek #include <string.h>
6*e4e21ee1SDavid van Moolenbroek 
7*e4e21ee1SDavid van Moolenbroek /*
8*e4e21ee1SDavid van Moolenbroek  * The sysctl(2) system call, handled by the MIB service.
9*e4e21ee1SDavid van Moolenbroek  */
10*e4e21ee1SDavid van Moolenbroek int
__sysctl(const int * name,unsigned int namelen,void * oldp,size_t * oldlenp,const void * newp,size_t newlen)11*e4e21ee1SDavid van Moolenbroek __sysctl(const int * name, unsigned int namelen, void * oldp, size_t * oldlenp,
12*e4e21ee1SDavid van Moolenbroek 	const void * newp, size_t newlen)
13*e4e21ee1SDavid van Moolenbroek {
14*e4e21ee1SDavid van Moolenbroek 	message m;
15*e4e21ee1SDavid van Moolenbroek 	int r;
16*e4e21ee1SDavid van Moolenbroek 
17*e4e21ee1SDavid van Moolenbroek 	memset(&m, 0, sizeof(m));
18*e4e21ee1SDavid van Moolenbroek 	m.m_lc_mib_sysctl.oldp = (vir_bytes)oldp;
19*e4e21ee1SDavid van Moolenbroek 	m.m_lc_mib_sysctl.oldlen = (oldlenp != NULL) ? *oldlenp : 0;
20*e4e21ee1SDavid van Moolenbroek 	m.m_lc_mib_sysctl.newp = (vir_bytes)newp;
21*e4e21ee1SDavid van Moolenbroek 	m.m_lc_mib_sysctl.newlen = newlen;
22*e4e21ee1SDavid van Moolenbroek 	m.m_lc_mib_sysctl.namelen = namelen;
23*e4e21ee1SDavid van Moolenbroek 	m.m_lc_mib_sysctl.namep = (vir_bytes)name;
24*e4e21ee1SDavid van Moolenbroek 	if (namelen <= CTL_SHORTNAME)
25*e4e21ee1SDavid van Moolenbroek 		memcpy(m.m_lc_mib_sysctl.name, name, sizeof(*name) * namelen);
26*e4e21ee1SDavid van Moolenbroek 
27*e4e21ee1SDavid van Moolenbroek 	r = _syscall(MIB_PROC_NR, MIB_SYSCTL, &m);
28*e4e21ee1SDavid van Moolenbroek 
29*e4e21ee1SDavid van Moolenbroek 	/*
30*e4e21ee1SDavid van Moolenbroek 	 * We copy the NetBSD behavior of replying with the old length also if
31*e4e21ee1SDavid van Moolenbroek 	 * the call failed, typically with ENOMEM.  This is undocumented
32*e4e21ee1SDavid van Moolenbroek 	 * behavior, but unfortunately relied on by sysctl(8) and other NetBSD
33*e4e21ee1SDavid van Moolenbroek 	 * userland code.  If the call failed at the IPC level, the resulting
34*e4e21ee1SDavid van Moolenbroek 	 * value will be garbage, but it should then not be used anyway.
35*e4e21ee1SDavid van Moolenbroek 	 */
36*e4e21ee1SDavid van Moolenbroek 	if (oldlenp != NULL)
37*e4e21ee1SDavid van Moolenbroek 		*oldlenp = m.m_mib_lc_sysctl.oldlen;
38*e4e21ee1SDavid van Moolenbroek 
39*e4e21ee1SDavid van Moolenbroek 	return r;
40*e4e21ee1SDavid van Moolenbroek }
41