slog is aptly named
I used to use the go log package, then I switched to the slog package, and it’s been a bumpy ride.
more...
I used to use the go log package, then I switched to the slog package, and it’s been a bumpy ride.
more...
I ripped out a dependency and then I found out what it did. I wrote an RSS parser for a very simple project, and then figured, how hard could it be to use in a real feed reader? Well, not very hard, but it was somewhat time consuming, and offers another perspective on using other people’s code.
more...
It’s been one year since our previous adventure, so it’s time for another round of guess why that dependency shows up in the tarball. This time we’re looking at honk, an ActivityPub server that’s supposed to be idiosyncratic with minimal dependencies, so you can keep all your attention focused where it’s needed.
more...
Poking through layers of indirection in go trying to recover some efficiency.
more...
ASUS laptops generally have a feature that lets the user toggle the fan speed. Fn-F5 on some models, Fn-F on others. The direct effect is to limit the fan speed, from whisper mode to megablast, and indirectly control performance. But it doesn’t work in OpenBSD, so I needed to write an ASUS ACPI WMI driver.
more...
As I move around, I roam between wifi networks, but sometimes lose the connection. Then I click a link and watch in vain as it fails to load. So I’d like an easy way to check which, if any, wifi network I’m connected to, such as by putting it in my dwm status bar. I could run ifconfig and parse the output, but that’s excessively wasteful. I need to get the info myself.
more...
The OpenBSD kernel is getting to be really old, like really, really old, mid 40s old, and consequently it doesn’t like surprises, so programs have to tell it where their syscalls are. In today’s edition of the polite programmer, we’ll learn the proper etiquette for doing so.
more...
On OpenBSD, there is a rule that you link with libc to interface with the kernel, because that’s where the syscall stubs live. This causes a great deal of consternation for partisans of other languages, because they don’t want to link “all of libc”. But when does anything link all of libc?
more...
What if we want a grep that doesn’t stuck but we don’t want to resort to wild hacks like editing the source? What if there was some way to flush stdout automatically?
The auto flusher is a very simple preload.
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
static void *
flusher(void *arg)
{
while (1) {
sleep(3);
fflush(stdout);
}
}
__attribute__((constructor))
void
herewego(void)
{
pthread_t thread;
pthread_create(&thread, NULL, flusher, NULL);
}
Magic constructor attribute for initializers in C, and then we create a thread which loops around occasionally flushing stdout, so if there’s any data left lingering, it will eventually find it’s way out instead of waiting forever.
$ cc -shared -lpthread -o libflusher.so flusher.c
$ env LD_PRELOAD=./libflusher.so grep ...
Sometimes pipes get stuck. To recap, if we run this command...
~/src/usr.bin/grep> tail -200 util.c | grep unsigned | grep int
grep_revstr(unsigned char *str, int len)
... we get the expected output. If we run it this way, however, there’s no output.
~/src/usr.bin/grep> tail -f -200 util.c | grep unsigned | grep int
The file isn’t being appended, meaning tail won’t exit, so we don’t expect the pipeline to ever finish, but we would like to see the current results.
Fortunately, grep provides an lbflag we can set. In this case, if the input is a pipe, we’ll assume there’s something fancy going on, and switch to line buffering.
struct stat sb;
fstat(0, &sb);
if ((sb.st_mode & S_IFMT) == S_IFIFO)
lbflag = 1;
Easy fix. (Or one can read the manual.)
But this is excessive. What about those times when we want the efficiency of buffering? There are lots of possible pipelines that don’t involve tail. What we can do instead is take a peek at some of our neighbors and see what’s really going on. Not perfectly accurate, but probably good enough.
static void
checklbflag()
{
pid_t pgrp = getpgrp();
struct kinfo_proc ki[24];
size_t len = sizeof(ki);
int mib[6] = { CTL_KERN, KERN_PROC, KERN_PROC_PGRP, pgrp,
sizeof(ki[0]), sizeof(ki)/sizeof(ki[0]) };
sysctl(mib, 6, ki, &len, NULL, 0);
for (size_t i = 0; i < len / sizeof(ki[0]); i++)
if (strcmp(ki[i].p_comm, "tail") == 0)
lbflag = 1;
}
Alas, this requires including <sys/sysctl.h> which will slow down our compiles.
It is also possible, using forbidden magic, to determine whether the pipe we are reading from is being written to by tail, as opposed to a tail at the end of the pipeline, but that’s left as an exercise for the reader.