add a command to force subbuffer switch
[ust.git] / libustcmd / ustcmd.c
index 55ac02a6193996afd109269bc077d6792feffe28..46a95618439915336fc654f9a90495b479d11039 100644 (file)
@@ -15,6 +15,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
  */
 
+#define _GNU_SOURCE
 #include <stdio.h>
 #include <unistd.h>
 #include <getopt.h>
 #include <fcntl.h>
 #include <string.h>
 #include <dirent.h>
-#
 
 #include "ustcomm.h"
 #include "ustcmd.h"
+#include "usterr.h"
 
-#define _GNU_SOURCE
-
-pid_t* ustcmd_get_online_pids(void) {
-       struct dirent* dirent;
-       DIR* dir;
-       char* ping_res;
+pid_t *ustcmd_get_online_pids(void)
+{
+       struct dirent *dirent;
+       DIR *dir;
+       unsigned int ret_size = 1 * sizeof(pid_t), i = 0;
 
        dir = opendir(SOCK_DIR);
        if (!dir) {
                return NULL;
        }
 
-       unsigned int ret_size = 1 * sizeof(pid_t), i = 0;
-       pid_t* ret = (pid_t*) malloc(ret_size);
+       pid_t *ret = (pid_t *) malloc(ret_size);
 
-       while (dirent = readdir(dir)) {
+       while ((dirent = readdir(dir))) {
                if (!strcmp(dirent->d_name, ".") ||
                        !strcmp(dirent->d_name, "..")) {
 
@@ -52,10 +51,10 @@ pid_t* ustcmd_get_online_pids(void) {
                if (dirent->d_type != DT_DIR &&
                        !!strcmp(dirent->d_name, "ustd")) {
 
-                       sscanf(dirent->d_name, "%u", (unsigned int*) &ret[i]);
+                       sscanf(dirent->d_name, "%u", (unsigned int *) &ret[i]);
                        if (pid_is_online(ret[i])) {
                                ret_size += sizeof(pid_t);
-                               ret = (pid_t*) realloc(ret, ret_size);
+                               ret = (pid_t *) realloc(ret, ret_size);
                                ++i;
                        }
                }
@@ -63,7 +62,8 @@ pid_t* ustcmd_get_online_pids(void) {
 
        ret[i] = 0; /* Array end */
 
-       if (ret[0] == 0) { /* No PID at all.. */
+       if (ret[0] == 0) {
+                /* No PID at all */
                free(ret);
                return NULL;
        }
@@ -80,17 +80,20 @@ pid_t* ustcmd_get_online_pids(void) {
  * @param pid  Traced process ID
  * @return     0 if successful, or errors {USTCMD_ERR_GEN, USTCMD_ERR_ARG}
  */
-int ustcmd_set_marker_state(const char* mn, int state, pid_t pid) {
+int ustcmd_set_marker_state(const char *mn, int state, pid_t pid)
+{
+       char *cmd_str [] = {"disable_marker", "enable_marker"};
+       char *cmd;
+       int result;
+
        if (mn == NULL) {
                return USTCMD_ERR_ARG;
        }
 
-       char* cmd_str [] = {"disable_marker", "enable_marker"};
-       char* cmd;
        asprintf(&cmd, "%s %s", cmd_str[state], mn);
 
-       int tres;
-       if (tres = ustcmd_shoot(cmd, pid, NULL)) {
+       result = ustcmd_send_cmd(cmd, pid, NULL);
+       if (result) {
                free(cmd);
                return USTCMD_ERR_GEN;
        }
@@ -99,16 +102,122 @@ int ustcmd_set_marker_state(const char* mn, int state, pid_t pid) {
        return 0;
 }
 
+/**
+ * Set subbuffer size.
+ *
+ * @param channel_size Channel name and size
+ * @param pid          Traced process ID
+ * @return             0 if successful, or error
+ */
+int ustcmd_set_subbuf_size(const char *channel_size, pid_t pid)
+{
+       char *cmd;
+       int result;
+
+       asprintf(&cmd, "%s %s", "set_subbuf_size", channel_size);
+
+       result = ustcmd_send_cmd(cmd, pid, NULL);
+       if (result != 1) {
+               free(cmd);
+               return 1;
+       }
+
+       free(cmd);
+       return 0;
+}
+
+/**
+ * Set subbuffer num.
+ *
+ * @param channel_num  Channel name and num
+ * @param pid          Traced process ID
+ * @return             0 if successful, or error
+ */
+int ustcmd_set_subbuf_num(const char *channel_size, pid_t pid)
+{
+       char *cmd;
+       int result;
+
+       asprintf(&cmd, "%s %s", "set_subbuf_num", channel_size);
+
+       result = ustcmd_send_cmd(cmd, pid, NULL);
+       if (result != 1) {
+               free(cmd);
+               return 1;
+       }
+
+       free(cmd);
+       return 0;
+}
+
+/**
+ * Get subbuffer size.
+ *
+ * @param channel      Channel name
+ * @param pid          Traced process ID
+ * @return             subbuf size if successful, or error
+ */
+int ustcmd_get_subbuf_size(const char *channel, pid_t pid)
+{
+       char *cmd, *reply;
+       int result;
+
+       /* format: channel_cpu */
+       asprintf(&cmd, "%s %s_0", "get_subbuf_size", channel);
+
+       result = ustcmd_send_cmd(cmd, pid, &reply);
+       if (result) {
+               free(cmd);
+               free(reply);
+               return -1;
+       }
+
+       result = atoi(reply);
+       free(cmd);
+       free(reply);
+       return result;
+}
+
+/**
+ * Get subbuffer num.
+ *
+ * @param channel      Channel name
+ * @param pid          Traced process ID
+ * @return             subbuf cnf if successful, or error
+ */
+int ustcmd_get_subbuf_num(const char *channel, pid_t pid)
+{
+       char *cmd, *reply;
+       int result;
+
+       /* format: channel_cpu */
+       asprintf(&cmd, "%s %s_0", "get_n_subbufs", channel);
+
+       result = ustcmd_send_cmd(cmd, pid, &reply);
+       if (result) {
+               free(cmd);
+               free(reply);
+               return -1;
+       }
+
+       result = atoi(reply);
+       free(cmd);
+       free(reply);
+       return result;
+}
+
 /**
  * Destroys an UST trace according to a PID.
  *
  * @param pid  Traced process ID
  * @return     0 if successful, or error USTCMD_ERR_GEN
  */
-int ustcmd_destroy_trace(pid_t pid) {
-       int tres;
+int ustcmd_destroy_trace(pid_t pid)
+{
+       int result;
 
-       if (tres = ustcmd_shoot("destroy", pid, NULL)) {
+       result = ustcmd_send_cmd("trace_destroy", pid, NULL);
+       if (result != 1) {
                return USTCMD_ERR_GEN;
        }
 
@@ -121,10 +230,30 @@ int ustcmd_destroy_trace(pid_t pid) {
  * @param pid  Traced process ID
  * @return     0 if successful, or error USTCMD_ERR_GEN
  */
-int ustcmd_setup_and_start(pid_t pid) {
-       int tres;
+int ustcmd_setup_and_start(pid_t pid)
+{
+       int result;
 
-       if (tres = ustcmd_shoot("start", pid, NULL)) {
+       result = ustcmd_send_cmd("start", pid, NULL);
+       if (result != 1) {
+               return USTCMD_ERR_GEN;
+       }
+
+       return 0;
+}
+
+/**
+ * Creates an UST trace according to a PID.
+ *
+ * @param pid  Traced process ID
+ * @return     0 if successful, or error USTCMD_ERR_GEN
+ */
+int ustcmd_create_trace(pid_t pid)
+{
+       int result;
+
+       result = ustcmd_send_cmd("trace_create", pid, NULL);
+       if (result != 1) {
                return USTCMD_ERR_GEN;
        }
 
@@ -137,10 +266,30 @@ int ustcmd_setup_and_start(pid_t pid) {
  * @param pid  Traced process ID
  * @return     0 if successful, or error USTCMD_ERR_GEN
  */
-int ustcmd_start_trace(pid_t pid) {
-       int tres;
+int ustcmd_start_trace(pid_t pid)
+{
+       int result;
+
+       result = ustcmd_send_cmd("trace_start", pid, NULL);
+       if (result != 1) {
+               return USTCMD_ERR_GEN;
+       }
+
+       return 0;
+}
+
+/**
+ * Alloc an UST trace according to a PID.
+ *
+ * @param pid  Traced process ID
+ * @return     0 if successful, or error USTCMD_ERR_GEN
+ */
+int ustcmd_alloc_trace(pid_t pid)
+{
+       int result;
 
-       if (tres = ustcmd_shoot("trace_start", pid, NULL)) {
+       result = ustcmd_send_cmd("trace_alloc", pid, NULL);
+       if (result != 1) {
                return USTCMD_ERR_GEN;
        }
 
@@ -153,10 +302,12 @@ int ustcmd_start_trace(pid_t pid) {
  * @param pid  Traced process ID
  * @return     0 if successful, or error USTCMD_ERR_GEN
  */
-int ustcmd_stop_trace(pid_t pid) {
-       int tres;
+int ustcmd_stop_trace(pid_t pid)
+{
+       int result;
 
-       if (tres = ustcmd_shoot("trace_stop", pid, NULL)) {
+       result = ustcmd_send_cmd("trace_stop", pid, NULL);
+       if (result != 1) {
                return USTCMD_ERR_GEN;
        }
 
@@ -169,7 +320,8 @@ int ustcmd_stop_trace(pid_t pid) {
  * @param str  String to search in
  * @return     Total newlines count
  */
-unsigned int ustcmd_count_nl(const char* str) {
+unsigned int ustcmd_count_nl(const char *str)
+{
        unsigned int i = 0, tot = 0;
 
        while (str[i] != '\0') {
@@ -188,7 +340,8 @@ unsigned int ustcmd_count_nl(const char* str) {
  * @param cmsf CMSF array to free
  * @return     0 if successful, or error USTCMD_ERR_ARG
  */
-int ustcmd_free_cmsf(struct USTcmd_cmsf* cmsf) {
+int ustcmd_free_cmsf(struct marker_status *cmsf)
+{
        if (cmsf == NULL) {
                return USTCMD_ERR_ARG;
        }
@@ -211,36 +364,39 @@ int ustcmd_free_cmsf(struct USTcmd_cmsf* cmsf) {
  * @param cmsf Pointer to CMSF array to be filled (callee allocates, caller
  *             frees with `ustcmd_free_cmsf')
  * @param pid  Targeted PID
- * @return     0 if successful, or errors {USTCMD_ERR_ARG, USTCMD_ERR_GEN}
+ * @return     0 if successful, or -1 on error
  */
-int ustcmd_get_cmsf(struct USTcmd_cmsf** cmsf, const pid_t pid) {
+int ustcmd_get_cmsf(struct marker_status **cmsf, const pid_t pid)
+{
+       char *big_str = NULL;
+       int result;
+       struct marker_status *tmp_cmsf = NULL;
+       unsigned int i = 0, cmsf_ind = 0;
+
        if (cmsf == NULL) {
-               return USTCMD_ERR_ARG;
+               return -1;
        }
-       char* big_str = NULL;
-       int tres;
-
-       if (tres = ustcmd_shoot("list_markers", pid, &big_str)) {
-               return USTCMD_ERR_GEN;
+       result = ustcmd_send_cmd("list_markers", pid, &big_str);
+       if (result != 1) {
+               return -1;
        }
 
-       if (big_str == NULL) {
-               fprintf(stderr, "ustcmd: error while getting markers list\n");
-               return USTCMD_ERR_GEN;
+       if (result != 1) {
+               ERR("error while getting markers list");
+               return -1;
        }
 
-       struct USTcmd_cmsf* tmp_cmsf = NULL;
-       tmp_cmsf = (struct USTcmd_cmsf*) malloc(sizeof(struct USTcmd_cmsf) *
+       tmp_cmsf = (struct marker_status *) malloc(sizeof(struct marker_status) *
                (ustcmd_count_nl(big_str) + 1));
        if (tmp_cmsf == NULL) {
-               return USTCMD_ERR_GEN;
+               return -1;
        }
 
        /* Parse received reply string (format: "[chan]/[mark] [st] [fs]"): */
-       unsigned int i = 0, cur_st, cmsf_ind = 0;
        while (big_str[i] != '\0') {
                char state;
-               sscanf(big_str + i, "%a[^/]/%a[^ ] %c %a[^\n]",
+
+               sscanf(big_str + i, "marker: %a[^/]/%a[^ ] %c %a[^\n]",
                        &tmp_cmsf[cmsf_ind].channel,
                        &tmp_cmsf[cmsf_ind].marker,
                        &state,
@@ -265,27 +421,90 @@ int ustcmd_get_cmsf(struct USTcmd_cmsf** cmsf, const pid_t pid) {
 }
 
 /**
- * Shoots a given command using ustcomm.
+ * Set socket path
+ *
+ * @param sock_path    Socket path
+ * @param pid          Traced process ID
+ * @return             0 if successful, or error
+ */
+int ustcmd_set_sock_path(const char *sock_path, pid_t pid)
+{
+       char *cmd;
+       int result;
+
+       asprintf(&cmd, "%s %s", "set_sock_path", sock_path);
+
+       result = ustcmd_send_cmd(cmd, pid, NULL);
+       if (result != 1) {
+               free(cmd);
+               return USTCMD_ERR_GEN;
+       }
+
+       free(cmd);
+       return 0;
+}
+
+/**
+ * Get socket path
+ *
+ * @param sock_path    Pointer to where the socket path will be returned
+ * @param pid          Traced process ID
+ * @return             0 if successful, or error
+ */
+int ustcmd_get_sock_path(char **sock_path, pid_t pid)
+{
+       char *cmd, *reply;
+       int result;
+
+       asprintf(&cmd, "%s", "get_sock_path");
+
+       result = ustcmd_send_cmd(cmd, pid, &reply);
+       if (result != 1) {
+               free(cmd);
+               free(reply);
+               return USTCMD_ERR_GEN;
+       }
+
+       free(cmd);
+       *sock_path = reply;
+       return 0;
+}
+
+int ustcmd_force_switch(pid_t pid)
+{
+       int result;
+
+       result = ustcmd_send_cmd("force_switch", pid, NULL);
+       if (result != 1) {
+               return USTCMD_ERR_GEN;
+       }
+
+       return 0;
+}
+
+/**
+ * Sends a given command to a traceable process
  *
- * @param cmd  Null-terminated command to shoot
+ * @param cmd  Null-terminated command to send
  * @param pid  Targeted PID
  * @param reply        Pointer to string to be filled with a reply string (must
  *             be NULL if no reply is needed for the given command).
- * @return     0 if successful, or errors {USTCMD_ERR_ARG, USTCMD_ERR_CONN}
+ * @return     -1 if successful, 0 on EOT, 1 on success
  */
-int ustcmd_shoot(const char* cmd, const pid_t pid, char** reply) {
-       if (cmd == NULL) {
-               return USTCMD_ERR_ARG;
-       }
 
+int ustcmd_send_cmd(const char *cmd, const pid_t pid, char **reply)
+{
        struct ustcomm_connection conn;
+       int retval;
+
        if (ustcomm_connect_app(pid, &conn)) {
-               fprintf(stderr, "ustcmd_shoot: could not connect to PID %u\n",
-                       (unsigned int) pid);
-               return USTCMD_ERR_CONN;
+               ERR("could not connect to PID %u", (unsigned int) pid);
+               return -1;
        }
 
-       ustcomm_send_request(&conn, cmd, reply);
+       retval = ustcomm_send_request(&conn, cmd, reply);
 
-       return 0;
+       ustcomm_close_app(&conn);
+
+       return retval;
 }
This page took 0.027743 seconds and 4 git commands to generate.