summaryrefslogtreecommitdiffstatshomepage
path: root/content
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--content/16/index.md2
-rw-r--r--content/17/index.md2
-rw-r--r--content/19/index.md87
-rw-r--r--content/19/kde-plasma.pngbin0 -> 1228299 bytes
-rw-r--r--content/19/notification.pngbin0 -> 72903 bytes
-rw-r--r--content/20/index.md66
-rw-r--r--content/21/index.md57
-rw-r--r--content/21/places.pngbin0 -> 73620 bytes
-rw-r--r--content/22/index.md52
-rw-r--r--content/23/index.md140
-rw-r--r--content/8/index.md2
11 files changed, 405 insertions, 3 deletions
diff --git a/content/16/index.md b/content/16/index.md
index 2cb12b3..a970d33 100644
--- a/content/16/index.md
+++ b/content/16/index.md
@@ -9,7 +9,7 @@ tags = ["experiments"]
My main desktop PC tracks the latest LTS [release](https://kernel.org/) of the
Linux kernel which very recently switched to the 5.15 line. Along with neat new
features like the
-[NTSF3 driver](https://lore.kernel.org/all/aa4aa155-b9b2-9099-b7a2-349d8d9d8fbd@paragon-software.com/)
+[NTFS3 driver](https://lore.kernel.org/all/aa4aa155-b9b2-9099-b7a2-349d8d9d8fbd@paragon-software.com/)
it also includes experimental support for
[Link Time Optimization](https://llvm.org/docs/LinkTimeOptimization.html)
through LLVM's
diff --git a/content/17/index.md b/content/17/index.md
index 2c79af6..f37ba18 100644
--- a/content/17/index.md
+++ b/content/17/index.md
@@ -3,7 +3,7 @@ date = 2022-02-13T18:25:11+01:00
title = "Getting MPD to parse TIT1 in MP3 files"
[taxonomies]
-tags = ["TIL"]
+tags = ["bugs"]
+++
I have a pretty extensive music library that I manage with MPD, the [Music
diff --git a/content/19/index.md b/content/19/index.md
new file mode 100644
index 0000000..792a6dd
--- /dev/null
+++ b/content/19/index.md
@@ -0,0 +1,87 @@
++++
+date = 2024-09-18T21:16:12+02:00
+
+title = "KDE Plasma 6 and two bugs"
+
+[taxonomies]
+tags = ["bugs"]
+
+[extra]
+related = []
++++
+
+For the last couple of months I have been running [sway](https://swaywm.org/) on
+my main desktop system after having been forced away from
+[hikari](https://hub.darcs.net/raichoo/hikari) because of its practically halted
+development and incompatibility with newer
+[wlroots](https://gitlab.freedesktop.org/wlroots/wlroots/) versions.
+
+I never felt completely satisfied with it and the whole experience was rather
+joyless, so about a week ago I decided to give [KDE Plasma
+6](https://kde.org/announcements/megarelease/6/) a try after a surprisingly
+decent experience on the [KDE Neon](https://neon.kde.org/) live image.
+
+Whilst undoubtedly greater in its complexity and code size than sway, to me
+Plasma 6 seems like one of the last decent desktop environments still remaining.
+It's incredibly customisable (but still comes with good defaults), looks nice
+out of the box, and most importantly seems to care about providing a nicely
+integrated and featureful experience. This even includes a companion app on
+Android, [KDE Connect](https://kdeconnect.kde.org/). It remains to be seen
+whether it will fully convince me in the long run, but for now I am very
+satisfied with it.
+
+{{ img(path="kde-plasma.png", alt="A picture of the KDE Plasma 6 desktop
+environment, with a browser window, a terminal, and an instance of Dolphin, a
+file manager.", caption="KDE Plasma 6 with a few windows open") }}
+
+This last week was mostly spent learning about the desktop environment and
+setting everything up exactly how I want it to be, but there were two notable
+bugs to squash as well.
+
+The first one reared its ugly head once I enabled backwards-compatibility with
+Qt5-based apps. I have a couple of such apps still, most prominently
+[Mumble](https://www.mumble.info/) and [Quassel IRC](https://quassel-irc.org/).
+Once the latter was built against the KFramework libraries, no more
+notifications were shown...
+
+Fixing this ended up taking about two days, most of which were spent discovering
+exactly how
+[KNotifications](https://api.kde.org/frameworks/knotifications/html/index.html)
+work. KDE provides apps with a tighter integration to the notification service,
+allowing users to specify which types of notifications to show, and how.
+Applications specify their notifications by shipping an `<app>.notifyrc` file.
+KDE ties this file to the application by matching its base name to the name
+given to the application (usually through a call to
+`QCoreApplication::applicationName` or when creating
+[KAboutData](https://api.kde.org/frameworks/kcoreaddons/html/classKAboutData.html)).
+
+It turns out that Quassel had recently been
+[patched](https://github.com/quassel/quassel/commit/020c163421691fa37330826df92ac0a248721290)
+to fix an issue where desktop environments did not show its icon correctly. This
+required a call to `setDesktopFileName` in `KAboutData` to make environments
+aware of the connection. However, Quassel's application name was
+[changed in the same commit](https://github.com/quassel/quassel/commit/020c163421691fa37330826df92ac0a248721290#diff-c72daad7d2269a2ee21584002ef1f30f4415335358a6c6f7e7296d3290a51a91R117),
+severing its link with the name given through its `quassel.notifyrc` file. This
+seems to have been done in addition to the `setDesktopFileName` call and was not
+necessary to solve the issue the commit was trying to address.
+
+I prepared a [pull request](https://github.com/quassel/quassel/pull/619) fixing
+this issue by reverting part of the offending commit.
+
+{{ img(path="notification.png", width=412, format="png", alt="A picture of a
+notification from Quassel IRC saying 'yay for notifications'.", caption="Glad to
+have these back") }}
+
+The second bug I randomly came across whilst perusing `journalctl` and seeing
+the following error from [Dolphin](https://apps.kde.org/dolphin/), KDE's file
+manager:
+
+ QString(View)::contains(): called on an invalid QRegularExpression object
+ (pattern is '\A(?:file:///home/wolf/[Z-A]/?)\z')
+
+Seeing this immediately made me wonder whether Dolphin plugs a URL straight into
+a regular expression without escaping it, and the answer, of course,
+[is yes](https://invent.kde.org/system/dolphin/-/blob/5c069471fccc41051b967be69f95655b3e0b73ef/src/dolphinviewcontainer.cpp#L554-557).
+I spent most of today's afternoon hunting this issue down and preparing a [merge
+request](https://invent.kde.org/system/dolphin/-/merge_requests/831) that fixes
+it in an elegant way.
diff --git a/content/19/kde-plasma.png b/content/19/kde-plasma.png
new file mode 100644
index 0000000..7a7251d
--- /dev/null
+++ b/content/19/kde-plasma.png
Binary files differ
diff --git a/content/19/notification.png b/content/19/notification.png
new file mode 100644
index 0000000..fbf11f6
--- /dev/null
+++ b/content/19/notification.png
Binary files differ
diff --git a/content/20/index.md b/content/20/index.md
new file mode 100644
index 0000000..fbc99c1
--- /dev/null
+++ b/content/20/index.md
@@ -0,0 +1,66 @@
++++
+date = 2024-09-19T22:45:36+02:00
+title = "List mpv(1)'s watch_later entries with later(1)"
+
+[taxonomies]
+tags = ["projects", "later(1)"]
+
+[extra]
+related = []
++++
+
+If you are like me then you have a basically never-ending backlog of videos to
+watch. Perhaps sometimes you even watch videos so long that they're basically
+impossible to finish in one sitting. Or you have about an hour left on a video,
+but you should really go to sleep.
+
+All of these require some way to remember the timestamp where you left off. I
+use [`mpv(1)`](https://mpv.io/) to watch my videos and thankfully there is a
+built-in way to do this. By default, hitting `Q` will quit the video and
+remember the timestamp ([among other
+settings](https://mpv.io/manual/stable/#resuming-playback)) for next time you
+open the file. This works regardless of whether the video exists on your
+filesystem or is streamed from a URL.
+
+After a while of using this you might amass more than a couple of unfinished
+videos that `mpv(1)` knows about, but what it sadly does not provide is an easy
+way to show you which videos those are...
+
+Whilst you can set
+[`write-filename-in-watch-later-config`](https://mpv.io/manual/stable/#options-write-filename-in-watch-later-config)
+and have `mpv(1)` save filenames and URLs in its watch later entries, quickly
+finding them is another story.
+
+This is where a shared effort between my partner
+[nortti](https://ahti.space/~nortti/) and me comes in:
+[`later(1)`](https://git.oriole.systems/later/about/). It is a small Python
+script that parses `mpv(1)`'s [watch
+later](https://mpv.io/manual/stable/#watch-later) entries and displays them in a
+human-readable and pretty manner:
+
+```
+albatross ~$ later
+Sep 19 19:50 https://www.youtube.com/watch?v=VKGtMK4CGV4 # The 2 Hour Hunt for Light Arrows - OoT Randomizer
+Sep 19 22:30 /home/wolf/Mall Grab - Understand feat. Brendan Yates.webm
+```
+
+From here it is easy to open up the video you want to continue watching: simply
+paste the path or URL printed by `later(1)` into `mpv(1)`.
+
+You might notice that the YouTube video is commented with its title. This is not
+information that `mpv(1)` saves, but `later(1)` can help here too. Using the
+`-u` or `--update-titles` flag, it will extract video titles using
+[`yt-dlp(1)`](https://github.com/yt-dlp/yt-dlp) and save them in its cache for
+subsequent retrieval. This should work for any site that `yt-dlp(1)` itself
+supports.
+
+If you have a Python available, setting up and using `later(1)` is trivial:
+simply copy the script into a directory in your `$PATH` (and the manual into
+`$MANPATH`) or use the `Makefile`:
+
+```
+$ PREFIX=~/.local make install
+```
+
+Do note that for `later(1)` to work correctly, the aforementioned
+`write-filename-in-watch-later-config` setting needs to be set.
diff --git a/content/21/index.md b/content/21/index.md
new file mode 100644
index 0000000..384509f
--- /dev/null
+++ b/content/21/index.md
@@ -0,0 +1,57 @@
++++
+date = 2024-09-26T19:27:54+02:00
+title = "Pretty names for mount points in /etc/fstab"
+
+[taxonomies]
+tags = ["TIL"]
+
+[extra]
+related = []
++++
+
+The file manager I'm using on my Plasma 6 system,
+[Dolphin](https://invent.kde.org/system/dolphin), has built-in support for
+remote folders via the [KIO](https://invent.kde.org/frameworks/kio) framework.
+Where before I was relying on [sshfs](https://github.com/libfuse/sshfs) mount
+points in `/etc/fstab`, I decided to try out the Dolphin way and set up my
+remote devices using its `sftp` backend.
+
+After a couple of days now I can say that this works beautifully... until you
+want to access the remote device on something that does not interface with KIO.
+This is especially important for me (and
+[others](https://invent.kde.org/plasma/plasma-desktop/-/issues/71#note_640907))
+since I want to be able to browse networked filesystems via my terminal and have
+the ability to directly open a terminal in that location through Dolphin,
+something which is not possible with the KIO backend.
+
+So in the end I went back to mount points in `/etc/fstab`. One small problem
+remained, however, and that was the way those mount points were displayed
+within Dolphin. There seemed to be no way to customize a mount point's name or
+icon, leading to an annoyingly long `/home/wolf/net/hosts/coleridge` entry in
+the *Devices* section of Dolphin's places panel.
+
+I couldn't find any help in `fstab(5)`, and indeed I had never heard of a way
+to give a mount point a "pretty name". However, after a bit of searching, I
+found people offhandedly mentioning the `x-gvfs-name` option. Some more
+searching revealed that nobody seems to care about documenting these features,
+but I was finally able to find an authoritative source within [gvfs
+itself](https://github.com/GNOME/gvfs/blob/989d746ed771fc5e5bf134677cf8d571170b262e/monitor/udisks2/what-is-shown.txt#L29-L35).
+
+Happily there's not only `x-gvfs-name` but also support for custom icons
+through `x-gvfs-icon`. So, if you want your file manager to display a pretty
+name and icon for one of your mount points, simply add the following to the
+relevant entry in `/etc/fstab`:
+
+```
+x-gvfs-name=My%20Device,x-gvfs-icon=network-server
+```
+
+This should be possible at least on GNOME and KDE desktops. I imagine a bunch
+of other environments and programs silently support this behaviour as well.
+
+{{ img(path="places.png", format="png", alt="A screenshot of Dolphin, KDE's
+file manager, showing the user's home directory with the places panel on the
+left side containing various categorized entries. The entries below the Devices
+category read flood, demeter, coleridge, and OnePlus 12, each with its own
+pretty name and relevant icon.", caption="Dolphin displaying pretty names and
+icons in the *Devices* category") }}
diff --git a/content/21/places.png b/content/21/places.png
new file mode 100644
index 0000000..cfbd8e7
--- /dev/null
+++ b/content/21/places.png
Binary files differ
diff --git a/content/22/index.md b/content/22/index.md
new file mode 100644
index 0000000..c3ece23
--- /dev/null
+++ b/content/22/index.md
@@ -0,0 +1,52 @@
++++
+date = 2024-09-28T18:23:12+02:00
+title = "MIME type subclassing and its consequences"
+
+[taxonomies]
+tags = ["TIL"]
+
+[extra]
+related = []
++++
+
+The freedesktop.org [shared MIME-info database
+spec](https://specifications.freedesktop.org/shared-mime-info-spec/latest) says
+the following in [section
+2.11](https://specifications.freedesktop.org/shared-mime-info-spec/latest/ar01s02.html#subclassing):
+
+> A type is a subclass of another type if any instance of the first type is
+> also an instance of the second. For example, all `image/svg+xml` files are
+> also `application/xml`, `text/plain` and `application/octet-stream` files.
+> Subclassing is about the format, rather than the category of the data (for
+> example, there is no 'generic spreadsheet' class that all spreadsheets
+> inherit from).
+>
+> Some subclass rules are implicit:
+> - All `text/*` types are subclasses of `text/plain`.
+> - All streamable types (ie, everything except the `inode/*` types) are subclasses of application/octet-stream.
+
+So far so good; this makes intuitive sense and seems sensible enough. There is
+an interesting consequence of this rule when the MIME-info database is used by
+desktop systems for file associations, however: **An application associated with
+`application/octet-stream` will automatically be associated with all streamable
+types as well.**
+
+This means that if you associate `application/octet-stream` with your text
+editor, your desktop system will also suggest you open video and audio files
+with that same text editor. This behaviour can be quite surprising, especially
+if the association was added automatically when a file was opened through the
+"Open with..." dialog.
+
+What is even more confusing if you don't happen to know the subclassing rule is
+the fact that `~/.config/mimeapps.list` and applications interfacing with this
+file will not even list the editor as associated with any audio or video files.
+You might just skip over the entry it has for `application/octet-stream`, not
+realizing its significance. Perhaps you even assume (understandably) that
+`application/octet-stream` only specifies any file of "unknown" type.
+User-facing documentation on desktop systems (if it even exists) does not
+discuss this behaviour.
+
+Whilst looking into this I found an older KDE bug report with some [interesting
+thoughts](https://bugs.kde.org/show_bug.cgi?id=425154#c2) on how to explain this
+behaviour to the end user, but sadly as far as I have seen none of these have
+made it into the system setting's file association dialog.
diff --git a/content/23/index.md b/content/23/index.md
new file mode 100644
index 0000000..442f383
--- /dev/null
+++ b/content/23/index.md
@@ -0,0 +1,140 @@
++++
+date = 2024-10-02T18:42:07+02:00
+title = "musl and a curious Rust segfault"
+
+[taxonomies]
+tags = ["bugs"]
+
+[extra]
+related = []
++++
+
+About a week ago I noticed that [`fd(1)`](https://github.com/sharkdp/fd), a
+Rust-based alternative to [`find(1)`](https://www.gnu.org/software/findutils/),
+would suddenly segfault on my [musl](https://www.musl-libc.org/)-based server
+system. Usually a segfault is nothing particularly special to my eyes, but this
+one was different. Even just having `fd(1)` attempt to print its help text was
+enough to trigger it, and when I attempted to debug it with
+[`gdb(1)`](https://www.sourceware.org/gdb/), I saw the following:
+
+```
+(gdb) run
+Starting program: /usr/bin/fd
+
+Program received signal SIGSEGV, Segmentation fault.
+memcpy () at ../src_musl/src/string/x86_64/memcpy.s:18
+warning: 18 ../src_musl/src/string/x86_64/memcpy.s: No such file or directory
+(gdb) bt
+#0 memcpy () at ../src_musl/src/string/x86_64/memcpy.s:18
+#1 0x00007ffff7ab7177 in __copy_tls () at ../src_musl/src/env/__init_tls.c:66
+#2 0x00007ffff7ab730d in static_init_tls () at ../src_musl/src/env/__init_tls.c:149
+#3 0x00007ffff7aae89d in __init_libc () at ../src_musl/src/env/__libc_start_main.c:39
+#4 0x00007ffff7aae9c0 in __libc_start_main () at ../src_musl/src/env/__libc_start_main.c:80
+#5 0x00007ffff74107f6 in _start ()
+```
+
+So... the segfault is in musl, not in `fd`!?
+
+I immediately checked whether other basic programs on the system worked. *They
+did.* I checked when I last updated musl. *A couple of months ago, so that can't
+be it.* I checked specifically whether another Rust-based program worked. *It
+did.*
+
+`fd(1)` had been updated pretty recently, and I remembered it working correctly
+about a month ago, so maybe something specific to `fd(1)`'s usage of Rust
+triggered this segfault in musl? I wanted to make sure I could reproduce this in
+a development environment, so I cloned the `fd(1)` repository, built a debug
+release, and ran it...
+
+*It worked.* Huh!?
+
+I decided it was likely that [`portage`](https://wiki.gentoo.org/wiki/Portage),
+Gentoo's package manager, was building the program differently, so I took care
+to apply the same build flags to the development build. And what can I say:
+
+```
+error: failed to run custom build command for `crossbeam-utils v0.8.20`
+
+Caused by:
+ process didn't exit successfully: `fd/target/[...]/build-script-build`
+ (signal: 11, SIGSEGV: invalid memory reference)
+
+```
+
+... it didn't even get to build the `fd` binary proper. A segfault again, too.
+What on earth was going on? Why didn't this also happen in the `portage` build?
+
+Thankfully I now had a reproducer, so I did the only sensible thing and started
+removing random build flags until I got `fd` to build again. This was our
+culprit:
+
+```
+-Wl,-z,pack-relative-relocs
+```
+
+Already pretty out of my depth considering the fact that I couldn't fathom how
+`fd(1)` got musl to segfault on `memcpy`, I now also found that a piece of the
+puzzle required me to understand specific linker flags. *Oof.*
+
+Unsure what to do next I decided on a whim to compare the working and the
+broken binary with `readelf(1)`. The most obvious difference was that the
+working binary had its `.rela.dyn`
+[relocation](https://en.wikipedia.org/wiki/Relocation_(computing)) section
+populated with entries whilst the broken one was missing `.rela.dyn` but had
+`.relr.dyn` instead. At a loss, I stopped and went to do something else.
+
+The story would probably have ended here had I not mentioned this conundrum to
+[my partner](https://ahti.space/~nortti/) later in the day. We decided to have
+another look at the binaries. After some discussion we determined that the
+working binary was dynamically linked whilst the broken one wasn't. The other
+working Rust-based program, [`rg(1)`](https://github.com/BurntSushi/ripgrep),
+was also dynamically linked and had been built a while ago, so **at some point
+`portage` must have stopped producing Rust executables that were dynamically
+linked**. Finally some progress!
+
+At this point we need some background. Early on, Rust decided to use the
+`x86_64-unknown-linux-musl` target to provide statically-linked binaries that
+would run on a wide range of systems. Whilst support for dynamically linked
+executables on musl systems was [added back in
+2017](https://github.com/rust-lang/rust/pull/40113), the default behaviour was
+never changed, so Gentoo has to make sure to disable static linking by passing
+the `target-feature=-crt-static` flag.
+
+It does this in a system-wide fashion by setting an environment variable in
+[`/etc/env.d`](https://wiki.gentoo.org/wiki//etc/env.d):
+
+```
+$ cat /etc/env.d/50rust-bin-1.80.1
+LDPATH="/usr/lib/rust/lib"
+MANPATH="/usr/lib/rust/man"
+CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUSTFLAGS="-C target-feature=-crt-static"
+```
+
+This setting should therefore be picked up by `portage` as well, but when I
+examined its build environment it was simply not there. So finally we come to
+the last piece of the puzzle: a [recent
+change](https://gitweb.gentoo.org/repo/gentoo.git/commit/eclass/cargo.eclass?id=27d469a2114b4ad0b3e682854c50c806753eb472)
+in how `RUSTFLAGS` are set within `portage`. Here's the important part:
+
+```bash
+local -x CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS="-C strip=none -C linker=${LD_A[0]}"
+[[ ${#LD_A[@]} -gt 1 ]] && local CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS+="$(printf -- ' -C link-arg=%s' "${LD_A[@]:1}")"
+local CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS+=" ${RUSTFLAGS}"
+```
+
+Quoth the `bash(1)` manual:
+
+> Local variables "shadow" variables with the same name declared at previous
+> scopes. For instance, a local variable declared in a function hides a global
+> variable of the same name: references and assignments refer to the local
+> variable, leaving the global variable unmodified.
+
+When previously the `RUSTFLAGS` environment variable was only touched when
+cross-compiling, it was now overridden. To confirm, I edited the file in
+question to include the previous value, and both `fd(1)` and `rg(1)` worked
+again. Success!
+
+This whole saga was also [reported](https://bugs.gentoo.org/940197) to the
+Gentoo bug tracker and promptly fixed. A project for another day is figuring out
+exactly how a change from static linking to dynamic linking causes segfaults
+like this, because I sure would love to know the details.
diff --git a/content/8/index.md b/content/8/index.md
index 7bfcbb0..ac4b147 100644
--- a/content/8/index.md
+++ b/content/8/index.md
@@ -10,7 +10,7 @@ related = [9]
+++
When maintaining a project sooner or later there comes the time when you need to
-apply patches that have been submitted to you. Assuming a patch-based workflow
+apply patches that have been submitted to you. Assuming a patch-based workflow,
those are going to be one patch per mail, possibly connected in a thread.
There's lots of different ways of getting those patches to their final
destination, [`git-am(1)`](https://git-scm.com/docs/git-am), and in this post I