int uname(struct utsname *utsbuf) { static struct { struct _uzisysinfoblk i; char buf[128]; } uts; char *x[5]; int bytes = _uname(&uts.i, sizeof(uts)); char *p = uts.buf; char *xp = x[0]; int ct = 0; if (bytes == -1) return bytes; x[0] = utsbuf->release; x[1] = utsbuf->sysname; x[2] = utsbuf->version; x[2] = utsbuf->machine; bytes -= sizeof(struct _uzisysinfoblk); while(xp = x[ct++]) { do { *xp++=*p++; bytes--; } while(*p && bytes); } return 0; }
long sysconf(int name) { struct _uzisysinfoblk info; int psize; int pscale; _uname(&info, sizeof(info)); psize = 65536/info.banks; pscale = psize/1024; switch(name) { case _SC_ARG_MAX: return 512; case _SC_CHILD_MAX: /* nproc -1 ? */ case _SC_HOST_NAME_MAX: /* we will implement get/sethostname and domain name in userspace */ return 256; case _SC_LOGIN_NAME_MAX: return 32; case _SC_CLK_TCK: /* query via unameinfo */ return info.ticks; case _SC_OPEN_MAX: /* query via unameinfo */ return info.max_open; case _SC_PAGESIZE: /* query via unameinfo */ return psize; case _SC_RE_DUP_MAX: /* FIXME: read the regexp code */ return 4; case _SC_STREAM_MAX: /* In theory down to RAM */ return 256; case _SC_SYMLOOP_MAX: /* Not supported yet */ return 1; case _SC_TTY_NAME_MAX: return 9; case _SC_TZNAME_MAX: return 6; /* Don't provide _SC_VERSION - we don't really meet POSIX! */ case _SC_VERSION: return 0; case _SC_PHYS_PAGES: return info.memk/pscale; case _SC_AVPHYS_PAGES: return (info.memk-info.usedk)/pscale; case _SC_NPROCESSORS_CONF: case _SC_NPROCESSORS_ONLN: return 1; default: errno = EINVAL; return -1; } }
/* * gethostname bsd compatibility */ int gethostname(char *hname, int hlen) { struct utsname u; #if defined(__i386) && !defined(__amd64) if (_nuname(&u) < 0) { #else if (_uname(&u) < 0) { #endif /* __i386 */ return (-1); } (void) strncpy(hname, u.nodename, hlen); return (0); }
int uname(struct utsname * n) { if (KVER_NOT_INITIALIZED) kver_initialize(); if (KVER_BADLY_INITIALIZED) return _uname(n); (void) strncpy(n->sysname, real_utsname.sysname, _SYS_NMLN); (void) strncpy(n->nodename, real_utsname.nodename, _SYS_NMLN); (void) strncpy(n->release, kver.osrelease, _SYS_NMLN); (void) strncpy(n->version, kver.version, _SYS_NMLN); (void) strncpy(n->machine, real_utsname.machine, _SYS_NMLN); return 0; }
void _start(void) { struct utsname name; const char text_sysname[] = "sysname: "; const char text_nodename[] = "nodename: "; const char text_release[] = "release: "; const char text_version[] = "version: "; const char text_machine[] = "machine: "; const char text_domainname[] = "domainname: "; char buffer[sizeof(text_sysname) + sizeof(name.sysname) + sizeof(text_nodename) + sizeof(name.nodename) + sizeof(text_release) + sizeof(name.release) + sizeof(text_version) + sizeof(name.version) + sizeof(text_machine) + sizeof(name.machine) + sizeof(text_domainname) + sizeof(name.domainname) + 1]; char *ptr; if (_uname(&name) < 0) { write_string(2, "Error: uname failed\n"); exit(1); } ptr = buffer; ptr = stplcpy(ptr, text_sysname, sizeof(text_sysname) - 1); ptr = stplcpy(ptr, name.sysname, sizeof(name.sysname)); *ptr++ = '\n'; ptr = stplcpy(ptr, text_nodename, sizeof(text_nodename) - 1); ptr = stplcpy(ptr, name.nodename, sizeof(name.nodename)); *ptr++ = '\n'; ptr = stplcpy(ptr, text_release, sizeof(text_release) - 1); ptr = stplcpy(ptr, name.release, sizeof(name.release)); *ptr++ = '\n'; ptr = stplcpy(ptr, text_version, sizeof(text_version) - 1); ptr = stplcpy(ptr, name.version, sizeof(name.version)); *ptr++ = '\n'; ptr = stplcpy(ptr, text_machine, sizeof(text_machine) - 1); ptr = stplcpy(ptr, name.machine, sizeof(name.machine)); *ptr++ = '\n'; ptr = stplcpy(ptr, text_domainname, sizeof(text_domainname) - 1); ptr = stplcpy(ptr, name.domainname, sizeof(name.domainname)); *ptr++ = '\n'; write_all(1, buffer, (size_t)(ptr - buffer)); exit(0); }
/* * FIXME Update bitset in long-running process if dm claims new major numbers. */ static int _create_dm_bitset(void) { #ifdef DM_IOCTLS if (_dm_bitset || _dm_device_major) return 1; if (!_uname()) return 0; /* * 2.6 kernels are limited to one major number. * Assume 2.4 kernels are patched not to. * FIXME Check _dm_version and _dm_version_minor if 2.6 changes this. */ if (KERNEL_VERSION(_kernel_major, _kernel_minor, _kernel_release) >= KERNEL_VERSION(2, 6, 0)) _dm_multiple_major_support = 0; if (!_dm_multiple_major_support) { if (!_get_proc_number(PROC_DEVICES, DM_NAME, &_dm_device_major)) return 0; return 1; } /* Multiple major numbers supported */ if (!(_dm_bitset = dm_bitset_create(NULL, NUMBER_OF_MAJORS))) return 0; if (!_get_proc_number(PROC_DEVICES, DM_NAME, NULL)) { dm_bitset_destroy(_dm_bitset); _dm_bitset = NULL; return 0; } return 1; #else return 0; #endif }
static void kver_initialize(void) { char *v; int i; kver.osrevision = KVER_INVALID_OSRELEASE; /* init done */ v = getenv(VAR_LIBKVER_OSRELEASE); if (v == NULL) { char b[MAXPATHLEN + 1]; i = readlink(PATH_LIBKVER_OSRELEASE, b, sizeof b - 1); if (i <= 0) { v = NULL; } else { b[i] = '\0'; v = b; } } if (v == NULL) { warnx("libkver: not configured"); return; } if (_uname(&real_utsname) != 0) { warn("libkver: uname"); return; } kver.osrevision = str2osrevision(v); if (kver.osrevision == KVER_INVALID_OSRELEASE) { warnx("libkver: invalid version: %s", v); return; } (void) strncpy(kver.osrelease, v, _SYS_NMLN); kver.osrelease[_SYS_NMLN - 1] = '\0'; (void) snprintf(kver.version, _SYS_NMLN, KVER_VERSION_FMT, kver.osrelease, real_utsname.machine); return; }
static int _open_control(void) { #ifdef DM_IOCTLS char control[PATH_MAX]; uint32_t major = 0, minor; int dm_mod_autoload_support, needs_open; if (_control_fd != -1) return 1; if (!_uname()) return 0; snprintf(control, sizeof(control), "%s/%s", dm_dir(), DM_CONTROL_NODE); /* * dm-mod autoloading is supported since kernel 2.6.36. * Udev daemon will try to read modules.devname file extracted * by depmod and create any static nodes needed. * The /dev/mapper/control node can be created and prepared this way. * First access to such node should load dm-mod module automatically. */ dm_mod_autoload_support = KERNEL_VERSION(_kernel_major, _kernel_minor, _kernel_release) >= KERNEL_VERSION(2, 6, 36); /* * If dm-mod autoloading is supported and the control node exists * already try to open it now. This should autoload dm-mod module. */ if (dm_mod_autoload_support) { if (!_get_proc_number(PROC_DEVICES, MISC_NAME, &major)) /* If major not found, just fallback to hardcoded value. */ major = MISC_MAJOR; /* Recreate the node with correct major and minor if needed. */ if (!_control_exists(control, major, MAPPER_CTRL_MINOR) && !_create_control(control, major, MAPPER_CTRL_MINOR)) goto error; _open_and_assign_control_fd(control, 1); } /* * Get major and minor number assigned for the control node. * In case we make use of the module autoload support, this * information should be accessible now as well. */ if (!_control_device_number(&major, &minor)) log_error("Is device-mapper driver missing from kernel?"); /* * Check the control node and its major and minor number. * If there's anything wrong, remove the old node and create * a correct one. */ if ((needs_open = !_control_exists(control, major, minor)) && !_create_control(control, major, minor)) { _close_control_fd(); goto error; } /* * For older kernels without dm-mod autoloading support, we always * need to open the control node here - we still haven't done that! * For newer kernels with dm-mod autoloading, we open it only if the * node was recreated and corrected in previous step. */ if ((!dm_mod_autoload_support || needs_open) && !_open_and_assign_control_fd(control, 0)) goto error; if (!_create_dm_bitset()) { log_error("Failed to set up list of device-mapper major numbers"); return 0; } return 1; error: log_error("Failure to communicate with kernel device-mapper driver."); return 0; #else return 1; #endif }