HelenOS sources
This source file includes following definitions.
- __kio_init
- __kio_fini
- kio_write
- kio_update
- kio_command
- kio_printf
- kio_vprintf_str_write
- kio_vprintf_wstr_write
- kio_vprintf
#include <stddef.h>
#include <libc.h>
#include <str.h>
#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include <abi/kio.h>
#include <io/kio.h>
#include <printf_core.h>
#include <macros.h>
#include <libarch/config.h>
#include "../private/futex.h"
#define KIO_BUFFER_SIZE PAGE_SIZE
static struct {
futex_t futex;
char data[KIO_BUFFER_SIZE];
size_t used;
} kio_buffer;
void __kio_init(void)
{
if (futex_initialize(&kio_buffer.futex, 1) != EOK)
abort();
}
void __kio_fini(void)
{
futex_destroy(&kio_buffer.futex);
}
errno_t kio_write(const void *buf, size_t size, size_t *nwritten)
{
futex_down(&kio_buffer.futex);
const char *s = buf;
while (true) {
const char *endl = memchr(s, '\n', size);
if (endl) {
size_t used = kio_buffer.used;
size_t sz = min(KIO_BUFFER_SIZE - used, (size_t) (endl - s));
memcpy(&kio_buffer.data[used], s, sz);
__SYSCALL3(SYS_KIO, KIO_WRITE,
(sysarg_t) &kio_buffer.data[0], used + sz);
kio_buffer.used = 0;
size -= endl + 1 - s;
s = endl + 1;
} else {
size_t used = kio_buffer.used;
size_t sz = min(KIO_BUFFER_SIZE - used, size);
memcpy(&kio_buffer.data[used], s, sz);
kio_buffer.used += sz;
break;
}
}
futex_up(&kio_buffer.futex);
if (nwritten)
*nwritten = size;
return EOK;
}
void kio_update(void)
{
(void) __SYSCALL3(SYS_KIO, KIO_UPDATE, (uintptr_t) NULL, 0);
}
void kio_command(const void *buf, size_t size)
{
(void) __SYSCALL3(SYS_KIO, KIO_COMMAND, (sysarg_t) buf, (sysarg_t) size);
}
int kio_printf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
int ret = kio_vprintf(fmt, args);
va_end(args);
return ret;
}
static int kio_vprintf_str_write(const char *str, size_t size, void *data)
{
size_t wr;
wr = 0;
(void) kio_write(str, size, &wr);
return str_nlength(str, wr);
}
static int kio_vprintf_wstr_write(const char32_t *str, size_t size, void *data)
{
size_t offset = 0;
size_t chars = 0;
size_t wr;
while (offset < size) {
char buf[STR_BOUNDS(1)];
size_t sz = 0;
if (chr_encode(str[chars], buf, &sz, STR_BOUNDS(1)) == EOK)
kio_write(buf, sz, &wr);
chars++;
offset += sizeof(char32_t);
}
return chars;
}
int kio_vprintf(const char *fmt, va_list ap)
{
printf_spec_t ps = {
kio_vprintf_str_write,
kio_vprintf_wstr_write,
NULL
};
return printf_core(fmt, &ps, ap);
}
HelenOS homepage, sources at GitHub