+#define _GNU_SOURCE
+#include <stdio.h>
#include <unistd.h>
#include <getopt.h>
#include <stdlib.h>
-#include <stdio.h>
#include <fcntl.h>
#include "ustcomm.h"
-void parse_opts(int argc, char **argv)
+struct ust_opts {
+ char *cmd;
+ pid_t *pids;
+ int take_reply;
+};
+
+char *progname = NULL;
+
+void usage(void)
{
- int flags, opt;
- int nsecs, tfnd;
-
- nsecs = 0;
- tfnd = 0;
- flags = 0;
- while ((opt = getopt(argc, argv, "nt:")) != -1) {
- switch (opt) {
- case 'n':
- flags = 1;
- break;
- case 't':
- nsecs = atoi(optarg);
- tfnd = 1;
- break;
- default: /* '?' */
- fprintf(stderr, "Usage: %s [-t nsecs] [-n] name\n",
- argv[0]);
- exit(EXIT_FAILURE);
+ fprintf(stderr, "usage: %s [OPTIONS] COMMAND PID...\n", progname);
+ fprintf(stderr, "\nControl the tracing of a process that supports LTTng Userspace Tracing.\n\
+\n\
+Commands:\n\
+ --start-trace\t\t\tStart tracing\n\
+ --stop-trace\t\t\tStop tracing\n\
+ --destroy-trace\t\t\tDestroy the trace\n\
+ --enable-marker CHANNEL/MARKER\tEnable a marker\n\
+ --disable-marker CHANNEL/MARKER\tDisable a marker\n\
+ --list-markers\tList the markers of the process and their state\n\
+\n\
+");
+}
+
+int parse_opts_long(int argc, char **argv, struct ust_opts *opts)
+{
+ int c;
+ int digit_optind = 0;
+
+ opts->cmd = NULL;
+ opts->pids = NULL;
+ opts->take_reply = 0;
+
+ while (1) {
+ int this_option_optind = optind ? optind : 1;
+ int option_index = 0;
+ static struct option long_options[] = {
+ {"start-trace", 0, 0, 1000},
+ {"stop-trace", 0, 0, 1001},
+ {"destroy-trace", 0, 0, 1002},
+ {"list-markers", 0, 0, 1004},
+ {"print-markers", 0, 0, 1005},
+ {"pid", 1, 0, 1006},
+ {"enable-marker", 1, 0, 1007},
+ {"disable-marker", 1, 0, 1008},
+ {"start", 0, 0, 1009},
+ {"help", 0, 0, 'h'},
+ {"version", 0, 0, 1010},
+ {0, 0, 0, 0}
+ };
+
+ c = getopt_long(argc, argv, "h", long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 0:
+ printf("option %s", long_options[option_index].name);
+ if (optarg)
+ printf(" with arg %s", optarg);
+ printf("\n");
+ break;
+
+ case 1000:
+ opts->cmd = strdup("trace_start");
+ break;
+ case 1001:
+ opts->cmd = strdup("trace_stop");
+ break;
+ case 1009:
+ opts->cmd = strdup("start");
+ break;
+ case 1002:
+ opts->cmd = strdup("trace_destroy");
+ break;
+ case 1004:
+ opts->cmd = strdup("list_markers");
+ opts->take_reply = 1;
+ break;
+ case 1007:
+ asprintf(&opts->cmd, "enable_marker %s", optarg);
+ break;
+ case 1008:
+ asprintf(&opts->cmd, "disable_marker %s", optarg);
+ break;
+ case 'h':
+ usage();
+ exit(0);
+ case 1010:
+ printf("Version 0\n");
+
+ default:
+ /* unknown option or other error; error is printed by getopt, just return */
+ return 1;
}
}
- printf("flags=%d; tfnd=%d; optind=%d\n", flags, tfnd, optind);
+ if(argc - optind > 0) {
+ int i;
+ int pididx=0;
+ opts->pids = malloc((argc-optind+1) * sizeof(pid_t));
- if (optind >= argc) {
- fprintf(stderr, "Expected argument after options\n");
+ for(i=optind; i<argc; i++) {
+ opts->pids[pididx++] = atoi(argv[i]);
+ }
+ opts->pids[pididx] = -1;
+ }
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ pid_t *pidit;
+ //char *msg = argv[2];
+ struct ustcomm_connection conn;
+ int result;
+ struct ust_opts opts;
+
+ progname = argv[0];
+
+ if(argc <= 1) {
+ fprintf(stderr, "No operation specified.\n");
+ usage();
exit(EXIT_FAILURE);
}
- printf("name argument = %s\n", argv[optind]);
+ result = parse_opts_long(argc, argv, &opts);
+ if(result) {
+ usage();
+ exit(EXIT_FAILURE);
+ }
- /* Other code omitted */
+ if(opts.pids == NULL) {
+ fprintf(stderr, "No pid specified.\n");
+ usage();
+ exit(EXIT_FAILURE);
+ }
+ if(opts.cmd == NULL) {
+ fprintf(stderr, "No command specified.\n");
+ usage();
+ exit(EXIT_FAILURE);
+ }
- exit(EXIT_SUCCESS);
+ pidit = opts.pids;
-}
+ while(*pidit != -1) {
+ char *reply;
+ char **preply;
-int main(int argc, char *argv[])
-{
- pid_t pid = atoi(argv[1]);
+ if(opts.take_reply)
+ preply = &reply;
+ else
+ preply = NULL;
- char *msg = argv[2];
+ result = ustcomm_connect_app(*pidit, &conn);
+ if(result) {
+ fprintf(stderr, "error connecting to process\n");
+ exit(EXIT_FAILURE);
+ }
+ ustcomm_send_request(&conn, opts.cmd, preply);
- struct ustcomm_connection conn;
+ if(opts.take_reply)
+ printf("%s", reply);
+ pidit++;
+ }
- ustcomm_connect_app(pid, &conn);
- ustcomm_send_request(&conn, msg, NULL);
+ free(opts.pids);
+ free(opts.cmd);
return 0;
}