X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Futil.c;h=4795dbcc6aca0358795bafb460ff5a032d58ee04;hb=9e58ff9c5c3bd46a796a20fc6c304cdab489f334;hp=11ab074569ec422f5ecf9581ba94785e83c4a7e0;hpb=8c6db8336536916d0476ff8233e0abf40a2f6aab;p=elogind.git diff --git a/src/util.c b/src/util.c index 11ab07456..4795dbcc6 100644 --- a/src/util.c +++ b/src/util.c @@ -46,6 +46,7 @@ #include #include #include +#include #include "macro.h" #include "util.h" @@ -75,7 +76,7 @@ usec_t now(clockid_t clock_id) { return timespec_load(&ts); } -timestamp* timestamp_get(timestamp *ts) { +dual_timestamp* dual_timestamp_get(dual_timestamp *ts) { assert(ts); ts->realtime = now(CLOCK_REALTIME); @@ -565,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; @@ -2537,6 +2599,58 @@ int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) { return 0; } +cpu_set_t* cpu_set_malloc(unsigned *ncpus) { + cpu_set_t *r; + unsigned n = 1024; + + /* Allocates the cpuset in the right size */ + + for (;;) { + if (!(r = CPU_ALLOC(n))) + return NULL; + + if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) { + CPU_ZERO_S(CPU_ALLOC_SIZE(n), r); + + if (ncpus) + *ncpus = n; + + return r; + } + + CPU_FREE(r); + + if (errno != EINVAL) + return NULL; + + n *= 2; + } +} + +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); +} + static const char *const ioprio_class_table[] = { [IOPRIO_CLASS_NONE] = "none", [IOPRIO_CLASS_RT] = "realtime", @@ -2625,3 +2739,12 @@ static const char* const rlimit_table[] = { }; DEFINE_STRING_TABLE_LOOKUP(rlimit, int); + +static const char* const ip_tos_table[] = { + [IPTOS_LOWDELAY] = "low-delay", + [IPTOS_THROUGHPUT] = "throughput", + [IPTOS_RELIABILITY] = "reliability", + [IPTOS_LOWCOST] = "low-cost", +}; + +DEFINE_STRING_TABLE_LOOKUP(ip_tos, int);