X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=src%2Fcommon%2Futils.c;h=8ac143cb20f3779a9112009c5ca6dc795de109e7;hb=6826a68d673ed0a5b678453e0677db66c79fce0b;hp=4d49728c0f47a23cce6eba1bc2f72f11c2c14836;hpb=db5be0a3dcf30edeca9c3143682454bab9523f71;p=lttng-tools.git diff --git a/src/common/utils.c b/src/common/utils.c index 4d49728c0..8ac143cb2 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -37,10 +37,12 @@ #include #include #include +#include #include #include "utils.h" #include "defaults.h" +#include "time.h" /* * Return a partial realpath(3) of the path even if the full path does not @@ -528,7 +530,7 @@ int utils_create_lock_file(const char *filepath) S_IRGRP | S_IWGRP); if (fd < 0) { PERROR("open lock file %s", filepath); - ret = -1; + fd = -1; goto error; } @@ -1202,26 +1204,6 @@ end: return home_dir; } -/* - * Obtain the value of LTTNG_KMOD_PROBES environment variable, if exists. - * Otherwise returns NULL. - */ -LTTNG_HIDDEN -char *utils_get_kmod_probes_list(void) -{ - return lttng_secure_getenv(DEFAULT_LTTNG_KMOD_PROBES); -} - -/* - * Obtain the value of LTTNG_EXTRA_KMOD_PROBES environment variable, if - * exists. Otherwise returns NULL. - */ -LTTNG_HIDDEN -char *utils_get_extra_kmod_probes_list(void) -{ - return lttng_secure_getenv(DEFAULT_LTTNG_EXTRA_KMOD_PROBES); -} - /* * With the given format, fill dst with the time of len maximum siz. * @@ -1250,24 +1232,77 @@ size_t utils_get_current_time_str(const char *format, char *dst, size_t len) } /* - * Return the group ID matching name, else 0 if it cannot be found. + * Return 0 on success and set *gid to the group_ID matching the passed name. + * Else -1 if it cannot be found or an error occurred. */ LTTNG_HIDDEN -gid_t utils_get_group_id(const char *name) +int utils_get_group_id(const char *name, bool warn, gid_t *gid) { - struct group *grp; + static volatile int warn_once; + int ret; + long sys_len; + size_t len; + struct group grp; + struct group *result; + struct lttng_dynamic_buffer buffer; + + /* Get the system limit, if it exists. */ + sys_len = sysconf(_SC_GETGR_R_SIZE_MAX); + if (sys_len == -1) { + len = 1024; + } else { + len = (size_t) sys_len; + } + + lttng_dynamic_buffer_init(&buffer); + ret = lttng_dynamic_buffer_set_size(&buffer, len); + if (ret) { + ERR("Failed to allocate group info buffer"); + ret = -1; + goto error; + } - grp = getgrnam(name); - if (!grp) { - static volatile int warn_once; + while ((ret = getgrnam_r(name, &grp, buffer.data, buffer.size, &result)) == ERANGE) { + const size_t new_len = 2 * buffer.size; - if (!warn_once) { - WARN("No tracing group detected"); - warn_once = 1; + /* Buffer is not big enough, increase its size. */ + if (new_len < buffer.size) { + ERR("Group info buffer size overflow"); + ret = -1; + goto error; } - return 0; + + ret = lttng_dynamic_buffer_set_size(&buffer, new_len); + if (ret) { + ERR("Failed to grow group info buffer to %zu bytes", + new_len); + ret = -1; + goto error; + } + } + if (ret) { + PERROR("Failed to get group file entry for group name \"%s\"", + name); + ret = -1; + goto error; + } + + /* Group not found. */ + if (!result) { + ret = -1; + goto error; + } + + *gid = result->gr_gid; + ret = 0; + +error: + if (ret && warn && !warn_once) { + WARN("No tracing group detected"); + warn_once = 1; } - return grp->gr_gid; + lttng_dynamic_buffer_reset(&buffer); + return ret; } /* @@ -1402,15 +1437,17 @@ 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; } - ret = lseek(fd, length, SEEK_SET); - if (ret < 0) { + lseek_ret = lseek(fd, length, SEEK_SET); + if (lseek_ret < 0) { PERROR("lseek"); + ret = -1; goto end; } end: @@ -1429,11 +1466,17 @@ static const char *get_man_bin_path(void) } LTTNG_HIDDEN -int utils_show_man_page(int section, const char *page_name) +int utils_show_help(int section, const char *page_name, + const char *help_msg) { char section_string[8]; const char *man_bin_path = get_man_bin_path(); - int ret; + int ret = 0; + + if (help_msg) { + printf("%s", help_msg); + goto end; + } /* Section integer -> section string */ ret = sprintf(section_string, "%d", section); @@ -1448,5 +1491,42 @@ int utils_show_man_page(int section, const char *page_name) */ ret = execlp(man_bin_path, "man", "-M", MANPATH, section_string, page_name, NULL); + +end: 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; +}