Embedding files in C programs with koio May 29, 2018 on Drew DeVault's blog

Quick blog post today to introduce a new tool I wrote: koio. This is a small tool which takes a list of files and embeds them in a C file. A library provides an fopen shim which checks the list of embedded files before resorting to the real filesystem.

I made this tool for chopsui, where I eventually want to be able to bundle up sui markup, stylesheets, images, and so on in a statically linked chopsui program. Many projects have small tools which serve a similar purpose, but it was simple enough and useful enough that I chose to make something generic so it could be used on several projects.

The usage is pretty simple. I can embed ko_fopen.c in a C file with this command:

$ koio -o bundle.c ko_fopen.c://ko_fopen.c

I can compile and link with bundle.c and do something like this:

#include <koio.h>

void koio_load_assets(void);
void koio_unload_assets(void);

int main(int argc, char **argv) {
    koio_load_assets();
    FILE *src = ko_fopen("//ko_fopen.c", "r");
    int c;
    while ((c = fgetc(src)) != EOF) {
        putchar(c);
    }
    fclose(src);
    koio_unload_assets();
    return 0;
}

The generated bundle.c looks like this:

#include <koio.h>

static struct {
	const char *path;
	size_t len;
	char *data;
} files[] = {
	{
		.path = "//ko_fopen.c",
		.len = 408,
		.data =
"#define _POSIX_C_SOURCE 200809L\n#include <errno.h>\n#include <stdlib.h>\n#inc"
"lude <stdio.h>\n#include \"koio_private.h\"\n\nFILE *ko_fopen(const char *path"
", const char *mode) {\n\tstruct file_entry *entry = hashtable_get(&koio_vfs, p"
"ath);\n\tif (entry) {\n\t\tif (mode[0] != 'r' || mode[1] != '\\0') {\n\t\t\ter"
"rno = ENOTSUP;\n\t\t\treturn NULL;\n\t\t}\n\t\treturn fmemopen(entry->data, en"
"try->len, \"r\");\n\t}\n\treturn fopen(path, mode);\n}\n",
	},
};

void koio_load_assets(void) {
	ko_add_file(files[0].path, files[0].data, files[0].len);
}

void koio_unload_assets(void) {
	ko_del_file(files[0].path);
}

A very simple tool, but one that I hope people will find useful. It’s very lightweight:

Enjoy!

Articles from blogs I read Generated by openring

Feelings outlive paper, paper outlives feelings

A letter is communication. Communication of information and communication of feelings. Letters from my bank have little feelings (and sometimes little information too). Letters from individual people have a lot of feelings, even if they didn't intend …

via Cadence's Weblog September 5, 2025

What's cooking on SourceHut? Q3 2025

Hello everyone! It’s time for another quarterly update on what we’re up to at SourceHut. There’s a lot of great stuff going on since you last heard from us! Let’s get started. Drew’s update We finally rolled out the billing overhaul! God, that was so much work…

via Blogs on Sourcehut September 1, 2025

Astound Supports IPv6 Only in Washington

In the hopes that it saves someone else two hours later: the ISP Astound only supports IPv6 in Washington State. You might find this page which says “Astound supports IPv6 in most locations”. Their tech support agents might tell you that they support v6 o…

via Aphyr: Posts August 26, 2025