summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Syromyatnikov <evgsyr@gmail.com>2021-08-26 20:31:21 +0200
committerEugene Syromyatnikov <evgsyr@gmail.com>2021-08-30 21:34:33 +0200
commit1a2f6132fc0cf8f182436a4e74e97b5fdbcd7c7e (patch)
tree4a632a89a57e13f885ec4589bd385327fc69c271
parent8dc1d62336e90999c05b8ae9054958696b058892 (diff)
downloadstrace-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.h27
-rw-r--r--src/pidns.c59
-rw-r--r--src/util.c59
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.