X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Futils.c;h=f3718f00fa8ddabb7c921ac55287626dd83f45b8;hp=b16cdc97c2738ad70c23624fc91295c3317b1a66;hb=70d0b120691e90d81de7b38af8b845e261b5b40c;hpb=0f907de1f20c91a2bd1a08ee4d50332d1958754b diff --git a/src/common/utils.c b/src/common/utils.c index b16cdc97c..f3718f00f 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -309,10 +310,11 @@ error: * * Return 0 on success or else a negative value. */ +LTTNG_HIDDEN int utils_create_stream_file(char *path_name, char *file_name, uint64_t size, uint64_t count, int uid, int gid) { - int ret, out_fd; + int ret, out_fd, flags, mode; char full_path[PATH_MAX], *path_name_id = NULL, *path; assert(path_name); @@ -340,9 +342,15 @@ int utils_create_stream_file(char *path_name, char *file_name, uint64_t size, path = full_path; } + flags = O_WRONLY | O_CREAT | O_TRUNC; /* Open with 660 mode */ - out_fd = run_as_open(path, O_WRONLY | O_CREAT | O_TRUNC, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, uid, gid); + mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; + + if (uid < 0 || gid < 0) { + out_fd = open(path, flags, mode); + } else { + out_fd = run_as_open(path, flags, mode, uid, gid); + } if (out_fd < 0) { PERROR("open stream path %s", path); goto error_open; @@ -364,6 +372,7 @@ error: * * Return 0 on success or else a negative value. */ +LTTNG_HIDDEN int utils_rotate_stream_file(char *path_name, char *file_name, uint64_t size, uint64_t count, int uid, int gid, int out_fd, uint64_t *new_count) { @@ -386,3 +395,126 @@ int utils_rotate_stream_file(char *path_name, char *file_name, uint64_t size, error: return ret; } + +/** + * Prints the error message corresponding to a regex error code. + * + * @param errcode The error code. + * @param regex The regex object that produced the error code. + */ +static void regex_print_error(int errcode, regex_t *regex) +{ + /* Get length of error message and allocate accordingly */ + size_t length; + char *buffer; + + assert(regex != NULL); + + length = regerror(errcode, regex, NULL, 0); + if (length == 0) { + ERR("regerror returned a length of 0"); + return; + } + + buffer = zmalloc(length); + if (!buffer) { + ERR("regex_print_error: zmalloc failed"); + return; + } + + /* Get and print error message */ + regerror(errcode, regex, buffer, length); + ERR("regex error: %s\n", buffer); + free(buffer); + +} + +/** + * Parse a string that represents a size in human readable format. It + * supports decimal integers suffixed by 'k', 'M' or 'G'. + * + * The suffix multiply the integer by: + * 'k': 1024 + * 'M': 1024^2 + * 'G': 1024^3 + * + * @param str The string to parse. + * @param size Pointer to a size_t that will be filled with the + * resulting size. + * + * @return 0 on success, -1 on failure. + */ +int utils_parse_size_suffix(char *str, uint64_t *size) +{ + regex_t regex; + int ret; + const int nmatch = 3; + regmatch_t suffix_match, matches[nmatch]; + unsigned long long base_size; + long shift = 0; + + if (!str) { + return 0; + } + + /* Compile regex */ + ret = regcomp(®ex, "^\\(0x\\)\\{0,1\\}[0-9][0-9]*\\([kKMG]\\{0,1\\}\\)$", 0); + if (ret != 0) { + regex_print_error(ret, ®ex); + ret = -1; + goto end; + } + + /* Match regex */ + ret = regexec(®ex, str, nmatch, matches, 0); + if (ret != 0) { + ret = -1; + goto free; + } + + /* There is a match ! */ + errno = 0; + base_size = strtoull(str, NULL, 0); + if (errno != 0) { + PERROR("strtoull"); + ret = -1; + goto free; + } + + /* Check if there is a suffix */ + suffix_match = matches[2]; + if (suffix_match.rm_eo - suffix_match.rm_so == 1) { + switch (*(str + suffix_match.rm_so)) { + case 'K': + case 'k': + shift = KIBI_LOG2; + break; + case 'M': + shift = MEBI_LOG2; + break; + case 'G': + shift = GIBI_LOG2; + break; + default: + ERR("parse_human_size: invalid suffix"); + ret = -1; + goto free; + } + } + + *size = base_size << shift; + + /* Check for overflow */ + if ((*size >> shift) != base_size) { + ERR("parse_size_suffix: oops, overflow detected."); + ret = -1; + goto free; + } + + ret = 0; + +free: + regfree(®ex); +end: + return ret; +}