diff options
| author | zy <[email protected]> | 2023-12-12 02:59:48 -0500 |
|---|---|---|
| committer | zy <[email protected]> | 2023-12-12 02:59:48 -0500 |
| commit | 96462422ce52424e5a1e77a7232efdb4889ed83a (patch) | |
| tree | b8151138057e72d2a7a4ffad66c6b8877187ebf6 /source/ucli/helpfun.cc | |
| parent | 462bdebad6eb2734fd0be4d014bfa2fa67d0ab29 (diff) | |
code clean
Diffstat (limited to 'source/ucli/helpfun.cc')
| -rw-r--r-- | source/ucli/helpfun.cc | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/source/ucli/helpfun.cc b/source/ucli/helpfun.cc new file mode 100644 index 0000000..db6bf76 --- /dev/null +++ b/source/ucli/helpfun.cc @@ -0,0 +1,198 @@ +#include "helpfun.h" + +unsigned long run_in_host = 0; + +enum { RUN_IN_HOST = 0, RUN_IN_CONTAINER }; + +int is_pid_1_has_environ(const char *field) { + bool done = false; + FILE *f = NULL; + int r = 0; + size_t l; + + assert(field); + + f = fopen("/proc/1/environ", "re"); + if (!f) + return 0; + + (void)__fsetlocking(f, FSETLOCKING_BYCALLER); + + l = strlen(field); + + do { + char line[BUF_LEN]; + size_t i; + + for (i = 0; i < sizeof(line) - 1; i++) { + int c; + + c = getc(f); + if ((c == EOF)) { + done = true; + break; + } else if (c == 0) + break; + + line[i] = c; + } + line[i] = 0; + + if (strneq(line, field, l) && line[l] == '=') { + r = 1; + goto out; + } + + } while (!done); + +out: + fclose(f); + return r; +} + +int get_proc_field(const char *filename, const char *pattern, + const char *terminator, char **field) { + char status[BUF_LEN] = {0}; + char *t, *f; + size_t len; + int r; + + assert(terminator); + assert(filename); + assert(pattern); + assert(field); + + int fd = open(filename, O_RDONLY); + if (fd < 0) + return -errno; + + r = read(fd, &status, BUF_LEN - 1); + if (r < 0) + return r; + + t = status; + + do { + bool pattern_ok; + + do { + t = strstr(t, pattern); + if (!t) + return -ENOENT; + + /* Check that pattern occurs in beginning of line. */ + pattern_ok = (t == status || t[-1] == '\n'); + + t += strlen(pattern); + + } while (!pattern_ok); + + t += strspn(t, " \t"); + if (!*t) + return -ENOENT; + + } while (*t != ':'); + + t++; + + if (*t) { + t += strspn(t, " \t"); + + /* Also skip zeros, because when this is used for + * capabilities, we don't want the zeros. This way the + * same capability set always maps to the same string, + * irrespective of the total capability set size. For + * other numbers it shouldn't matter. */ + t += strspn(t, "0"); + /* Back off one char if there's nothing but whitespace + and zeros */ + if (!*t || isspace(*t)) + t--; + } + + len = strcspn(t, terminator); + + f = strndup(t, len); + if (!f) + return -ENOMEM; + + *field = f; + return 0; +} + +static int detect_container_by_pid_2(void) { + char *s = NULL; + int r; + + r = get_proc_field("/proc/2/status", "PPid", WHITESPACE, &s); + if (r >= 0) { + if (streq(s, "0")) + r = RUN_IN_HOST; + else + r = RUN_IN_CONTAINER; + } else if (r == -ENOENT) + r = RUN_IN_CONTAINER; + else { + printf("Failed to read /proc/2/status: %d\n", r); + r = RUN_IN_HOST; + } + + free(s); + return r; +} + +int check_in_host(void) { + int r; + + if (is_pid_1_has_environ("container")) + r = RUN_IN_CONTAINER; + else + r = detect_container_by_pid_2(); + + return r == RUN_IN_HOST; +} + +static const char *user_mode_str(int user_mode) { + switch (user_mode) { + case 1: + return "USER MODE"; + case 0: + return "SYSTEM MODE"; + default: + return "UNKNOWN MODE"; + } +} + +std::string state_str(int __state) { + std::vector<std::string> states; + if (__state == TASK_RUNNING) + states.push_back("TASK_RUNNING"); + // if (__state & TASK_RUNNING) states.push_back("TASK_RUNNING"); + if (__state & TASK_INTERRUPTIBLE) + states.push_back("TASK_INTERRUPTIBLE"); + if (__state & TASK_UNINTERRUPTIBLE) + states.push_back("TASK_UNINTERRUPTIBLE"); + if (__state & __TASK_STOPPED) + states.push_back("__TASK_STOPPED"); + if (__state & __TASK_TRACED) + states.push_back("__TASK_TRACED"); + if (__state & TASK_PARKED) + states.push_back("TASK_PARKED"); + if (__state & TASK_DEAD) + states.push_back("TASK_DEAD"); + if (__state == TASK_KILLABLE) + states.push_back("TASK_KILLABLE"); + if (__state == TASK_STOPPED) + states.push_back("TASK_STOPPED"); + if (__state == TASK_IDLE) + states.push_back("TASK_IDLE"); + + std::string result; + for (const auto &state : states) { + if (!result.empty()) + result += " | "; + result += state; + } + + return result; +} |
