etc/services - sync with NetBSD-8
[minix.git] / minix / lib / libc / sys / __sysctl.c
blobfd02bfa66a6e58169222f305997eaa7c21ad51ec
1 #include <sys/cdefs.h>
2 #include <lib.h>
3 #include "namespace.h"
4 #include "extern.h"
5 #include <string.h>
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)
14 message m;
15 int r;
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);
27 r = _syscall(MIB_PROC_NR, MIB_SYSCTL, &m);
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.
36 if (oldlenp != NULL)
37 *oldlenp = m.m_mib_lc_sysctl.oldlen;
39 return r;