X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=converter%2Fbabeltrace.c;h=539734eeaa55df4e3ba23019f8cbe5d9560fef51;hp=a7004e1b1e60a21e1531d463f98380afe5dfe7b2;hb=20d24215ef299a387abac4850f82359de8a86f4d;hpb=e669e45e7fdff6b855907cde40524ebf4cc8a3bc diff --git a/converter/babeltrace.c b/converter/babeltrace.c index a7004e1b..539734ee 100644 --- a/converter/babeltrace.c +++ b/converter/babeltrace.c @@ -18,7 +18,7 @@ * all copies or substantial portions of the Software. */ -#define _XOPEN_SOURCE 700 +#define _GNU_SOURCE #include #include #include @@ -33,10 +33,9 @@ #include #include #include -#include -#include #include #include +#include #include /* for clocks */ @@ -71,6 +70,7 @@ enum { OPT_CLOCK_SECONDS, OPT_CLOCK_DATE, OPT_CLOCK_GMT, + OPT_CLOCK_FORCE_CORRELATE, }; static struct poptOption long_options[] = { @@ -89,6 +89,7 @@ static struct poptOption long_options[] = { { "clock-seconds", 0, POPT_ARG_NONE, NULL, OPT_CLOCK_SECONDS, NULL, NULL }, { "clock-date", 0, POPT_ARG_NONE, NULL, OPT_CLOCK_DATE, NULL, NULL }, { "clock-gmt", 0, POPT_ARG_NONE, NULL, OPT_CLOCK_GMT, NULL, NULL }, + { "clock-force-correlate", 0, POPT_ARG_NONE, NULL, OPT_CLOCK_FORCE_CORRELATE, NULL, NULL }, { NULL, 0, 0, NULL, 0, NULL, NULL }, }; @@ -129,6 +130,8 @@ static void usage(FILE *fp) fprintf(fp, " (default is: [hh:mm:ss.ns])\n"); fprintf(fp, " --clock-date Print clock date\n"); fprintf(fp, " --clock-gmt Print clock in GMT time zone (default: local time zone)\n"); + fprintf(fp, " --clock-force-correlate Assume that clocks are inherently correlated\n"); + fprintf(fp, " across traces.\n"); list_formats(fp); fprintf(fp, "\n"); } @@ -274,6 +277,9 @@ static int parse_options(int argc, char **argv) case OPT_CLOCK_GMT: opt_clock_gmt = 1; break; + case OPT_CLOCK_FORCE_CORRELATE: + opt_clock_force_correlate = 1; + break; default: ret = -EINVAL; @@ -296,6 +302,94 @@ end: } +/* + * bt_context_add_traces_recursive: Open a trace recursively + * + * Find each trace present in the subdirectory starting from the given + * path, and add them to the context. + * + * Return: 0 on success, nonzero on failure. + * Unable to open toplevel: failure. + * Unable to open some subdirectory or file: warn and continue; + */ +int bt_context_add_traces_recursive(struct bt_context *ctx, const char *path, + const char *format_str) +{ + FTS *tree; + FTSENT *node; + GArray *trace_ids; + char lpath[PATH_MAX]; + char * const paths[2] = { lpath, NULL }; + int ret; + + /* + * Need to copy path, because fts_open can change it. + * It is the pointer array, not the strings, that are constant. + */ + strncpy(lpath, path, PATH_MAX); + lpath[PATH_MAX - 1] = '\0'; + + tree = fts_open(paths, FTS_NOCHDIR | FTS_LOGICAL, 0); + if (tree == NULL) { + fprintf(stderr, "[error] [Context] Cannot traverse \"%s\" for reading.\n", + path); + return -EINVAL; + } + + trace_ids = g_array_new(FALSE, TRUE, sizeof(int)); + + while ((node = fts_read(tree))) { + int dirfd, metafd; + + if (!(node->fts_info & FTS_D)) + continue; + + dirfd = open(node->fts_accpath, 0); + if (dirfd < 0) { + fprintf(stderr, "[error] [Context] Unable to open trace " + "directory file descriptor.\n"); + ret = dirfd; + goto error; + } + metafd = openat(dirfd, "metadata", O_RDONLY); + if (metafd < 0) { + ret = close(dirfd); + if (ret < 0) { + perror("close"); + goto error; + } + } else { + int trace_id; + + ret = close(metafd); + if (ret < 0) { + perror("close"); + goto error; + } + ret = close(dirfd); + if (ret < 0) { + perror("close"); + goto error; + } + + trace_id = bt_context_add_trace(ctx, + node->fts_accpath, format_str); + if (trace_id < 0) { + fprintf(stderr, "[error] [Context] opening trace \"%s\" from %s " + "for reading.\n", node->fts_accpath, path); + ret = trace_id; + goto error; + } + g_array_append_val(trace_ids, trace_id); + } + } + + g_array_free(trace_ids, TRUE); + return 0; + +error: + return ret; +}