ifdef CONFIG_RBD
SOURCE += engines/rbd.c
endif
+SOURCE += oslib/asprintf.c
ifndef CONFIG_STRSEP
SOURCE += oslib/strsep.c
endif
fi
print_config "rdmacm" "$rdmacm"
+##########################################
+# asprintf() and vasprintf() probes
+if test "$have_asprintf" != "yes" ; then
+ have_asprintf="no"
+fi
+cat > $TMPC << EOF
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ return asprintf(NULL, "%s", "str") == 0;
+}
+EOF
+if compile_prog "" "" "have_asprintf"; then
+ have_asprintf="yes"
+fi
+print_config "asprintf()" "$have_asprintf"
+
+if test "$have_vasprintf" != "yes" ; then
+ have_vasprintf="no"
+fi
+cat > $TMPC << EOF
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ return vasprintf(NULL, "%s", NULL) == 0;
+}
+EOF
+if compile_prog "" "" "have_vasprintf"; then
+ have_vasprintf="yes"
+fi
+print_config "vasprintf()" "$have_vasprintf"
+
##########################################
# Linux fallocate probe
if test "$linux_fallocate" != "yes" ; then
if test "$posix_pshared" = "yes" ; then
output_sym "CONFIG_PSHARED"
fi
+if test "$have_asprintf" = "yes" ; then
+ output_sym "HAVE_ASPRINTF"
+fi
+if test "$have_vasprintf" = "yes" ; then
+ output_sym "HAVE_VASPRINTF"
+fi
if test "$linux_fallocate" = "yes" ; then
output_sym "CONFIG_LINUX_FALLOCATE"
fi
#include <syslog.h>
#include "fio.h"
-
-#define LOG_START_SZ 512
+#include "oslib/asprintf.h"
size_t log_info_buf(const char *buf, size_t len)
{
return fwrite(buf, len, 1, f_out);
}
-static size_t valist_to_buf(char **buffer, const char *fmt, va_list src_args)
-{
- size_t len, cur = LOG_START_SZ;
- va_list args;
-
- do {
- *buffer = calloc(1, cur);
- if (!*buffer)
- return 0;
-
- va_copy(args, src_args);
- len = vsnprintf(*buffer, cur, fmt, args);
- va_end(args);
-
- if (len < cur)
- break;
-
- cur = len + 1;
- free(*buffer);
- } while (1);
-
- return len;
-}
-
-/* allocate buffer, fill with prefix string followed by vararg string */
-static size_t prevalist_to_buf(char **buffer, const char *pre, int prelen,
- const char *fmt, va_list src_args)
-{
- size_t len, cur = LOG_START_SZ;
- va_list args;
-
- do {
- *buffer = calloc(1, cur);
- if (!*buffer)
- return 0;
-
- va_copy(args, src_args);
- memcpy(*buffer, pre, prelen);
- len = prelen + vsnprintf(*buffer + prelen, cur - prelen, fmt, args);
- va_end(args);
-
- if (len < cur)
- break;
-
- cur = len + 1;
- free(*buffer);
- } while (1);
-
- return len;
-}
-
size_t log_valist(const char *fmt, va_list args)
{
char *buffer;
- size_t len;
+ int len;
- len = valist_to_buf(&buffer, fmt, args);
+ len = vasprintf(&buffer, fmt, args);
+ if (len < 0)
+ return 0;
len = log_info_buf(buffer, len);
free(buffer);
/* add prefix for the specified type in front of the valist */
void log_prevalist(int type, const char *fmt, va_list args)
{
- char pre[32];
- char *buffer;
- size_t len;
- int prelen;
+ char *buf1, *buf2;
+ int len;
pid_t pid;
pid = gettid();
&& pid != *fio_debug_jobp)
return;
- prelen = snprintf(pre, sizeof pre, "%-8s %-5u ", debug_levels[type].name, (int) pid);
- if (prelen > 0) {
- len = prevalist_to_buf(&buffer, pre, prelen, fmt, args);
- len = log_info_buf(buffer, len);
- free(buffer);
- }
+ len = vasprintf(&buf1, fmt, args);
+ if (len < 0)
+ return;
+ len = asprintf(&buf2, "%-8s %-5u %s", debug_levels[type].name,
+ (int) pid, buf1);
+ free(buf1);
+ if (len < 0)
+ return;
+ len = log_info_buf(buf2, len);
+ free(buf2);
}
size_t log_info(const char *format, ...)
{
char *buffer;
va_list args;
- size_t len;
+ int len;
va_start(args, format);
- len = valist_to_buf(&buffer, format, args);
+ len = vasprintf(&buffer, format, args);
va_end(args);
-
+ if (len < 0)
+ return 0;
len = buf_output_add(buf, buffer, len);
free(buffer);
size_t log_err(const char *format, ...)
{
- size_t ret, len;
+ size_t ret;
+ int len;
char *buffer;
va_list args;
va_start(args, format);
- len = valist_to_buf(&buffer, format, args);
+ len = vasprintf(&buffer, format, args);
va_end(args);
+ if (len < 0)
+ return len;
if (is_backend) {
ret = fio_server_text_output(FIO_LOG_ERR, buffer, len);
--- /dev/null
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "oslib/asprintf.h"
+
+#ifndef HAVE_VASPRINTF
+int vasprintf(char **strp, const char *fmt, va_list ap)
+{
+ va_list ap_copy;
+ char *str;
+ int len;
+
+#ifdef va_copy
+ va_copy(ap_copy, ap);
+#else
+ __va_copy(ap_copy, ap);
+#endif
+ len = vsnprintf(NULL, 0, fmt, ap_copy);
+ va_end(ap_copy);
+
+ if (len < 0)
+ return len;
+
+ len++;
+ str = malloc(len);
+ *strp = str;
+ return str ? vsnprintf(str, len, fmt, ap) : -1;
+}
+#endif
+
+#ifndef HAVE_ASPRINTF
+int asprintf(char **strp, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start(arg, fmt);
+ done = vasprintf(strp, fmt, arg);
+ va_end(arg);
+
+ return done;
+}
+#endif
--- /dev/null
+#ifndef FIO_ASPRINTF_H
+#define FIO_ASPRINTF_H
+
+#ifndef HAVE_VASPRINTF
+int vasprintf(char **strp, const char *fmt, va_list ap);
+#endif
+#ifndef HAVE_ASPRINTF
+int asprintf(char **strp, const char *fmt, ...);
+#endif
+
+#endif /* FIO_ASPRINTF_H */
static void dump_buf(char *buf, unsigned int len, unsigned long long offset,
const char *type, struct fio_file *f)
{
- char *ptr, fname[DUMP_BUF_SZ];
- size_t buf_left = DUMP_BUF_SZ;
+ char *ptr, *fname;
+ char sep[2] = { FIO_OS_PATH_SEPARATOR, 0 };
int ret, fd;
ptr = strdup(f->file_name);
- memset(fname, 0, sizeof(fname));
- if (aux_path)
- sprintf(fname, "%s%c", aux_path, FIO_OS_PATH_SEPARATOR);
-
- strncpy(fname + strlen(fname), basename(ptr), buf_left - 1);
-
- buf_left -= strlen(fname);
- if (buf_left <= 0) {
+ if (asprintf(&fname, "%s%s%s.%llu.%s", aux_path ? : "",
+ aux_path ? sep : "", basename(ptr), offset, type) < 0) {
if (!fio_did_warn(FIO_WARN_VERIFY_BUF))
- log_err("fio: verify failure dump buffer too small\n");
- free(ptr);
- return;
+ log_err("fio: not enough memory for dump buffer filename\n");
+ goto free_ptr;
}
- snprintf(fname + strlen(fname), buf_left, ".%llu.%s", offset, type);
-
fd = open(fname, O_CREAT | O_TRUNC | O_WRONLY, 0644);
if (fd < 0) {
perror("open verify buf file");
- free(ptr);
- return;
+ goto free_fname;
}
while (len) {
close(fd);
log_err(" %s data dumped as %s\n", type, fname);
+
+free_fname:
+ free(fname);
+
+free_ptr:
free(ptr);
}