I'm Remy, a developer from The Netherlands with a focus on C++, C, C#, Linux and embedded systems.
I currently work for
To read more or get in touch, click here. This is my personal website, these articles do not reflect or are based on work, opinions or policies of any of my (previous) employers. Any resemblance to reality is pure coincidence.
Using IceWM and a Raspberry Pi as my main PC, sharing my theme, config and some tips and tricks.10-07-2021 | Remy van Elst
KDE is my desktop environment of choice. KDE5 is rock-solid, configurable in any way possible and works great. It treats you like a responsible adult instead of a child like GNOME does these days, and after XFCE switched to GTK3, the RAM usage is on-par, more often than not a bare KDE install (Debian or Arch) uses around 300MB ram. This is with Baloo (search indexer) and Akonadi (PIM database backend) disabled. Great default behaviour, low resource usage and enourmous configurability, so why is this post then titled 'IceWM'? At home I'm using a small ARM device (Raspberry Pi 4 with an SSD) as my main computer, and there resources are limited. KDE runs fine, but you notice that it is a bit slower than on my work computer. IceWM on the other hand, uses less than 30 MB of RAM and even less CPU. The program that gives you a desktop background, icewmbg, uses double the RAM of IceWM itself! IceWM, next to Awesome, is one of my favorite window managers, very configurable and provides all I need. This PC doesn't have multiple screens, which would be a bit more of a hassle than with KDE. After switching, the machine feels a lot faster. It's the small details in which I notice it, like text input, a few seconds of lag here and there. This post shows my IceWM config including some options explained, my IceWM theme and a few tips and tricks to configure the rest of the desktop.Read more...
Firefox 89 Proton UI Tab Styling27-06-2021 | Remy van Elst
Firefox 89 recently came out with a 'new' user interface (named proton). I'm not a fan of change because UX/UI people need to make it seem like their job is relevant. Also, the picture they show under the headline '17 billion clicks...' only scares the crap out of me, tracking every move a user makes in their browser seems to me to be a bad idea, but hey, lets see how long Mozilla can continue their war against their own users. Since the
about:config flag to disable proton will probably be gone in a few releases I thought, why not try to get used to this new interface. It's so enormous and wide, lacking contrast. As you might have guessed, I cannot get used to the tab bar, so in this post I'll show you how to use the
userChrome.css file to make the new tab bar look a bit more like the old tab bar.
Get started with the Nitrokey HSM or SmartCard-HSMPublished: 19-06-2016 | Last update: 20-06-2021 | Author: Remy van Elst
This is a guide to get started with the Nitrokey HSM (or SmartCard-HSM). It covers what a HSM is and what it can be used for. It also goes over software installation and initializing the device, including backups of the device and the keys. Finally we do some actual crypto operatons via pkcs11, OpenSSL, Apache and OpenSSH. We also cover usage in Thunderbird (S/MIME), Elementary Files (EF), a Web cluster with Apache and mod_nss and the decryption of the keys.Read more...
Execute a command and get both output and exit status in C++ (Windows & Linux)07-06-2021 | Remy van Elst
Recently I had to parse some command line output inside a C++ program. Executing a command and getting just the exit status is easy using
std::system, but also getting output is a bit harder and OS specific. By using
popen, a POSIX
C function we can get both the exit status as well as the output of a given command. On Windows I'm using
_popen, so the code should be cross platform, except for the exit status on Windows is alway 0, that concept does not exist there. This article starts off with a stack overflow example to get just the output of a command and builds on that to a safer version (null-byte handling) that returns both the exit status as well as the command output. It also involves a lot of detail on
fgets and how to handle binary data.
Exclude lines in less (or journalctl)23-05-2021 | Remy van Elst
This is a small tip I want to give you when using a
less based pager, for example in
journalctl or when viewing a file interactively with
more. You can exclude certain lines that match one or multiple words (or a regex) with a few keystrokes, once
less is open. This is one of those tips you never knew you needed, but when you know it, you'll use it frequently. Like in my case today when searching through some logfiles to find out why my database stopped working.
All packages that were present in Ubuntu 18.04 but absent in Ubuntu 20.0419-05-2021 | Remy van Elst
Figure out the differences between two apt repositories. Recently I've had a few packages that I often use but were missing from Ubuntu 20.04 LTS. One is ckermit and the other is gnash, both of which I 'converted' to a snap. (In air quotes because I just converted the 18.04 deb). This made me wonder if I could figure out a list of that are present in Ubuntu 18.04, but absent in Ubuntu 20.04. As
dpkg are standardized tools and and package formats, we can use a few shell tools to parse the package lists and compare them side by side.
This post shows you how to do the comparison yourself and I discuss the removed packages a bit. Some are version increments (like
gcc-6 in Ubuntu 18.04 but
gcc-7in Ubuntu 20.04), and some are packages that were combined into one instead of split up (like
ltsp in Ubuntu 20.04 but a bunch of seperate
ltsp-$postfix packages instead in Ubuntu 18.04). Many others are just replaced by newer versions (
python3-ceph). The list of differences is provided as a download, both ways.
I've packaged up CKermit as a snap, for Ubuntu 20.0416-05-2021 | Remy van Elst
Last year I packaged up gnash as a snap because it was missing from the Ubuntu 20.04 apt repositories. Recently I found out that
ckermit is also not in Ubuntu 20.04, as far as I can tell because it wasn't in the Debian repositories when the Ubuntu 20.04 initial sync happened. Which is very inconvenient for an LTS release.
I often use
ckermit to connect to our hardware via a script, to automatically boot from NFS (via u-boot). I could do that manually via
minicom, but I have a
kermit script that does it for me, which is very convenient. Since the snapping of
gnash was so easy, I decided to do it for
ckermit as well, since I now know how to convert deb packages to snaps. I also have a few colleagues who also use those kermit scripts and are going to update to 20.04 in the (near) future.
The snap packaging is based on work by Phil Roche, he wrote about re-packaging older debian packages with an Ubuntu 18.04/16.04 base layer as a snap. My
ckermit package is confined (no
--classic needed), the source code for the snap is on my github and on any snap-enabled distro you can now 'snap install ckermit-raymii' to enjoy CKermit.
I've packaged up Gnash as a snap, for modern linuxPublished: 07-12-2020 | Last update: 15-05-2021 | Author: Remy van Elst
I hate snaps just as much as the next guy but last week I did something unexpected. I packaged up Gnash as a snap. Gnash is a GNU flash media player, not updated since 2011, and thus removed from the Ubuntu 20.04 repositories. The snap packaging is based on work by phil roche, he wrote about re-packaging older debian packages with an Ubuntu 18.04/16.04 base layer as a snap. My gnash package is confined (no '--classic' needed), the source code for the snap is on my github and on any snap-enabled distro you can now 'snap install gnash-raymii' to enjoy Gnash again.Read more...
It compiles does not always mean that it works, a tale of virtual overridden fun in C++Published: 12-05-2021 | Last update: 14-05-2021 | Author: Remy van Elst
In a recent article on clang-tidy I referenced the fact that we're doing a huge refactoring regarding
char pointers, lifetime, ownership and
std::strings. Todays post is another one related to that change, where even though everything compiled correctly, it didn't
work. For a compiled language, that is not something you expect. Next to unit tests, a compiler error is your number one sign that you've made a mistake somewhere.
In this case however, the code all compiled fine. The issue here was an older part of the code not using
override combined with automated refactoring in CLion missing some parts of the code during a change. So, the issue in this case is entirely our own fault, it was spotted in the manual testing, but I'd rather had it not happen at all.
In this post I'll describe the problem including some example code that illustrates what happened. My key point is that even though the code compiles, you should always test it, preferably automated with unit and integrations tests, otherwise manually with a runbook.
Run MS Teams on a coffee machine?!? (Or: Embedded Linux Framebuffer VNC client)08-04-2021 | Remy van Elst
To fill some time during compiling I tried to get a VNC client running on a coffee machine, specifically to show MS Teams. At work I develop software for these coffee machines in C++, which allows me to do such fun stuff, because from a software point of view, it's just an ARM PC running linux with a framebuffer for graphics. I compiled a few framebuffer VNC clients, fired up an SSH tunnel and used
x11vnc to share one specific window and after a few attempts, Teams was up and running on my 'new' second monitor.
This post contains my little adventure in framebuffer VNC clients, but it's not a comprehensive guide as most of my other articles. Showing you how to set up an Openembedded server with a VariScite specific toolchain is way too much work to cross-compile a simple C program, but since that's my day job, why not use it for fun. It contains some tips for
x11vnc and shows you two different framebuffer VNC clients,
Run one specific clang-tidy check on your entire codebase05-04-2021 | Remy van Elst
Recently I did a major refactor on a piece of code that involved thousands of lines of code which were in one way or another related to string handling. All of the code handled
char* (C style character pointer arrays) and the concept of
const or ownership was literally unknown in that part of the codebase. The refactored code uses
std::string's, but due to the legacy nature, a large number of methods returned
nullptr's instead of empty strings. I understand why this was done, but finding all those instances and the fact it only gives a runtime error was a bit of a bummer.
clang-tidy is here to save the day. In my IDE, CLion, it gives a warning when you return a
nullptr. It however does that only in the file you're currently editing, and since we're talking millions of files, I wasn't going to open them by hand. You can run
clang-tidy easily on one file, and it's not hard to run it on an entire codebase as well, using the script
run-clang-tidy.py, provided in their packages.
This snippet shows you how to run one specific
clang-tidy check, in my case,
bugprone-string-constructor, on a (cmake and C++) codebase.