1,5 → 1,6 |
/* |
* Copyright (c) 2006 Josef Cejka |
* Copyright (c) 2008 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
34,41 → 35,35 |
|
#include <stdarg.h> |
#include <stdio.h> |
#include <unistd.h> |
#include <stdlib.h> |
#include <io/printf_core.h> |
#include <futex.h> |
#include <async.h> |
|
static atomic_t printf_futex = FUTEX_INITIALIZER; |
|
static int vprintf_write(const char *str, size_t count, void *unused) |
static int asprintf_prewrite(const char *str, size_t count, void *unused) |
{ |
return write_stdout(str, count); |
return count; |
} |
|
/** Print formatted text. |
* @param fmt format string |
* @param ap format parameters |
* \see For more details about format string see printf_core. |
*/ |
int vprintf(const char *fmt, va_list ap) |
int asprintf(char **strp, const char *fmt, ...) |
{ |
struct printf_spec ps = { |
(int (*)(void *, size_t, void *)) vprintf_write, |
asprintf_prewrite, |
NULL |
}; |
/* |
* Prevent other threads to execute printf_core() |
*/ |
futex_down(&printf_futex); |
/* |
* Prevent other pseudo threads of the same thread |
* to execute printf_core() |
*/ |
async_serialize_start(); |
int ret = printf_core(fmt, &ps, ap); |
async_serialize_end(); |
futex_up(&printf_futex); |
int ret; |
va_list args; |
|
va_start(args, fmt); |
ret = printf_core(fmt, &ps, args); |
va_end(args); |
if (ret > 0) { |
*strp = malloc(ret + 20); |
if (!*strp) |
return -1; |
va_start(args, fmt); |
vsprintf(*strp, fmt, args); |
va_end(args); |
} |
|
return ret; |
} |
|