X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=ust%2Fust.c;h=d05674535dfbd5d4c9ecf3fdc0b5cb807ee4842d;hb=6d45c11a63ffac29844304c53dffb76976ec98c1;hp=ab5b5360a40ab5f81cc918c7f7d16d1c741cef55;hpb=ae93765676ecc0a41945151427a8afb9910954e6;p=lttng-ust.git diff --git a/ust/ust.c b/ust/ust.c index ab5b5360..d0567453 100644 --- a/ust/ust.c +++ b/ust/ust.c @@ -21,9 +21,11 @@ #include #include #include +#include #include "ustcomm.h" #include "ustcmd.h" +#include "usterr.h" enum command { START_TRACE, @@ -35,12 +37,14 @@ enum command { DISABLE_MARKER, GET_ONLINE_PIDS, UNKNOWN -}; +}; struct ust_opts { enum command cmd; pid_t *pids; - char* m_name; + char *regex; + regex_t preg; + int regex_state; }; char *progname = NULL; @@ -66,7 +70,8 @@ int parse_opts_long(int argc, char **argv, struct ust_opts *opts) int c; opts->pids = NULL; - opts->m_name = NULL; + opts->regex = NULL; + opts->regex_state = -1; while (1) { int option_index = 0; @@ -115,11 +120,11 @@ int parse_opts_long(int argc, char **argv, struct ust_opts *opts) break; case 1007: opts->cmd = ENABLE_MARKER; - opts->m_name = strdup(optarg); + opts->regex = strdup(optarg); break; case 1008: opts->cmd = DISABLE_MARKER; - opts->m_name = strdup(optarg); + opts->regex = strdup(optarg); break; case 1011: opts->cmd = GET_ONLINE_PIDS; @@ -138,25 +143,78 @@ int parse_opts_long(int argc, char **argv, struct ust_opts *opts) } } - if(argc - optind > 0 && opts->cmd != GET_ONLINE_PIDS) { + if (argc - optind > 0 && opts->cmd != GET_ONLINE_PIDS) { int i; int pididx=0; opts->pids = malloc((argc-optind+1) * sizeof(pid_t)); for(i=optind; ipids[pididx++] = atoi(argv[i]); + /* don't take any chances, use a long long */ + long long tmp; + char *endptr; + tmp = strtoull(argv[i], &endptr, 10); + if(*endptr != '\0') { + ERR("The pid \"%s\" is invalid.", argv[i]); + return 1; + } + opts->pids[pididx++] = (pid_t) tmp; } opts->pids[pididx] = -1; } + if (opts->cmd == ENABLE_MARKER || opts->cmd == DISABLE_MARKER) { + opts->regex_state = regcomp(&opts->preg, opts->regex, 0); + if (opts->regex_state) { + ERR("invalid regular expression\n"); + } + } + return 0; } +static void regex_change_m_state(struct ust_opts *opts, pid_t pid) +{ + struct marker_status *cmsf = NULL; + unsigned int i = 0; + int e = (opts->cmd == ENABLE_MARKER); + + if (opts->regex_state != 0) { + return; + } + + if (ustcmd_get_cmsf(&cmsf, pid)) { + fprintf(stderr, "error while trying to get markers for PID " + "%u\n", (unsigned int) pid); + return; + } + while (cmsf[i].channel != NULL) { + char *mc; + asprintf(&mc, "%s/%s", cmsf[i].channel, cmsf[i].marker); + if (regexec(&opts->preg, mc, 0, NULL, 0) == 0) { + /* We got a match! */ + if (ustcmd_set_marker_state(mc, + e ? USTCMD_MS_ON : USTCMD_MS_OFF, pid)) { + fprintf(stderr, + "error while trying to %sable marker" + "\"%s\" for PID %u\n", + e ? "en" : "dis", mc, + (unsigned int) pid); + } else { + printf("sucessfully %sabled marker " + "\"%s\" for PID %u\n", + e ? "en" : "dis", mc, + (unsigned int) pid); + } + } + free(mc); + ++i; + } + ustcmd_free_cmsf(cmsf); +} + int main(int argc, char *argv[]) { pid_t *pidit; - //char *msg = argv[2]; - struct ustcomm_connection conn; int result; struct ust_opts opts; @@ -170,6 +228,7 @@ int main(int argc, char *argv[]) result = parse_opts_long(argc, argv, &opts); if(result) { + fprintf(stderr, "\n"); usage(); exit(EXIT_FAILURE); } @@ -184,9 +243,8 @@ int main(int argc, char *argv[]) usage(); exit(EXIT_FAILURE); } - if (opts.cmd == GET_ONLINE_PIDS) { - pid_t* pp = ustcmd_get_online_pids(); + pid_t *pp = ustcmd_get_online_pids(); unsigned int i = 0; if (pp) { @@ -196,123 +254,91 @@ int main(int argc, char *argv[]) } free(pp); } - + exit(EXIT_SUCCESS); } pidit = opts.pids; - struct USTcmd_cmsf* cmsf = NULL; - + struct marker_status *cmsf = NULL; + while(*pidit != -1) { switch (opts.cmd) { case START_TRACE: - if (ustcmd_start_trace(*pidit)) { - fprintf(stderr, - "error while trying to for trace " - "with PID %u\n", (unsigned int) *pidit); + result = ustcmd_start_trace(*pidit); + if (result) { + ERR("error while trying to for trace with PID %u\n", (unsigned int) *pidit); + break; + } + //printf("sucessfully started trace for PID %u\n", (unsigned int) *pidit); break; - } - printf("sucessfully started trace for PID %u\n", - (unsigned int) *pidit); - break; - + case STOP_TRACE: - if (ustcmd_stop_trace(*pidit)) { - fprintf(stderr, - "error while trying to stop trace " - "for PID %u\n", (unsigned int) *pidit); + result = ustcmd_stop_trace(*pidit); + if (result) { + ERR("error while trying to stop trace for PID %u\n", (unsigned int) *pidit); + break; + } + //printf("sucessfully stopped trace for PID %u\n", (unsigned int) *pidit); break; - } - printf("sucessfully stopped trace for PID %u\n", - (unsigned int) *pidit); - break; - + case START: - if (ustcmd_setup_and_start(*pidit)) { - fprintf(stderr, - "error while trying to setup/start " - "trace for PID %u\n", - (unsigned int) *pidit); + result = ustcmd_setup_and_start(*pidit); + if (result) { + ERR("error while trying to setup/start trace for PID %u\n", (unsigned int) *pidit); + break; + } + //printf("sucessfully setup/started trace for PID %u\n", (unsigned int) *pidit); break; - } - printf("sucessfully setup/started trace for PID %u\n", - (unsigned int) *pidit); - break; - + case DESTROY: - if (ustcmd_destroy_trace(*pidit)) { - fprintf(stderr, - "error while trying to destroy " - "trace with PID %u\n", - (unsigned int) *pidit); + result = ustcmd_destroy_trace(*pidit); + if (result) { + ERR("error while trying to destroy trace with PID %u\n", (unsigned int) *pidit); + break; + } + //printf("sucessfully destroyed trace for PID %u\n", (unsigned int) *pidit); break; - } - printf("sucessfully destroyed trace for PID %u\n", - (unsigned int) *pidit); - break; - + case LIST_MARKERS: - cmsf = NULL; - if (ustcmd_get_cmsf(&cmsf, *pidit)) { - fprintf(stderr, - "error while trying to list markers for" - " PID %u\n", (unsigned int) *pidit); + cmsf = NULL; + if (ustcmd_get_cmsf(&cmsf, *pidit)) { + fprintf(stderr, + "error while trying to list markers for" + " PID %u\n", (unsigned int) *pidit); + break; + } + unsigned int i = 0; + while (cmsf[i].channel != NULL) { + printf("{PID: %u, channel/marker: %s/%s, " + "state: %u, fs: %s}\n", + (unsigned int) *pidit, + cmsf[i].channel, + cmsf[i].marker, + cmsf[i].state, + cmsf[i].fs); + ++i; + } + ustcmd_free_cmsf(cmsf); break; - } - unsigned int i = 0; - while (cmsf[i].channel != NULL) { - printf("{PID: %u, channel/marker: %s/%s, " - "state: %u, fs: %s}\n", - (unsigned int) *pidit, - cmsf[i].channel, - cmsf[i].marker, - cmsf[i].state, - cmsf[i].fs); - ++i; - } - ustcmd_free_cmsf(cmsf); - break; - + case ENABLE_MARKER: - if (ustcmd_set_marker_state(opts.m_name, USTCMD_MS_ON, - *pidit)) { - - fprintf(stderr, - "error while trying to enable marker" - "\"%s\" for PID %u\n", - opts.m_name, - (unsigned int) *pidit); - break; - } - printf("sucessfully enabled marker \"%s\" for PID %u\n", - opts.m_name, (unsigned int) *pidit); - break; - case DISABLE_MARKER: - if (ustcmd_set_marker_state(opts.m_name, USTCMD_MS_OFF, - *pidit)) { - fprintf(stderr, - "error while trying to disable marker" - "\"%s\" for PID %u\n", - opts.m_name, - (unsigned int) *pidit); - break; - } - printf("sucessfully disabled marker \"%s\" for PID %u\n", - opts.m_name, (unsigned int) *pidit); + regex_change_m_state(&opts, *pidit); break; - + default: - fprintf(stderr, "error: unknown command...\n"); + ERR("unknown command\n"); break; } - + pidit++; } - free(opts.pids); - if (opts.m_name != NULL) { - free(opts.m_name); + if (opts.pids != NULL) { + free(opts.pids); + } + if (opts.regex != NULL) { + free(opts.regex); } return 0;