X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Futil.c;h=80b88b0e4e2fee36dc9dbf278ed919276107cc19;hb=6a3b1508f7a9c8ecf712beb44baa13f252f0d3d8;hp=08bdec223eda8f2bebd6d345050c49aca74b40b3;hpb=60b4f27794f3f3b5bd1c67b42d09eb4c21838aed;p=elogind.git diff --git a/src/util.c b/src/util.c index 08bdec223..80b88b0e4 100644 --- a/src/util.c +++ b/src/util.c @@ -250,7 +250,7 @@ int parse_boolean(const char *v) { } int parse_pid(const char *s, pid_t* ret_pid) { - unsigned long ul; + unsigned long ul = 0; pid_t pid; int r; @@ -2617,33 +2617,6 @@ int make_null_stdio(void) { return make_stdio(null_fd); } -bool is_clean_exit(int code, int status) { - - if (code == CLD_EXITED) - return status == 0; - - /* If a daemon does not implement handlers for some of the - * signals that's not considered an unclean shutdown */ - if (code == CLD_KILLED) - return - status == SIGHUP || - status == SIGINT || - status == SIGTERM || - status == SIGPIPE; - - return false; -} - -bool is_clean_exit_lsb(int code, int status) { - - if (is_clean_exit(code, status)) - return true; - - return - code == CLD_EXITED && - (status == EXIT_NOTINSTALLED || status == EXIT_NOTCONFIGURED); -} - bool is_device_path(const char *path) { /* Returns true on paths that refer to a device, either in @@ -3044,6 +3017,21 @@ void status_welcome(void) { if (!ansi_color) const_color = "1;34"; /* Light Blue for Gentoo */ +#elif defined(TARGET_ALTLINUX) + + if (!pretty_name) { + if ((r = read_one_line_file("/etc/altlinux-release", &pretty_name)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/altlinux-release: %s", strerror(-r)); + } else + truncate_nl(pretty_name); + } + + if (!ansi_color) + const_color = "0;36"; /* Cyan for ALTLinux */ + + #elif defined(TARGET_DEBIAN) if (!pretty_name) { @@ -3090,6 +3078,9 @@ void status_welcome(void) { status_printf("Welcome to \x1B[%sm%s\x1B[0m!\n", const_color ? const_color : ansi_color, const_pretty ? const_pretty : pretty_name); + + free(ansi_color); + free(pretty_name); } char *replace_env(const char *format, char **env) { @@ -3326,6 +3317,44 @@ char *unquote(const char *s, const char* quotes) { return strdup(s); } +char *normalize_env_assignment(const char *s) { + char *name, *value, *p, *r; + + p = strchr(s, '='); + + if (!p) { + if (!(r = strdup(s))) + return NULL; + + return strstrip(r); + } + + if (!(name = strndup(s, p - s))) + return NULL; + + if (!(p = strdup(p+1))) { + free(name); + return NULL; + } + + value = unquote(strstrip(p), QUOTES); + free(p); + + if (!value) { + free(p); + free(name); + return NULL; + } + + if (asprintf(&r, "%s=%s", name, value) < 0) + r = NULL; + + free(value); + free(name); + + return r; +} + int wait_for_terminate(pid_t pid, siginfo_t *status) { assert(pid >= 1); assert(status); @@ -3398,7 +3427,18 @@ bool null_or_empty(struct stat *st) { } DIR *xopendirat(int fd, const char *name, int flags) { - return fdopendir(openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags)); + int nfd; + DIR *d; + + if ((nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags)) < 0) + return NULL; + + if (!(d = fdopendir(nfd))) { + close_nointr_nofail(nfd); + return NULL; + } + + return d; } int signal_from_string_try_harder(const char *s) { @@ -3479,7 +3519,7 @@ char *fstab_node_to_udev_node(const char *p) { if (!t) return NULL; - r = asprintf(&dn, "/dev/disk/by-uuid/%s", ascii_strlower(t)); + r = asprintf(&dn, "/dev/disk/by-uuid/%s", t); free(t); if (r < 0) @@ -3509,19 +3549,119 @@ void filter_environ(const char *prefix) { environ[j] = NULL; } +bool tty_is_vc(const char *tty) { + assert(tty); + + if (startswith(tty, "/dev/")) + tty += 5; + + return startswith(tty, "tty") && + tty[3] >= '0' && tty[3] <= '9'; +} + const char *default_term_for_tty(const char *tty) { + char *active = NULL; + const char *term; + assert(tty); if (startswith(tty, "/dev/")) tty += 5; - if (startswith(tty, "tty") && - tty[3] >= '0' && tty[3] <= '9') - return "TERM=linux"; + /* Resolve where /dev/console is pointing when determining + * TERM */ + if (streq(tty, "console")) + if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) { + truncate_nl(active); + + /* If multiple log outputs are configured the + * last one is what /dev/console points to */ + if ((tty = strrchr(active, ' '))) + tty++; + else + tty = active; + } + + term = tty_is_vc(tty) ? "TERM=linux" : "TERM=vt100"; + free(active); + + return term; +} + +bool running_in_vm(void) { + +#if defined(__i386__) || defined(__x86_64__) - /* FIXME: Proper handling of /dev/console would be cool */ + /* Both CPUID and DMI are x86 specific interfaces... */ - return "TERM=vt100"; + const char *const dmi_vendors[] = { + "/sys/class/dmi/id/sys_vendor", + "/sys/class/dmi/id/board_vendor", + "/sys/class/dmi/id/bios_vendor" + }; + + uint32_t eax = 0x40000000; + union { + uint32_t sig32[3]; + char text[13]; + } sig; + + unsigned i; + + for (i = 0; i < ELEMENTSOF(dmi_vendors); i++) { + char *s; + bool b; + + if (read_one_line_file(dmi_vendors[i], &s) < 0) + continue; + + b = startswith(s, "QEMU") || + /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ + startswith(s, "VMware") || + startswith(s, "VMW") || + startswith(s, "Microsoft Corporation") || + startswith(s, "innotek GmbH") || + startswith(s, "Xen"); + + free(s); + + if (b) + return true; + } + + /* http://lwn.net/Articles/301888/ */ + zero(sig); + + +#if defined (__i386__) +#define REG_a "eax" +#define REG_b "ebx" +#elif defined (__amd64__) +#define REG_a "rax" +#define REG_b "rbx" +#endif + + __asm__ __volatile__ ( + /* ebx/rbx is being used for PIC! */ + " push %%"REG_b" \n\t" + " cpuid \n\t" + " mov %%ebx, %1 \n\t" + " pop %%"REG_b" \n\t" + + : "=a" (eax), "=r" (sig.sig32[0]), "=c" (sig.sig32[1]), "=d" (sig.sig32[2]) + : "0" (eax) + ); + + if (streq(sig.text, "XenVMMXenVMM") || + streq(sig.text, "KVMKVMKVM") || + /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ + streq(sig.text, "VMwareVMware") || + /* http://msdn.microsoft.com/en-us/library/bb969719.aspx */ + streq(sig.text, "Microsoft Hv")) + return true; +#endif + + return false; } static const char *const ioprio_class_table[] = {