int sysctl(const int *name, unsigned int namelen, void *oldp, size_t *oldlenp, const void *newp, size_t newlen) { size_t oldlen, savelen; int error; if (name[0] != CTL_USER) return (__sysctl(name, namelen, oldp, oldlenp, newp, newlen)); oldlen = (oldlenp == NULL) ? 0 : *oldlenp; savelen = oldlen; error = user_sysctl(name + 1, namelen - 1, oldp, &oldlen, newp, newlen); if (error != 0) { errno = error; return (-1); } if (oldlenp != NULL) { *oldlenp = oldlen; if (oldp != NULL && oldlen > savelen) { errno = ENOMEM; return (-1); } } return (0); }
void __guard_setup (void) { size_t size; #ifdef HAVE_DEV_ERANDOM int mib[3]; #endif if (__guard != 0UL) return; #ifndef __SSP_QUICK_CANARY__ #ifdef HAVE_DEV_ERANDOM /* Random is another depth in Linux, hence an array of 3. */ mib[0] = CTL_KERN; mib[1] = KERN_RANDOM; mib[2] = RANDOM_ERANDOM; size = sizeof (unsigned long); if (__sysctl (mib, 3, &__guard, &size, NULL, 0) != (-1)) if (__guard != 0UL) return; #endif /* * Attempt to open kernel pseudo random device if one exists before * opening urandom to avoid system entropy depletion. */ { int fd; #ifdef HAVE_DEV_ERANDOM if ((fd = open ("/dev/erandom", O_RDONLY)) == (-1)) #endif fd = open ("/dev/urandom", O_RDONLY); if (fd != (-1)) { size = read (fd, (char *) &__guard, sizeof (__guard)); close (fd); if (size == sizeof (__guard)) return; } } #endif /* If sysctl was unsuccessful, use the "terminator canary". */ __guard = 0xFF0A0D00UL; { /* Everything failed? Or we are using a weakened model of the * terminator canary */ struct timeval tv; gettimeofday (&tv, NULL); __guard ^= tv.tv_usec ^ tv.tv_sec; } }
int setdomainname (const char *name, size_t len) { /* Set the "kern.domainname" sysctl value. */ int request[2] = { CTL_KERN, KERN_NISDOMAINNAME }; if (__sysctl (request, 2, NULL, NULL, (void *) name, len) < 0) return -1; return 0; }
/* * This function uses a presently undocumented interface to the kernel * to walk the tree and get the type so it can print the value. * This interface is under work and consideration, and should probably * be killed with a big axe by the first person who can find the time. * (be aware though, that the proper interface isn't as obvious as it * may seem, there are various conflicting requirements. */ int sysctlnametomib(const char *name, int *mibp, size_t *sizep) { int oid[2]; int error; oid[0] = 0; oid[1] = 3; *sizep *= sizeof (int); error = __sysctl(oid, 2, mibp, sizep, (void *)name, strlen(name)); *sizep /= sizeof (int); return (error); }
int __sysctlnametomib (const char *name, int *mibp, size_t *sizep) { /* Convert the string NAME to a binary encoded request. The kernel contains a routine for doing this, called "name2oid". But the way to call it is a little bit strange. */ int name2oid_request[2] = { 0, 3 }; int retval; *sizep *= sizeof (int); retval = __sysctl (name2oid_request, 2, mibp, sizep, (void *) name, strlen (name)); *sizep /= sizeof (int); return retval; }
int __profile_frequency (void) { /* Fetch the "kern.clockrate" sysctl value. */ int request[2] = { CTL_KERN, KERN_CLOCKRATE }; struct clockinfo result; size_t result_len = sizeof (result); if (__sysctl (request, 2, &result, &result_len, NULL, 0) < 0) /* Dummy result. */ return 1; /* Yes, hz, not profhz. On i386, the value is 100, not 1024. */ return result.hz; }
int __kernel_getosreldate(void) { static int osreldate; int mib[2]; size_t size; if (osreldate == 0) { mib[0] = CTL_KERN; mib[1] = KERN_OSRELDATE; size = sizeof osreldate; if (__sysctl(mib, 2, &osreldate, &size, NULL, 0) == -1) return (-1); } return (osreldate); }
static int _mapped_addr_enabled(void) { /* implementation dependent check */ #if defined(__KAME__) && defined(IPV6CTL_MAPPED_ADDR) int mib[4]; size_t len; int val; mib[0] = CTL_NET; mib[1] = PF_INET6; mib[2] = IPPROTO_IPV6; mib[3] = IPV6CTL_MAPPED_ADDR; len = sizeof(val); if (__sysctl(mib, 4, &val, &len, 0, 0) == 0 && val != 0) return 1; #endif /* __KAME__ && IPV6CTL_MAPPED_ADDR */ return 0; }
static size_t arc4_sysctl(u_char *buf, size_t size) { int mib[2]; size_t len, done; mib[0] = CTL_KERN; mib[1] = KERN_ARND; done = 0; do { len = size; if (__sysctl(mib, 2, buf, &len, NULL, 0) == -1) return (done); done += len; buf += len; size -= len; } while (size > 0); return (done); }
/* Put the 1 minute, 5 minute and 15 minute load averages into the first NELEM elements of LOADAVG. Return the number written (never more than three, but may be less than NELEM), or -1 if an error occurred. */ int getloadavg (double loadavg[], int nelem) { if (nelem > 3) nelem = 3; if (nelem > 0) { /* Fetch the "vm.loadavg" sysctl value. */ int request[2] = { CTL_VM, VM_LOADAVG }; struct loadavg result; size_t result_len = sizeof (result); int i; if (__sysctl (request, 2, &result, &result_len, NULL, 0) < 0) return -1; for (i = 0; i < nelem; i++) loadavg[i] = (double) result.ldavg[i] / (double) result.fscale; } return nelem; }
static void __guard_setup(void) { int mib[2]; size_t len; if (__guard[0] != 0) return; mib[0] = CTL_KERN; mib[1] = KERN_ARND; len = sizeof(__guard); if (__sysctl(mib, 2, __guard, &len, NULL, 0) == -1 || len != sizeof(__guard)) { /* If sysctl was unsuccessful, use the "terminator canary". */ ((unsigned char *)__guard)[0] = 0; ((unsigned char *)__guard)[1] = 0; ((unsigned char *)__guard)[2] = '\n'; ((unsigned char *)__guard)[3] = 255; } }
int getdomainname (char *name, size_t len) { /* Fetch the "kern.domainname" sysctl value. */ int request[2] = { CTL_KERN, KERN_NISDOMAINNAME }; size_t result_len = len; if (__sysctl (request, 2, name, &result_len, NULL, 0) < 0) { if (errno == ENOMEM) __set_errno (ENAMETOOLONG); return -1; } if (result_len >= len) { __set_errno (ENAMETOOLONG); return -1; } name[result_len] = '\0'; return 0; }
__guard_setup(void) { #if !defined(__minix) static const int mib[2] = { CTL_KERN, KERN_ARND }; size_t len; #endif /* !defined(__minix) */ if (__stack_chk_guard[0] != 0) return; #if !defined(__minix) len = sizeof(__stack_chk_guard); if (__sysctl(mib, (u_int)__arraycount(mib), __stack_chk_guard, &len, NULL, 0) == -1 || len != sizeof(__stack_chk_guard)) { #endif /* !defined(__minix) */ /* If sysctl was unsuccessful, use the "terminator canary". */ ((unsigned char *)(void *)__stack_chk_guard)[0] = 0; ((unsigned char *)(void *)__stack_chk_guard)[1] = 0; ((unsigned char *)(void *)__stack_chk_guard)[2] = '\n'; ((unsigned char *)(void *)__stack_chk_guard)[3] = 255; #if !defined(__minix) } #endif /* !defined(__minix) */ }
/*LINTED used*/ static void __guard_setup(void) { static const int mib[2] = { CTL_KERN, KERN_ARND }; volatile long tmp_stack_chk_guard[nitems(__stack_chk_guard)]; size_t len; int error, idx; if (__stack_chk_guard[0] != 0) return; /* * Avoid using functions which might have stack protection * enabled, to update the __stack_chk_guard. First fetch the * data into a temporal array, then do manual volatile copy to * not allow optimizer to call memcpy() behind us. */ error = _elf_aux_info(AT_CANARY, (void *)tmp_stack_chk_guard, sizeof(tmp_stack_chk_guard)); if (error == 0 && tmp_stack_chk_guard[0] != 0) { for (idx = 0; idx < nitems(__stack_chk_guard); idx++) { __stack_chk_guard[idx] = tmp_stack_chk_guard[idx]; tmp_stack_chk_guard[idx] = 0; } return; } len = sizeof(__stack_chk_guard); if (__sysctl(mib, nitems(mib), __stack_chk_guard, &len, NULL, 0) == -1 || len != sizeof(__stack_chk_guard)) { /* If sysctl was unsuccessful, use the "terminator canary". */ ((unsigned char *)(void *)__stack_chk_guard)[0] = 0; ((unsigned char *)(void *)__stack_chk_guard)[1] = 0; ((unsigned char *)(void *)__stack_chk_guard)[2] = '\n'; ((unsigned char *)(void *)__stack_chk_guard)[3] = 255; } }
/* Test whether the machine has more than one processor. This is not the best test but good enough. More complicated tests would require `malloc' which is not available at that time. */ static int is_smp_system (void) { static const int sysctl_args[] = { CTL_KERN, KERN_VERSION }; char buf[512]; size_t reslen = sizeof (buf); /* Try reading the number using `sysctl' first. */ if (__sysctl ((int *) sysctl_args, sizeof (sysctl_args) / sizeof (sysctl_args[0]), buf, &reslen, NULL, 0) < 0) { /* This was not successful. Now try reading the /proc filesystem. */ int fd = __open ("/proc/sys/kernel/version", O_RDONLY); if (__builtin_expect (fd, 0) == -1 || (reslen = __read (fd, buf, sizeof (buf))) <= 0) /* This also didn't work. We give up and say it's a UP machine. */ buf[0] = '\0'; __close (fd); } return strstr (buf, "SMP") != NULL; }
int getifaddrs(struct ifaddrs **pif) { int icnt = 1; int dcnt = 0; int ncnt = 0; #ifdef NET_RT_IFLIST int mib[6]; size_t needed; char *buf; char *next; struct ifaddrs *cif = 0; char *p, *p0; struct rt_msghdr *rtm; struct if_msghdr *ifm; struct ifa_msghdr *ifam; struct sockaddr_dl *dl; struct sockaddr *sa; struct ifaddrs *ifa, *ift; u_short idx = 0; #else /* NET_RT_IFLIST */ struct ifaddrs *ifa, *ift; char buf[1024]; int m, sock; struct ifconf ifc; struct ifreq *ifr; struct ifreq *lifr; #endif /* NET_RT_IFLIST */ int i; size_t len, alen; char *data; char *names; #ifdef NET_RT_IFLIST mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; /* protocol */ mib[3] = 0; /* wildcard address family */ mib[4] = NET_RT_IFLIST; mib[5] = 0; /* no flags */ if (__sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) return (-1); if ((buf = malloc(needed)) == NULL) return (-1); if (__sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { free(buf); return (-1); } for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)(void *)next; if (rtm->rtm_version != RTM_VERSION) continue; switch (rtm->rtm_type) { case RTM_IFINFO: ifm = (struct if_msghdr *)(void *)rtm; if (ifm->ifm_addrs & RTA_IFP) { idx = ifm->ifm_index; ++icnt; dl = (struct sockaddr_dl *)(void *)(ifm + 1); dcnt += SA_RLEN((struct sockaddr *)(void*)dl) + ALIGNBYTES; #ifdef HAVE_IFM_DATA dcnt += sizeof(ifm->ifm_data); #endif /* HAVE_IFM_DATA */ ncnt += dl->sdl_nlen + 1; } else idx = 0; break; case RTM_NEWADDR: ifam = (struct ifa_msghdr *)(void *)rtm; if (idx && ifam->ifam_index != idx) abort(); /* this cannot happen */ #define RTA_MASKS (RTA_NETMASK | RTA_IFA | RTA_BRD) if (idx == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0) break; p = (char *)(void *)(ifam + 1); ++icnt; #ifdef HAVE_IFAM_DATA dcnt += sizeof(ifam->ifam_data) + ALIGNBYTES; #endif /* HAVE_IFAM_DATA */ /* Scan to look for length of address */ alen = 0; for (p0 = p, i = 0; i < RTAX_MAX; i++) { if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) == 0) continue; sa = (struct sockaddr *)(void *)p; len = SA_RLEN(sa); if (i == RTAX_IFA) { alen = len; break; } p += len; } for (p = p0, i = 0; i < RTAX_MAX; i++) { if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) == 0) continue; sa = (struct sockaddr *)(void *)p; len = SA_RLEN(sa); if (i == RTAX_NETMASK && SA_LEN(sa) == 0) dcnt += alen; else dcnt += len; p += len; } break; } } #else /* NET_RT_IFLIST */ ifc.ifc_buf = buf; ifc.ifc_len = sizeof(buf); if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) return (-1); i = ioctl(sock, SIOCGIFCONF, (char *)&ifc); close(sock); if (i < 0) return (-1); ifr = ifc.ifc_req; lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len]; while (ifr < lifr) { struct sockaddr *sa; sa = &ifr->ifr_addr; ++icnt; dcnt += SA_RLEN(sa); ncnt += sizeof(ifr->ifr_name) + 1; if (SA_LEN(sa) < sizeof(*sa)) ifr = (struct ifreq *)(((char *)sa) + sizeof(*sa)); else ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa)); } #endif /* NET_RT_IFLIST */ if (icnt + dcnt + ncnt == 1) { *pif = NULL; free(buf); return (0); } data = malloc(sizeof(struct ifaddrs) * icnt + dcnt + ncnt); if (data == NULL) { free(buf); return(-1); } ifa = (struct ifaddrs *)(void *)data; data += sizeof(struct ifaddrs) * icnt; names = data + dcnt; memset(ifa, 0, sizeof(struct ifaddrs) * icnt); ift = ifa; #ifdef NET_RT_IFLIST idx = 0; for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)(void *)next; if (rtm->rtm_version != RTM_VERSION) continue; switch (rtm->rtm_type) { case RTM_IFINFO: ifm = (struct if_msghdr *)(void *)rtm; if (ifm->ifm_addrs & RTA_IFP) { idx = ifm->ifm_index; dl = (struct sockaddr_dl *)(void *)(ifm + 1); cif = ift; ift->ifa_name = names; ift->ifa_flags = (int)ifm->ifm_flags; memcpy(names, dl->sdl_data, (size_t)dl->sdl_nlen); names[dl->sdl_nlen] = 0; names += dl->sdl_nlen + 1; ift->ifa_addr = (struct sockaddr *)(void *)data; memcpy(data, dl, (size_t)SA_LEN((struct sockaddr *) (void *)dl)); data += SA_RLEN((struct sockaddr *)(void *)dl); #ifdef HAVE_IFM_DATA /* ifm_data needs to be aligned */ ift->ifa_data = data = (void *)ALIGN(data); memcpy(data, &ifm->ifm_data, sizeof(ifm->ifm_data)); data += sizeof(ifm->ifm_data); #else /* HAVE_IFM_DATA */ ift->ifa_data = NULL; #endif /* HAVE_IFM_DATA */ ift = (ift->ifa_next = ift + 1); } else idx = 0; break; case RTM_NEWADDR: ifam = (struct ifa_msghdr *)(void *)rtm; if (idx && ifam->ifam_index != idx) abort(); /* this cannot happen */ if (idx == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0) break; ift->ifa_name = cif->ifa_name; ift->ifa_flags = cif->ifa_flags; ift->ifa_data = NULL; p = (char *)(void *)(ifam + 1); /* Scan to look for length of address */ alen = 0; for (p0 = p, i = 0; i < RTAX_MAX; i++) { if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) == 0) continue; sa = (struct sockaddr *)(void *)p; len = SA_RLEN(sa); if (i == RTAX_IFA) { alen = len; break; } p += len; } for (p = p0, i = 0; i < RTAX_MAX; i++) { if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) == 0) continue; sa = (struct sockaddr *)(void *)p; len = SA_RLEN(sa); switch (i) { case RTAX_IFA: ift->ifa_addr = (struct sockaddr *)(void *)data; memcpy(data, p, len); data += len; break; case RTAX_NETMASK: ift->ifa_netmask = (struct sockaddr *)(void *)data; if (SA_LEN(sa) == 0) { memset(data, 0, alen); data += alen; break; } memcpy(data, p, len); data += len; break; case RTAX_BRD: ift->ifa_broadaddr = (struct sockaddr *)(void *)data; memcpy(data, p, len); data += len; break; } p += len; } #ifdef HAVE_IFAM_DATA /* ifam_data needs to be aligned */ ift->ifa_data = data = (void *)ALIGN(data); memcpy(data, &ifam->ifam_data, sizeof(ifam->ifam_data)); data += sizeof(ifam->ifam_data); #endif /* HAVE_IFAM_DATA */ ift = (ift->ifa_next = ift + 1); break; } } free(buf); #else /* NET_RT_IFLIST */ ifr = ifc.ifc_req; lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len]; while (ifr < lifr) { struct sockaddr *sa; ift->ifa_name = names; names[sizeof(ifr->ifr_name)] = 0; strncpy(names, ifr->ifr_name, sizeof(ifr->ifr_name)); while (*names++) ; ift->ifa_addr = (struct sockaddr *)data; sa = &ifr->ifr_addr; memcpy(data, sa, SA_LEN(sa)); data += SA_RLEN(sa); ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa)); ift = (ift->ifa_next = ift + 1); } #endif /* NET_RT_IFLIST */ if (--ift >= ifa) { ift->ifa_next = NULL; *pif = ifa; } else { *pif = NULL; free(ifa); } return (0); }
static int init_iosys (void) { char systype[256]; int i, n; static int iobase_name[] = { CTL_BUS, BUS_ISA, BUS_ISA_PORT_BASE }; static int ioshift_name[] = { CTL_BUS, BUS_ISA, BUS_ISA_PORT_SHIFT }; size_t len = sizeof(io.base); if (! __sysctl (iobase_name, 3, &io.io_base, &len, NULL, 0) && ! __sysctl (ioshift_name, 3, &io.shift, &len, NULL, 0)) { io.initdone = 1; return 0; } n = __readlink (PATH_ARM_SYSTYPE, systype, sizeof (systype) - 1); if (n > 0) { systype[n] = '\0'; if (isdigit (systype[0])) { if (sscanf (systype, "%li,%i", &io.io_base, &io.shift) == 2) { io.initdone = 1; return 0; } /* else we're likely going to fail with the system match below */ } } else { FILE * fp; fp = fopen (PATH_CPUINFO, "rce"); if (! fp) return -1; while ((n = fscanf (fp, "Hardware\t: %256[^\n]\n", systype)) != EOF) { if (n == 1) break; else fgets_unlocked (systype, 256, fp); } fclose (fp); if (n == EOF) { /* this can happen if the format of /proc/cpuinfo changes... */ fprintf (stderr, "ioperm: Unable to determine system type.\n" "\t(May need " PATH_ARM_SYSTYPE " symlink?)\n"); __set_errno (ENODEV); return -1; } } /* translate systype name into i/o system: */ for (i = 0; i < sizeof (platform) / sizeof (platform[0]); ++i) { if (strcmp (platform[i].name, systype) == 0) { io.shift = platform[i].shift; io.io_base = platform[i].io_base; io.initdone = 1; return 0; } } /* systype is not a known platform name... */ __set_errno (ENODEV); return -1; }
int sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp, const void *newp, size_t newlen) { int retval; retval = __sysctl(name, namelen, oldp, oldlenp, newp, newlen); if (retval != -1 || errno != ENOENT || name[0] != CTL_USER) return (retval); if (newp != NULL) { errno = EPERM; return (-1); } if (namelen != 2) { errno = EINVAL; return (-1); } switch (name[1]) { case USER_CS_PATH: if (oldp && *oldlenp < sizeof(_PATH_STDPATH)) { errno = ENOMEM; return -1; } *oldlenp = sizeof(_PATH_STDPATH); if (oldp != NULL) memmove(oldp, _PATH_STDPATH, sizeof(_PATH_STDPATH)); return (0); } if (oldp && *oldlenp < sizeof(int)) { errno = ENOMEM; return (-1); } *oldlenp = sizeof(int); if (oldp == NULL) return (0); switch (name[1]) { case USER_BC_BASE_MAX: *(int *)oldp = BC_BASE_MAX; return (0); case USER_BC_DIM_MAX: *(int *)oldp = BC_DIM_MAX; return (0); case USER_BC_SCALE_MAX: *(int *)oldp = BC_SCALE_MAX; return (0); case USER_BC_STRING_MAX: *(int *)oldp = BC_STRING_MAX; return (0); case USER_COLL_WEIGHTS_MAX: *(int *)oldp = COLL_WEIGHTS_MAX; return (0); case USER_EXPR_NEST_MAX: *(int *)oldp = EXPR_NEST_MAX; return (0); case USER_LINE_MAX: *(int *)oldp = LINE_MAX; return (0); case USER_RE_DUP_MAX: *(int *)oldp = RE_DUP_MAX; return (0); case USER_POSIX2_VERSION: *(int *)oldp = _POSIX2_VERSION; return (0); case USER_POSIX2_C_BIND: #ifdef POSIX2_C_BIND *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_C_DEV: #ifdef POSIX2_C_DEV *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_CHAR_TERM: #ifdef POSIX2_CHAR_TERM *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_FORT_DEV: #ifdef POSIX2_FORT_DEV *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_FORT_RUN: #ifdef POSIX2_FORT_RUN *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_LOCALEDEF: #ifdef POSIX2_LOCALEDEF *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_SW_DEV: #ifdef POSIX2_SW_DEV *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_UPE: #ifdef POSIX2_UPE *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_STREAM_MAX: *(int *)oldp = FOPEN_MAX; return (0); case USER_TZNAME_MAX: *(int *)oldp = NAME_MAX; return (0); default: errno = EINVAL; return (-1); } /* NOTREACHED */ }
int sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp, const void *newp, size_t newlen) { int retval; size_t orig_oldlen; orig_oldlen = oldlenp ? *oldlenp : 0; retval = __sysctl(name, namelen, oldp, oldlenp, newp, newlen); /* * All valid names under CTL_USER have a dummy entry in the sysctl * tree (to support name lookups and enumerations) with an * empty/zero value, and the true value is supplied by this routine. * For all such names, __sysctl() is used solely to validate the * name. * * Return here unless there was a successful lookup for a CTL_USER * name. */ if (retval || name[0] != CTL_USER) return (retval); if (newp != NULL) { errno = EPERM; return (-1); } if (namelen != 2) { errno = EINVAL; return (-1); } switch (name[1]) { case USER_CS_PATH: if (oldp && orig_oldlen < sizeof(_PATH_STDPATH)) { errno = ENOMEM; return -1; } *oldlenp = sizeof(_PATH_STDPATH); if (oldp != NULL) memmove(oldp, _PATH_STDPATH, sizeof(_PATH_STDPATH)); return (0); } if (oldp && *oldlenp < sizeof(int)) { errno = ENOMEM; return (-1); } *oldlenp = sizeof(int); if (oldp == NULL) return (0); switch (name[1]) { case USER_BC_BASE_MAX: *(int *)oldp = BC_BASE_MAX; return (0); case USER_BC_DIM_MAX: *(int *)oldp = BC_DIM_MAX; return (0); case USER_BC_SCALE_MAX: *(int *)oldp = BC_SCALE_MAX; return (0); case USER_BC_STRING_MAX: *(int *)oldp = BC_STRING_MAX; return (0); case USER_COLL_WEIGHTS_MAX: *(int *)oldp = COLL_WEIGHTS_MAX; return (0); case USER_EXPR_NEST_MAX: *(int *)oldp = EXPR_NEST_MAX; return (0); case USER_LINE_MAX: *(int *)oldp = LINE_MAX; return (0); case USER_RE_DUP_MAX: *(int *)oldp = RE_DUP_MAX; return (0); case USER_POSIX2_VERSION: *(int *)oldp = _POSIX2_VERSION; return (0); case USER_POSIX2_C_BIND: #if _POSIX2_C_BIND > 0 *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_C_DEV: #if _POSIX2_C_DEV > 0 *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_CHAR_TERM: #if _POSIX2_CHAR_TERM > 0 *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_FORT_DEV: #if _POSIX2_FORT_DEV > 0 *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_FORT_RUN: #if _POSIX2_FORT_RUN > 0 *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_LOCALEDEF: #if _POSIX2_LOCALEDEF > 0 *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_SW_DEV: #if _POSIX2_SW_DEV > 0 *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_UPE: #if _POSIX2_UPE > 0 *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_STREAM_MAX: *(int *)oldp = FOPEN_MAX; return (0); case USER_TZNAME_MAX: *(int *)oldp = NAME_MAX; return (0); default: errno = EINVAL; return (-1); } /* NOTREACHED */ }
/* Create a device file named PATH relative to FD, with permission and special bits MODE and device number DEV (which can be constructed from major and minor device numbers with the `makedev' macro above). */ int __xmknodat (int vers, int fd, const char *file, mode_t mode, dev_t * dev) { if (vers != _MKNOD_VER) { __set_errno (EINVAL); return -1; } # ifndef __ASSUME_ATFCTS if (__have_atfcts >= 0) # endif { int result; /* The FreeBSD mknod() system call cannot be used to create FIFOs; we must use the mkfifo() system call for this purpose. */ if (S_ISFIFO (mode)) result = INLINE_SYSCALL (mkfifoat, 3, fd, file, mode); else result = INLINE_SYSCALL (mknodat, 4, fd, file, mode, *dev); # ifndef __ASSUME_ATFCTS if (result == -1 && errno == ENOSYS) __have_atfcts = -1; else # endif return result; } #ifndef __ASSUME_ATFCTS if (fd != AT_FDCWD && file[0] != '/') { int mib[4]; size_t kf_len = 0; char *kf_buf, *kf_bufp; size_t filelen; if (fd < 0) { __set_errno (EBADF); return -1; } filelen = strlen (file); if (__builtin_expect (filelen == 0, 0)) { __set_errno (ENOENT); return -1; } mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_FILEDESC; mib[3] = __getpid (); if (__sysctl (mib, 4, NULL, &kf_len, NULL, 0) != 0) { __set_errno (ENOSYS); return -1; } kf_buf = alloca (kf_len + filelen); if (__sysctl (mib, 4, kf_buf, &kf_len, NULL, 0) != 0) { __set_errno (ENOSYS); return -1; } kf_bufp = kf_buf; while (kf_bufp < kf_buf + kf_len) { struct kinfo_file *kf = (struct kinfo_file *) (uintptr_t) kf_bufp; if (kf->kf_fd == fd) { if (kf->kf_type != KF_TYPE_VNODE || kf->kf_vnode_type != KF_VTYPE_VDIR) { __set_errno (ENOTDIR); return -1; } strcat (kf->kf_path, "/"); strcat (kf->kf_path, file); file = kf->kf_path; break; } kf_bufp += kf->kf_structsize; } if (kf_bufp >= kf_buf + kf_len) { __set_errno (EBADF); return -1; } } return __xmknod (vers, file, mode, dev); #endif }