aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeilin Ye <peilin.ye@bytedance.com>2022-05-24 19:53:21 -0700
committerDavid Ahern <dsahern@kernel.org>2022-05-30 09:54:23 -0600
commit12d491e58ff574219f1c01f844c0c76e4f4e5eef (patch)
treeb432108ff4192b40592fbcd07a8e82e1fdeab900
parent210018bfe99b21effd3f6f2f67dec7dcba49decc (diff)
downloadiproute2-12d491e58ff574219f1c01f844c0c76e4f4e5eef.tar.gz
ss: Factor out fd iterating logic from user_ent_hash_build()
We are planning to add a thread version of the -p, --process option. Move the logic iterating $PROC_ROOT/$PID/fd/ into a new function, user_ent_hash_build_task(), to make it easier. Since we will use this function for both processes and threads, rename local variables as such (e.g. from "process" to "task"). Signed-off-by: Peilin Ye <peilin.ye@bytedance.com> Signed-off-by: David Ahern <dsahern@kernel.org>
-rw-r--r--misc/ss.c144
1 files changed, 79 insertions, 65 deletions
diff --git a/misc/ss.c b/misc/ss.c
index 97f41a0eb..ac0967fac 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -567,6 +567,81 @@ static void user_ent_add(unsigned int ino, char *process,
*pp = p;
}
+#define MAX_PATH_LEN 1024
+
+static void user_ent_hash_build_task(char *path, int pid)
+{
+ const char *no_ctx = "unavailable";
+ char task[16] = {'\0', };
+ char stat[MAX_PATH_LEN];
+ int pos_id, pos_fd;
+ char *task_context;
+ struct dirent *d;
+ DIR *dir;
+
+ if (getpidcon(pid, &task_context) != 0)
+ task_context = strdup(no_ctx);
+
+ pos_id = strlen(path); /* $PROC_ROOT/$ID/ */
+
+ snprintf(path + pos_id, MAX_PATH_LEN - pos_id, "fd/");
+ dir = opendir(path);
+ if (!dir) {
+ freecon(task_context);
+ return;
+ }
+
+ pos_fd = strlen(path); /* $PROC_ROOT/$ID/fd/ */
+
+ while ((d = readdir(dir)) != NULL) {
+ const char *pattern = "socket:[";
+ char *sock_context;
+ unsigned int ino;
+ ssize_t link_len;
+ char lnk[64];
+ int fd;
+
+ if (sscanf(d->d_name, "%d%*c", &fd) != 1)
+ continue;
+
+ snprintf(path + pos_fd, MAX_PATH_LEN - pos_fd, "%d", fd);
+
+ link_len = readlink(path, lnk, sizeof(lnk) - 1);
+ if (link_len == -1)
+ continue;
+ lnk[link_len] = '\0';
+
+ if (strncmp(lnk, pattern, strlen(pattern)))
+ continue;
+
+ if (sscanf(lnk, "socket:[%u]", &ino) != 1)
+ continue;
+
+ if (getfilecon(path, &sock_context) <= 0)
+ sock_context = strdup(no_ctx);
+
+ if (task[0] == '\0') {
+ FILE *fp;
+
+ strlcpy(stat, path, pos_id + 1);
+ snprintf(stat + pos_id, sizeof(stat) - pos_id, "stat");
+
+ fp = fopen(stat, "r");
+ if (fp) {
+ if (fscanf(fp, "%*d (%[^)])", task) < 1)
+ ; /* ignore */
+ fclose(fp);
+ }
+ }
+
+ user_ent_add(ino, task, pid, fd, task_context, sock_context);
+ freecon(sock_context);
+ }
+
+ freecon(task_context);
+ closedir(dir);
+}
+
static void user_ent_destroy(void)
{
struct user_ent *p, *p_next;
@@ -589,13 +664,10 @@ static void user_ent_destroy(void)
static void user_ent_hash_build(void)
{
const char *root = getenv("PROC_ROOT") ? : "/proc/";
+ char name[MAX_PATH_LEN];
struct dirent *d;
- char name[1024];
int nameoff;
DIR *dir;
- char *pid_context;
- char *sock_context;
- const char *no_ctx = "unavailable";
strlcpy(name, root, sizeof(name));
@@ -609,71 +681,13 @@ static void user_ent_hash_build(void)
return;
while ((d = readdir(dir)) != NULL) {
- struct dirent *d1;
- char process[16];
- int pid, pos;
- DIR *dir1;
+ int pid;
if (sscanf(d->d_name, "%d%*c", &pid) != 1)
continue;
- if (getpidcon(pid, &pid_context) != 0)
- pid_context = strdup(no_ctx);
-
- snprintf(name + nameoff, sizeof(name) - nameoff, "%d/fd/", pid);
- pos = strlen(name);
- dir1 = opendir(name);
- if (!dir1) {
- freecon(pid_context);
- continue;
- }
-
- process[0] = '\0';
-
- while ((d1 = readdir(dir1)) != NULL) {
- const char *pattern = "socket:[";
- unsigned int ino;
- char lnk[64];
- int fd;
- ssize_t link_len;
- char tmp[1024];
-
- if (sscanf(d1->d_name, "%d%*c", &fd) != 1)
- continue;
-
- snprintf(name + pos, sizeof(name) - pos, "%d", fd);
-
- link_len = readlink(name, lnk, sizeof(lnk) - 1);
- if (link_len == -1)
- continue;
- lnk[link_len] = '\0';
-
- if (strncmp(lnk, pattern, strlen(pattern)))
- continue;
-
- if (sscanf(lnk, "socket:[%u]", &ino) != 1)
- continue;
-
- if (getfilecon(name, &sock_context) <= 0)
- sock_context = strdup(no_ctx);
-
- if (process[0] == '\0') {
- FILE *fp;
-
- snprintf(tmp, sizeof(tmp), "%s/%d/stat", root, pid);
-
- fp = fopen(tmp, "r");
- if (fp) {
- if (fscanf(fp, "%*d (%[^)])", process) < 1)
- ; /* ignore */
- fclose(fp);
- }
- }
- user_ent_add(ino, process, pid, fd, pid_context, sock_context);
- freecon(sock_context);
- }
- freecon(pid_context);
- closedir(dir1);
+ snprintf(name + nameoff, sizeof(name) - nameoff, "%d/", pid);
+ user_ent_hash_build_task(name, pid);
}
closedir(dir);
}