]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
ss: Factor out fd iterating logic from user_ent_hash_build()
authorPeilin Ye <peilin.ye@bytedance.com>
Wed, 25 May 2022 02:53:21 +0000 (19:53 -0700)
committerDavid Ahern <dsahern@kernel.org>
Mon, 30 May 2022 15:54:23 +0000 (09:54 -0600)
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>
misc/ss.c

index 97f41a0eb7b08b2ce82fc99211aaaa8725144b01..ac0967fac4645d7c49705cd9694668d27f7a31e1 100644 (file)
--- 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);
 }