#include "utils.h"
#include "defaults.h"
+#include "time.h"
/*
* Return a partial realpath(3) of the path even if the full path does not
error:
free(resolved_path);
free(cut_path);
+ free(try_path);
+ if (try_path_prev != try_path) {
+ free(try_path_prev);
+ }
return NULL;
}
S_IRGRP | S_IWGRP);
if (fd < 0) {
PERROR("open lock file %s", filepath);
- ret = -1;
+ fd = -1;
goto error;
}
{
int ret;
- assert(new_count);
assert(stream_fd);
ret = close(out_fd);
PERROR("Closing tracefile");
goto error;
}
+ *stream_fd = -1;
if (count > 0) {
/*
* Unlinking the old file rather than overwriting it
* achieves this.
*/
- *new_count = (*new_count + 1) % count;
- ret = utils_unlink_stream_file(path_name, file_name,
- size, *new_count, uid, gid, 0);
+ if (new_count) {
+ *new_count = (*new_count + 1) % count;
+ }
+ ret = utils_unlink_stream_file(path_name, file_name, size,
+ new_count ? *new_count : 0, uid, gid, 0);
if (ret < 0 && errno != ENOENT) {
goto error;
}
} else {
- (*new_count)++;
+ if (new_count) {
+ (*new_count)++;
+ }
}
- ret = utils_create_stream_file(path_name, file_name, size, *new_count,
- uid, gid, 0);
+ ret = utils_create_stream_file(path_name, file_name, size,
+ new_count ? *new_count : 0, uid, gid, 0);
if (ret < 0) {
goto error;
}
}
return ret;
}
+
+LTTNG_HIDDEN
+int utils_truncate_stream_file(int fd, off_t length)
+{
+ int ret;
+ off_t lseek_ret;
+
+ ret = ftruncate(fd, length);
+ if (ret < 0) {
+ PERROR("ftruncate");
+ goto end;
+ }
+ lseek_ret = lseek(fd, length, SEEK_SET);
+ if (lseek_ret < 0) {
+ PERROR("lseek");
+ ret = -1;
+ goto end;
+ }
+end:
+ return ret;
+}
+
+static const char *get_man_bin_path(void)
+{
+ char *env_man_path = lttng_secure_getenv(DEFAULT_MAN_BIN_PATH_ENV);
+
+ if (env_man_path) {
+ return env_man_path;
+ }
+
+ return DEFAULT_MAN_BIN_PATH;
+}
+
+LTTNG_HIDDEN
+int utils_show_man_page(int section, const char *page_name)
+{
+ char section_string[8];
+ const char *man_bin_path = get_man_bin_path();
+ int ret;
+
+ /* Section integer -> section string */
+ ret = sprintf(section_string, "%d", section);
+ assert(ret > 0 && ret < 8);
+
+ /*
+ * Execute man pager.
+ *
+ * We provide -M to man here because LTTng-tools can
+ * be installed outside /usr, in which case its man pages are
+ * not located in the default /usr/share/man directory.
+ */
+ ret = execlp(man_bin_path, "man", "-M", MANPATH,
+ section_string, page_name, NULL);
+ return ret;
+}
+
+LTTNG_HIDDEN
+int timespec_to_ms(struct timespec ts, unsigned long *ms)
+{
+ unsigned long res, remain_ms;
+
+ if (ts.tv_sec > ULONG_MAX / MSEC_PER_SEC) {
+ errno = EOVERFLOW;
+ return -1; /* multiplication overflow */
+ }
+ res = ts.tv_sec * MSEC_PER_SEC;
+ remain_ms = ULONG_MAX - res;
+ if (ts.tv_nsec / NSEC_PER_MSEC > remain_ms) {
+ errno = EOVERFLOW;
+ return -1; /* addition overflow */
+ }
+ res += ts.tv_nsec / NSEC_PER_MSEC;
+ *ms = res;
+ return 0;
+}
+
+LTTNG_HIDDEN
+struct timespec timespec_abs_diff(struct timespec t1, struct timespec t2)
+{
+ uint64_t ts1 = (uint64_t) t1.tv_sec * (uint64_t) NSEC_PER_SEC +
+ (uint64_t) t1.tv_nsec;
+ uint64_t ts2 = (uint64_t) t2.tv_sec * (uint64_t) NSEC_PER_SEC +
+ (uint64_t) t2.tv_nsec;
+ uint64_t diff = max(ts1, ts2) - min(ts1, ts2);
+ struct timespec res;
+
+ res.tv_sec = diff / (uint64_t) NSEC_PER_SEC;
+ res.tv_nsec = diff % (uint64_t) NSEC_PER_SEC;
+ return res;
+}