chiark / gitweb /
build-sys: prepare release 1
[elogind.git] / src / util.c
index 41d8e7f999eeaffaf695d06bcbeea22e34ca9531..a5f904dbfdea2e90137728ad12fcc7b6af7e2d55 100644 (file)
@@ -46,6 +46,7 @@
 #include <sys/prctl.h>
 #include <sys/utsname.h>
 #include <pwd.h>
+#include <netinet/ip.h>
 
 #include "macro.h"
 #include "util.h"
@@ -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,105 @@ 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);
+}
+
+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",
@@ -2625,3 +2786,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);