diff options
author | Eugene Syromyatnikov <evgsyr@gmail.com> | 2021-08-26 20:31:21 +0200 |
---|---|---|
committer | Eugene Syromyatnikov <evgsyr@gmail.com> | 2021-08-30 21:34:33 +0200 |
commit | 1a2f6132fc0cf8f182436a4e74e97b5fdbcd7c7e (patch) | |
tree | 4a632a89a57e13f885ec4589bd385327fc69c271 | |
parent | 8dc1d62336e90999c05b8ae9054958696b058892 (diff) | |
download | strace-1a2f6132fc0cf8f182436a4e74e97b5fdbcd7c7e.tar.gz |
util, pidns: generalise get_id_list
The parsing code implemented in it can be easily utilised for reading
other /proc/pid/status fields (Uid/Gid, for example), so let's move it
to util.c and make more generic.
* src/defs.h (proc_status_get_id_list): New declaration.
* src/util.c (proc_status_get_id_list): New function.
* src/pidns.c (get_id_list): Implement as a proc_status_get_id_list
wrapper.
-rw-r--r-- | src/defs.h | 27 | ||||
-rw-r--r-- | src/pidns.c | 59 | ||||
-rw-r--r-- | src/util.c | 59 |
3 files changed, 88 insertions, 57 deletions
diff --git a/src/defs.h b/src/defs.h index 1121ad571..b8146469d 100644 --- a/src/defs.h +++ b/src/defs.h @@ -1157,6 +1157,33 @@ printfd(struct tcb *tcp, int fd) } /** + * Helper function, converts pid to string, or to "self" for pid == 0. + * Uses static buffer for operation. + */ +extern const char *pid_to_str(pid_t pid); + +/** + * Get list of IDs present in a proc status record. IDs are placed in the array + * in the order they are stored in /proc. + * + * @param proc_pid PID (as present in /proc) to get information for. + * @param id_buf Pointer to buffer where parsed IDs are stored. + * Can be NULL. + * @param id_buf_size Number of items id_buf can store. If there are more IDs + * than id_buf can store, the excess IDs are not stored + * but still counted. + * @param str (Prefix) string IDs from which are to be read. + * @param str_size Size of the prefix string. Can be 0, in this case str + * has to be '\0'-terminated in order to be able to obtain + * its length. + * @return Number of items read (even if they are not written). + * 0 indicates error. + */ +extern size_t proc_status_get_id_list(int proc_pid, + int *id_buf, size_t id_buf_size, + const char *str, size_t str_size); + +/** * Print file descriptor fd owned by process with ID pid (from the PID NS * of the tracee). */ diff --git a/src/pidns.c b/src/pidns.c index d3ebd0535..9ec72a47d 100644 --- a/src/pidns.c +++ b/src/pidns.c @@ -139,21 +139,6 @@ get_cached_proc_pid(unsigned int ns, int ns_pid, enum pid_type type) } /** - * Helper function, converts pid to string, or to "self" for pid == 0. - * Uses static buffer for operation. - */ -static const char * -pid_to_str(pid_t pid) -{ - if (!pid) - return "self"; - - static char buf[sizeof("-2147483648")]; - xsprintf(buf, "%d", pid); - return buf; -} - -/** * Returns a list of PID NS IDs for the specified PID. * * @param proc_pid PID (as present in /proc) to get information for. @@ -226,48 +211,8 @@ get_ns_hierarchy(int proc_pid, unsigned int *ns_buf, size_t ns_buf_size) static size_t get_id_list(int proc_pid, int *id_buf, enum pid_type type) { - const char *ns_str = id_strs[type].str; - size_t ns_str_size = id_strs[type].size; - - size_t n = 0; - - char status_path[PATH_MAX + 1]; - xsprintf(status_path, "/proc/%s/status", pid_to_str(proc_pid)); - FILE *f = fopen_stream(status_path, "r"); - if (!f) - return 0; - - char *line = NULL; - size_t linesize = 0; - char *p = NULL; - - while (getline(&line, &linesize, f) > 0) { - if (strncmp(line, ns_str, ns_str_size) == 0) { - p = line + ns_str_size; - break; - } - } - - while (p) { - errno = 0; - long id = strtol(p, NULL, 10); - - if (id < 0 || id > INT_MAX || errno) { - perror_func_msg("converting pid (%ld) to int", id); - break; - } - - if (id_buf) - id_buf[n] = (int) id; - - n++; - strsep(&p, "\t"); - } - - free(line); - fclose(f); - - return n; + return proc_status_get_id_list(proc_pid, id_buf, MAX_NS_DEPTH, + id_strs[type].str, id_strs[type].size); } /** diff --git a/src/util.c b/src/util.c index a22d4095f..d438150ee 100644 --- a/src/util.c +++ b/src/util.c @@ -686,6 +686,65 @@ printfd_pid_tracee_ns(struct tcb *tcp, pid_t pid, int fd) printfd_pid(tcp, strace_pid, fd); } +const char * +pid_to_str(pid_t pid) +{ + if (!pid) + return "self"; + + static char buf[sizeof("-2147483648")]; + xsprintf(buf, "%d", pid); + return buf; +} + +size_t +proc_status_get_id_list(int proc_pid, int *id_buf, size_t id_buf_size, + const char *str, size_t str_size) +{ + size_t n = 0; + + if (!str_size) + str_size = strlen(str); + + char status_path[PATH_MAX + 1]; + xsprintf(status_path, "/proc/%s/status", pid_to_str(proc_pid)); + FILE *f = fopen_stream(status_path, "r"); + if (!f) + return 0; + + char *line = NULL; + size_t linesize = 0; + char *p = NULL; + + while (getline(&line, &linesize, f) > 0) { + if (strncmp(line, str, str_size) == 0) { + p = line + str_size; + break; + } + } + + while (p) { + errno = 0; + long id = strtol(p, NULL, 10); + + if (id < 0 || id > INT_MAX || errno) { + debug_func_perror_msg("converting \"%s\" to int", p); + break; + } + + if (id_buf && n < id_buf_size) + id_buf[n] = (int) id; + + n++; + strsep(&p, "\t"); + } + + free(line); + fclose(f); + + return n; +} + /* * Quote string `instr' of length `size' * Write up to (3 + `size' * 4) bytes to `outstr' buffer. |