On rewriting Go code in C++
On rewriting tooling in C++
I wrote some tooling in C++ that reimplements some functionality I had originally written in Go, mostly to build more C++ skills relevant to work. They're similar line counts:
+--------------+-------+-------+---------+------+
| Language | files | blank | comment | code |
+--------------+-------+-------+---------+------+
| C++ | 4 | 91 | 85 | 406 |
| C/C++ Header | 3 | 24 | 63 | 31 |
+--------------+-------+-------+---------+------+
| C++ total | 7 | 115 | 148 | 437 |
+--------------+-------+-------+---------+------+
| Go | 7 | 68 | 33 | 317 |
+--------------+-------+-------+---------+------+
A little bit more code, most because my flags and configuration packages are more verbose in C++ than in Go. One area of illustration: uploading files.
func (pkg Debpack) Put(debFile string) error {
url := pkg.URL("upload")
file, err := os.Open(debFile)
if err != nil {
return err
}
defer file.Close()
client := http.DefaultClient
req, err := http.NewRequest(http.MethodPut, url, file)
if err != nil {
return err
}
req.SetBasicAuth(config.Get("username"), config.Get("password"))
resp, err := client.Do(req)
defer resp.Body.Close()
if err != nil {
return err
}
result := http.StatusText(resp.StatusCode)
switch resp.StatusCode {
case 201:
result = "package created"
case 400:
result = "bad name, version, distribution, component or arch (duplicate?)"
case 409:
result = "duplicate package"
}
fmt.Printf("%s: %d %s\n", filepath.Base(debFile), resp.StatusCode, result)
return nil
}
and in C++:
bool
putDebian(std::vector<std::string> args)
{
auto ok = true;
for (auto &arg: args) {
auto url = debianEndpoint("upload");
auto result = PutFile(url, arg);
std::cout << "\t[*] PUT " << std::filesystem::path(arg).filename() << ": ";
std::cout << ResultToString(result) << "\n";
ok &= ResultSuccess(result);
}
return ok;
}
and:
Result
PutFile(std::string url, std::string path)
{
const curlpp::Cleanup clearerr;
static std::string userPass;
auto verbose = false;
curlpp::Easy request;
if (scsl::SimpleConfig::GetGlobal("verbose") == "true") {
verbose = true;
}
if (userPass.empty()) {
userPass = getUserPass();
}
try {
std::list<std::string> header;
header.emplace_back("Content-Type: application/octet-stream");
if (!std::filesystem::exists(path)) {
std::cerr << "[!] " << path << " does not exist!\n";
return Result::CurlFailed;
}
auto fileSize = static_cast<int64_t>(std::filesystem::file_size(path));
std::ifstream uploadFile(path);
if (!uploadFile.good()) {
std::cerr << "[!] " << path << " does not exist!\n";
return Result::CurlFailed;
}
request.setOpt(new curlpp::options::Url(url));
if (verbose) {
request.setOpt(new curlpp::options::Verbose(true));
}
request.setOpt(new curlpp::options::UserPwd(userPass));
request.setOpt(new curlpp::Options::ReadStream(&uploadFile));
request.setOpt(new curlpp::Options::InfileSize(fileSize));
request.setOpt(new curlpp::Options::Upload(true));
request.perform();
} catch (curlpp::LogicError &e) {
std::cerr << e.what() << "\n";
return Result::CurlFailed;
} catch (curlpp::RuntimeError &e) {
std::cerr << e.what() << "\n";
return Result::CurlFailed;
}
auto httpStatus = curlpp::infos::ResponseCode::get(request);
switch (httpStatus) {
case 201:
return Result::Created;
case 400:
return Result::BadPackage;
case 409:
return Result::DuplicatePackage;
default:
return Result::CurlFailed;
}
}
kyOSPi//64
Also fired off a background project to work on kOS//pi64.

After realizing I lost all traces of Pious, and re-reading Fantasia and Acorns and Oak Trees, I figured I should kick off a backburner project to write an operating system for the Pi.
Here's what I would like to build: a hypervisor that runs unikernels in "slots." Each unikernel is allocated one or more disk images; each kernel is fully isolated from the others and uses a capability system to assist in enforcing this.
Unlike the previous baking-pi and pious operating systems, this will be a 64-bit operating system. The picture is of a CM4 carrier board, but I ended up scrounging up another pair of Raspberry Pi 4's, one of which went into the rack (where it was originally intended to go), and the other is the kOS//pi64 development board.
The first step is to get a serial console working. The next step is to think about starting to build out a capability system, which will likely start with a virtual memory manager. I'm also going to have to think about getting a network driver going. Gods help me, I'm also thinking about doing some Rust with this. First things first, though. It's also a very slow burn project, and I don't expect to get much done on it very quickly.