procfs: add reading cmdline and exe 28/183128/3
authorLukasz Stanislawski <l.stanislaws@samsung.com>
Fri, 29 Jun 2018 10:44:56 +0000 (12:44 +0200)
committerLukasz Stanislawski <l.stanislaws@samsung.com>
Tue, 3 Jul 2018 13:25:09 +0000 (15:25 +0200)
Change-Id: Ibf7e126b86ddb70144448f87da167a55a4dfb7cf

src/procfs.c
src/procfs.h

index bbcad07..2e64900 100644 (file)
@@ -18,6 +18,7 @@
 #include <string.h>
 #include <dirent.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 #include "procfs.h"
 #include "log.h"
@@ -31,6 +32,8 @@
 #define PIDSTAT_FILEPATH "/proc/%d/stat"
 #define SMAPS_FILEPATH "/proc/%d/smaps"
 #define PROC_DIR_PATH "/proc/"
+#define PROC_PID_EXE_PATH "/proc/%d/exe"
+#define PROC_PID_CMDLINE_PATH "/proc/%d/cmdline"
 
 struct procfs_pid_iterator
 {
@@ -350,3 +353,83 @@ void procfs_pid_iterator_free(procfs_pid_iterator_t *iterator)
        if (iterator->dir) closedir(iterator->dir);
        free(iterator);
 }
+
+int procfs_read_exe(int pid, char **exe)
+{
+       ON_TRUE_RETURN_VAL(pid < 0, -1);
+       ON_NULL_RETURN_VAL(exe, -1);
+
+       char buf[256];
+       size_t size = 32;
+       char *buffer = NULL;
+       int ret;
+
+       snprintf(buf, sizeof(buf), PROC_PID_EXE_PATH, pid);
+
+       do
+       {
+               size *= 2;
+               char *tmp = realloc(buffer, size);
+               if (!tmp) {
+                       free(buffer);
+                       return -1;
+               }
+               buffer = tmp;
+               ret = readlink(buf, buffer, size);
+               if (ret == -1) {
+                       free(buffer);
+                       return -1;
+               }
+               buffer[ret] = '\0';
+       } while (ret >= size);
+
+       *exe = buffer;
+       return 0;
+}
+
+int procfs_read_cmdline(int pid, char **cmdline)
+{
+       ON_TRUE_RETURN_VAL(pid < 0, -1);
+       ON_NULL_RETURN_VAL(cmdline, -1);
+
+       char buf[64];
+       int read, read_total = 0;
+       char *cmd = NULL;
+
+       snprintf(buf, sizeof(buf), PROC_PID_CMDLINE_PATH, pid);
+
+       FILE *cmdline_fp = fopen(buf, "r");
+       if (!cmdline_fp) {
+               ERR("failed to open %s", buf);
+               return -1;
+       }
+
+       while ((read = fread(buf, 1, sizeof(buf), cmdline_fp)) != 0) {
+               char *tmp = realloc(cmd, read_total + read + 1);
+               if (!tmp) {
+                       fclose(cmdline_fp);
+                       free(cmd);
+                       return -1;
+               }
+               cmd = tmp;
+               memcpy(cmd + read_total, buf, read);
+               read_total += read;
+       }
+
+       if (read_total == 0) {
+               fclose(cmdline_fp);
+               *cmdline = NULL;
+               return 0;
+       }
+
+       // clear string from end-of-string characters
+       for (int i = 0; i < read_total; ++i) {
+               if (cmd[i] == '\0')
+                       cmd[i] = ' ';
+       }
+       cmd[read_total] = '\0';
+
+       fclose(cmdline_fp);
+       *cmdline = cmd;
+       return 0;
+}
index 6151d8e..5cda830 100644 (file)
@@ -188,4 +188,30 @@ void procfs_pid_iterator_free(procfs_pid_iterator_t *iterator);
  */
 procfs_pid_iterator_t *procfs_get_pid_iterator();
 
+/**
+ * @brief Reads cmdline file for given pid
+ *
+ * @param[in] pid
+ * @param[out] cmdline pointer to newly allocated null-terminated string buffer or NULL
+ * if cmdline file is empty.
+ *
+ * @return numer of bytes written in buffer or -1 on error.
+ *
+ * @note the returned cmdline should be released with @free
+ * @note the cmdline parameters are separated using ' ' sign.
+ */
+int procfs_read_cmdline(int pid, char **cmdline);
+
+/**
+ * @brief Reads exe file for given pid
+ *
+ * @param[in] pid
+ * @param[out] pointer to null-terminated string buffer
+ *
+ * @return 0 on success, -1 on failure
+ *
+ * @note the returned buffer should be released with @free
+ */
+int procfs_read_exe(int pid, char **buffer);
+
 #endif