X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Futil.c;h=a5f904dbfdea2e90137728ad12fcc7b6af7e2d55;hp=ea8bfc198457f554b678a41f63f65d44ac3410fa;hb=afe1be4dbdf142513f6ac1d92e6a20bdc4b20c80;hpb=82c121a4754a9d405b07c75796e329942af2ccc5 diff --git a/src/util.c b/src/util.c index ea8bfc198..a5f904dbf 100644 --- a/src/util.c +++ b/src/util.c @@ -566,6 +566,67 @@ int get_process_name(pid_t pid, char **name) { return 0; } +int get_process_cmdline(pid_t pid, size_t max_length, char **line) { + char *p, *r, *k; + int c; + bool space = false; + size_t left; + FILE *f; + + assert(pid >= 1); + assert(max_length > 0); + assert(line); + + if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0) + return -ENOMEM; + + f = fopen(p, "r"); + free(p); + + if (!f) + return -errno; + + if (!(r = new(char, max_length))) { + fclose(f); + return -ENOMEM; + } + + k = r; + left = max_length; + while ((c = getc(f)) != EOF) { + + if (isprint(c)) { + if (space) { + if (left <= 4) + break; + + *(k++) = ' '; + left--; + space = false; + } + + if (left <= 4) + break; + + *(k++) = (char) c; + left--; + } else + space = true; + } + + if (left <= 4) { + size_t n = MIN(left-1, 3U); + memcpy(k, "...", n); + k[n] = 0; + } else + *k = 0; + + fclose(f); + + *line = r; + return 0; +} + char *strappend(const char *s, const char *suffix) { size_t a, b; char *r; @@ -2566,6 +2627,77 @@ cpu_set_t* cpu_set_malloc(unsigned *ncpus) { } } +void status_vprintf(const char *format, va_list ap) { + char *s = NULL; + int fd = -1; + + assert(format); + + /* This independent of logging, as status messages are + * optional and go exclusively to the console. */ + + if (vasprintf(&s, format, ap) < 0) + goto finish; + + if ((fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC)) < 0) + goto finish; + + write(fd, s, strlen(s)); + +finish: + free(s); + + if (fd >= 0) + close_nointr_nofail(fd); +} + +void status_printf(const char *format, ...) { + va_list ap; + + assert(format); + + va_start(ap, format); + status_vprintf(format, ap); + va_end(ap); +} + +void status_welcome(void) { + +#if defined(TARGET_FEDORA) + char *r; + + if (read_one_line_file("/etc/system-release", &r) < 0) + return; + + truncate_nl(r); + + /* This tries to mimic the color magic the old Red Hat sysinit + * script did. */ + + if (startswith(r, "Red Hat")) + status_printf("Welcome to \x1B[0;31m%s\x1B[0m!\n", r); /* Red for RHEL */ + else if (startswith(r, "Fedora")) + status_printf("Welcome to \x1B[0;34m%s\x1B[0m!\n", r); /* Blue for Fedora */ + else + status_printf("Welcome to %s!\n", r); + + free(r); + +#elif defined(TARGET_SUSE) + char *r; + + if (read_one_line_file("/etc/SuSE-release", &r) < 0) + return; + + truncate_nl(r); + + status_printf("Welcome to \x1B[0;32m%s\x1B[0m!\n", r); /* Green for SUSE */ + free(r); +#else +#warning "You probably should add a welcome text logic here." +#endif +} + static const char *const ioprio_class_table[] = { [IOPRIO_CLASS_NONE] = "none", [IOPRIO_CLASS_RT] = "realtime",