HelenOS sources
This source file includes following definitions.
- producer
- consumer
- kio_notification_handler
- main
#include <_bits/decls.h>
#include <libarch/config.h>
#include <stdio.h>
#include <async.h>
#include <as.h>
#include <ddi.h>
#include <errno.h>
#include <str_error.h>
#include <io/kio.h>
#include <sysinfo.h>
#include <stdlib.h>
#include <fibril_synch.h>
#include <adt/list.h>
#include <adt/prodcons.h>
#include <tinput.h>
#include <uchar.h>
#include <vfs/vfs.h>
#define NAME "kio"
#define LOG_FNAME "/log/kio"
typedef struct {
link_t link;
size_t bytes;
char *data;
} item_t;
static prodcons_t pc;
static FIBRIL_MUTEX_INITIALIZE(mtx);
#define READ_BUFFER_SIZE PAGE_SIZE
static size_t current_at;
static char read_buffer[READ_BUFFER_SIZE];
static void producer(size_t bytes, char *data)
{
item_t *item = malloc(sizeof(item_t));
if (item == NULL)
return;
item->bytes = bytes;
item->data = malloc(bytes);
if (!item->data) {
free(item);
return;
}
memcpy(item->data, data, bytes);
link_initialize(&item->link);
prodcons_produce(&pc, &item->link);
}
static errno_t consumer(void *data)
{
FILE *log = fopen(LOG_FNAME, "a");
if (log == NULL)
printf("%s: Unable to create log file %s (%s)\n", NAME, LOG_FNAME,
str_error(errno));
while (true) {
link_t *link = prodcons_consume(&pc);
item_t *item = list_get_instance(link, item_t, link);
fwrite(item->data, 1, item->bytes, stdout);
if (log) {
fwrite(item->data, 1, item->bytes, log);
fflush(log);
vfs_sync(fileno(log));
}
free(item->data);
free(item);
}
fclose(log);
return EOK;
}
static void kio_notification_handler(ipc_call_t *call, void *arg)
{
size_t kio_written = (size_t) ipc_get_arg1(call);
fibril_mutex_lock(&mtx);
while (current_at != kio_written) {
size_t read = kio_read(read_buffer, READ_BUFFER_SIZE, current_at);
if (read == 0)
break;
current_at += read;
if (read > READ_BUFFER_SIZE) {
read = READ_BUFFER_SIZE;
}
producer(read, read_buffer);
}
async_event_unmask(EVENT_KIO);
fibril_mutex_unlock(&mtx);
}
int main(int argc, char *argv[])
{
prodcons_initialize(&pc);
errno_t rc = async_event_subscribe(EVENT_KIO, kio_notification_handler, NULL);
if (rc != EOK) {
fprintf(stderr, "%s: Unable to register kio notifications\n",
NAME);
return rc;
}
fid_t fid = fibril_create(consumer, NULL);
if (!fid) {
fprintf(stderr, "%s: Unable to create consumer fibril\n",
NAME);
return ENOMEM;
}
tinput_t *input = tinput_new();
if (!input) {
fprintf(stderr, "%s: Could not create input\n", NAME);
return ENOMEM;
}
fibril_add_ready(fid);
async_event_unmask(EVENT_KIO);
kio_update();
tinput_set_prompt(input, "kio> ");
char *str;
while ((rc = tinput_read(input, &str)) == EOK) {
if (str_cmp(str, "") == 0) {
free(str);
continue;
}
kio_command(str, str_size(str));
free(str);
}
if (rc == ENOENT)
rc = EOK;
return EOK;
}
HelenOS homepage, sources at GitHub