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