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