X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Futil.c;h=b02a77eed8ab65e144cbf557e12a5974e0ec880c;hb=b4353094e5097c0cb149b5adcffe2a6ba9240283;hp=7e8246bb61195a0019b6945eb87e7a621b892c41;hpb=07faed4f99d0c798f92de3032b9c20ca31388494;p=elogind.git diff --git a/src/util.c b/src/util.c index 7e8246bb6..b02a77eed 100644 --- a/src/util.c +++ b/src/util.c @@ -683,6 +683,73 @@ fail: return r; } +int load_env_file( + const char *fname, + char ***rl) { + + FILE *f; + char **m = 0; + int r; + + assert(fname); + assert(rl); + + if (!(f = fopen(fname, "re"))) + return -errno; + + while (!feof(f)) { + char l[LINE_MAX], *p, *u; + char **t; + + if (!fgets(l, sizeof(l), f)) { + if (feof(f)) + break; + + r = -errno; + goto finish; + } + + p = strstrip(l); + + if (!*p) + continue; + + if (strchr(COMMENTS, *p)) + continue; + + if (!(u = normalize_env_assignment(p))) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + t = strv_append(m, u); + free(u); + + if (!t) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + strv_free(m); + m = t; + } + + r = 0; + + *rl = m; + m = NULL; + +finish: + if (f) + fclose(f); + + strv_free(m); + + return r; +} + char *truncate_nl(char *s) { assert(s); @@ -3713,13 +3780,13 @@ int detect_vm(const char **id) { /* Both CPUID and DMI are x86 specific interfaces... */ - const char *const dmi_vendors[] = { + static const char *const dmi_vendors[] = { "/sys/class/dmi/id/sys_vendor", "/sys/class/dmi/id/board_vendor", "/sys/class/dmi/id/bios_vendor" }; - const char dmi_vendor_table[] = + static const char dmi_vendor_table[] = "QEMU\0" "qemu\0" /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ "VMware\0" "vmware\0" @@ -3727,9 +3794,10 @@ int detect_vm(const char **id) { "Microsoft Corporation\0" "microsoft\0" "innotek GmbH\0" "oracle\0" "Xen\0" "xen\0" + "Bochs\0" "bochs\0" "\0"; - const char cpuid_vendor_table[] = + static const char cpuid_vendor_table[] = "XenVMMXenVMM\0" "xen\0" "KVMKVMKVM\0" "kvm\0" /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ @@ -3743,34 +3811,9 @@ int detect_vm(const char **id) { uint32_t sig32[3]; char text[13]; } sig; - unsigned i; const char *j, *k; - - for (i = 0; i < ELEMENTSOF(dmi_vendors); i++) { - char *s; - int r; - const char *found = NULL; - - if ((r = read_one_line_file(dmi_vendors[i], &s)) < 0) { - if (r != -ENOENT) - return r; - - continue; - } - - NULSTR_FOREACH_PAIR(j, k, dmi_vendor_table) - if (startswith(s, j)) - found = k; - free(s); - - if (found) { - if (id) - *id = found; - - return 1; - } - } + bool hypervisor; /* http://lwn.net/Articles/301888/ */ zero(sig); @@ -3795,7 +3838,9 @@ int detect_vm(const char **id) { : "0" (eax) ); - if (ecx & 0x80000000U) { + hypervisor = !!(ecx & ecx & 0x80000000U); + + if (hypervisor) { /* There is a hypervisor, see what it is */ eax = 0x40000000U; @@ -3818,14 +3863,41 @@ int detect_vm(const char **id) { return 1; } + } + + for (i = 0; i < ELEMENTSOF(dmi_vendors); i++) { + char *s; + int r; + const char *found = NULL; + + if ((r = read_one_line_file(dmi_vendors[i], &s)) < 0) { + if (r != -ENOENT) + return r; + + continue; + } + + NULSTR_FOREACH_PAIR(j, k, dmi_vendor_table) + if (startswith(s, j)) + found = k; + free(s); + + if (found) { + if (id) + *id = found; + return 1; + } + } + + if (hypervisor) { if (id) *id = "other"; return 1; } -#endif +#endif return 0; } @@ -3972,6 +4044,17 @@ finish: hashmap_free_free(pids); } +int kill_and_sigcont(pid_t pid, int sig) { + int r; + + r = kill(pid, sig) < 0 ? -errno : 0; + + if (r >= 0) + kill(pid, SIGCONT); + + return r; +} + static const char *const ioprio_class_table[] = { [IOPRIO_CLASS_NONE] = "none", [IOPRIO_CLASS_RT] = "realtime",