Blog: Gaming on Alpine Linux

All off topic discussions go here. Everything from the funny thing your cat did to your favorite tv shows. Non-programming computer questions are ok too.
Post Reply
nullplan
Member
Member
Posts: 1760
Joined: Wed Aug 30, 2017 8:24 am

Blog: Gaming on Alpine Linux

Post by nullplan »

Today I decided to do something productive with my Sunday: After casting my vote in the morning, I decided to get rid of the last Windows installation in my possession.

I have a laptop I use for web (mostly Youtube), e-mail, and development. It's been running Linux since I got it. I also have a PC I use for gaming. Until today, it was running Windows (first 10, then 11). But with Microsoft getting increasingly desperate to squeeze blood from the stone that is Windows, and turning to the dark AI arts to do it (not so long ago, Windows Recall would have been classed as spyware, plain and simple), I decided to get rid of it by installing Linux. And not just any Linux, but Alpine Linux.

I do realize I set myself up for failure here. Not only using the less popular platform, but foregoing glibc, and with it binary compatibility to what few games are supported natively. But I did make it work, for now. It doesn't work very well, but good enough for my purposes. Also, as a Debian user of 20 years, using something completely different definitely was a new experience for me. I keep typing "apt" when I mean "apk", and when running a command as root, my fingers instinctively seek out the s and u keys, before remembering that "sudo" is now "doas". Force of habit. Hopefully after today, I won't be needing that many root commands anymore, though.

Installation was surprisingly painless, though the Alpine installer is nothing for people that break out in hives at the sight of a console. Remember the old Debian installer, before they had the ncurses one? That is pretty much the Alpine installer. But it also has some features Debian is sorely lacking: When being asked to select a package mirror to use (a question you basically have to answer with zero context), you have the option to select the fastest one. That verifies that your internet connection is working, and filters out completely non-working ones as well.

After installation I finally figured out how to make the BIOS boot from M.2 drive. There is a boot order list in the BIOS, but that did not contain the M.2 drive, so there was no way for me to put it up at the top of the list. Turns out that MSI was just being difficult: The boot order list contains only one entry for each type of drive, and further down you can select which drive is meant for each given type. So in the boot order, I had to put "UEFI Harddisk" at the top, then further down select the M.2 drive as the option for "UEFI Harddisk". Why the indirection? Because they could, I suppose.

Anyway, I wasn't done doing things the hard way. The base system install has no graphics system, so I decided to install Wayland. That was the first time for me. On my laptop, I am happily using Xorg and awesome. But Wayland is the future, so best to rip the band-aid off in one go. I would have used Hyprland, but Alpine has no package for it, so now I am using sway for the time being. The Alpine wiki makes reference to loading the right graphics modules and stuff, but apparently that is not necessary, as the kernel auto-detects the hardware and loads modules accordingly. I had never really used an AMD GPU on Linux before, so when the Wiki said to just pick "radeon" or "amdgpu" as driver, I was a bit stumped. Turned out not to matter for the above reason, but apparently "amdgpu" is the right one.

Also, when sway reports an error from the amdgpu driver about how it could not create some sort of context, that error message does not matter. Always helpful to have error messages that don't matter.

The Wiki wanted me to install a greeter. After much back and forth, I had something working, but found that I could not log in. The reason being that my password contains a y, and I have a German keyboard. And if there is a way to set the keyboard layout generally for all Wayland compositors, I could not find it, but they default to American layout. I did set the layout in sway, but the greeter ran under cage, and there was no documentation for changing the keyboard layout in cage.

In the end, I decided to get rid of the greeter. I login with agetty on the command line, then start the graphics server, like it was 1995. Only the graphics server is now called sway instead of xinit.

Next issue was sound. Apparently, the current hotness is "pipewire". I had only ever vaguely heard about it, and I suppose something must throw a spanner in the works every now and again. After following the Wiki directions, I now have a system that works, but only in sway under dbus. I'm not a big fan of this bundling (why are graphics and sound now entwined?), but apparently it must be done, because pipewire depends on dbus, and I'm not starting dbus twice! The setup I have now works, but only once per boot. Thankfully I rarely log off the system without shutting it down entirely.

Finally, the games. I decided to go with Steam (obviously). However, the Wiki instructions were somewhat false. It was necessary for me to install Steam in the system flatpak repository along with the user one, because otherwise there would be an error on startup. After doing that, it was possible for me to log in, but I did find that my gamepad was not recognized. That was because even though I had installed the steam-devices package, my user still had to be in the "input" group for SDL to recognize the input devices. God only knows how the compositors kept reading those event files!

My first test case was Solar Ash, a Windows game with no Linux support. Running it under Proton worked pretty much immediately, once the input file kerfuffle was sorted. And the game ran about as well as it did on Windows.

Next test case was EXAPUNKS, a native Linux puzzle game. That one turned out to be much harder, actually. I could start the game, but it would always crash after a couple of seconds. So it was time for me to get the debugger out. And the debugger I used was the only real debugger: strace. Unlike all the others, it does not try to misrepresent reality by claiming that C was BASIC, but rather, it only displays what syscalls the processes are making, and what the results are.

Using strace, I determined that the game was writing a crash report to /tmp. But I could not find it there. After much back and forth, it turns out that Steam does some black magic with mount namespaces and cgroups, and what EXAPUNKS saw as /tmp was actually $XDG_RUNTIME_DIRECTORY/<some longer path here>/tmp. Maybe there was also something going on with bind mounts. Anyway, there was an error message about dbus not containing the OpenURI function, so I was hoping that if I could provide that function, then the crash information would be displayed to me in firefox. That never happened!

First, OpenURI is contained in the XDG GTK portal, so I had to install the package xdg-desktop-portal-gtk. But that one by default provides OpenURI only to GNOME. I am using sway. I had to create an obscure config file to make it work, and then reboot the system. And even then, no crash report, but the error message about the non-existant OpenURI was now gone.

It turned out that EXAPUNKS was crashing and writing a crash log to /tmp/burduke-crash-log.html, then calling "xdg-open /tmp/burduke-crash-log.html". xdg-open would find the file under that name and run the OpenURI function through dbus. But dbus would escape the sandbox Steam had made, and the file name would not be translated, so by the time it reached Firefox, the file could no longer be found (because of the aforementioned mount namespace trickery), and Firefox would just decide to do - nothing. Lovely.

Once I had the file name, though, I could search for the file, and I did find it. And then I looked at it, and the reason it crashed was that the type "System.Console" could not be created.

See, EXAPUNKS was written in C#. And on Linux, it is executed under Mono, of course. And apparently someone at Mono needs to get a kick in the arse. It turns out that if the TERM variable is set to a string the system doesn't have the terminfo for, then Mono will fail creating the System.Console type, with either the exception "There was an exception creating the type "System.Console"", or sometimes the exception is even printed, and then it is a chain of things resulting finally in "Exception: Bad magic number 542." This despite the fact, that in the overwhelming majority of cases, System.Console is only used to print simple strings, and that works the same on all terminals. And because I was using Wayland, my terminal emulator was now called "foot". The terminfo for "foot" was in my local terminfo database, of course, but flatpaks run in their own environments I can't change, and I have no idea how I should do so.

So, closing Steam and restarting it setting TERM=xterm allowed me to get further. Modifying EXAPUNKS' loader script to also set TERM=xterm (because it somehow got reverted when starting the game in Steam) finally allowed the game to work. What was the message printed to the terminal, that was so important it had to crash the application? "The key could not be found in the dictionary", printed 50 times. Not saying what key or what dictionary. Apparently it was read on some kind of timer after starting the game.

There you have it. Gaming is definitely possible on Linux, even with distributions that are definitely not meant for it. Next step for me is going to be to actually start using the two hard disks I have in the system, as additional storage. I have an LVM tutorial queued up already. I'll see how it goes.
Carpe diem!
User avatar
BigBuda
Member
Member
Posts: 104
Joined: Fri Sep 03, 2021 5:20 pm

Re: Blog: Gaming on Alpine Linux

Post by BigBuda »

nullplan wrote:Today I decided to do something productive with my Sunday: After casting my vote in the morning, I decided to get rid of the last Windows installation in my possession.
I'd agree with "something productive"...
nullplan wrote:I have a laptop I use for web (mostly Youtube), e-mail, and development. It's been running Linux since I got it. I also have a PC I use for gaming. Until today, it was running Windows (first 10, then 11). But with Microsoft getting increasingly desperate to squeeze blood from the stone that is Windows, and turning to the dark AI arts to do it (not so long ago, Windows Recall would have been classed as spyware, plain and simple), I decided to get rid of it by installing Linux. And not just any Linux, but Alpine Linux.
Alpine is awesome for the use cases it seems to aim for.
nullplan wrote:I do realize I set myself up for failure here. Not only using the less popular platform, but foregoing glibc, and with it binary compatibility to what few games are supported natively. But I did make it work, for now. It doesn't work very well, but good enough for my purposes. Also, as a Debian user of 20 years, using something completely different definitely was a new experience for me. I keep typing "apt" when I mean "apk", and when running a command as root, my fingers instinctively seek out the s and u keys, before remembering that "sudo" is now "doas". Force of habit. Hopefully after today, I won't be needing that many root commands anymore, though.
I wouldn't say that you set yourself up for failure, but Alpine Linux seems to be for a very specific use case and not as a general use desktop. It's mostly used as a base for routers, switches, NAS and etc. I'd take Alpine Linux over any other for infrastructure projects any day (both network gear and servers). I'm especially fond of the combination of Alpine + LXD or Incus. I can have the base system for a server up and running in a short time, with a very thin layer (~300MB to ~600MB) reducing both the attack surface and the update/failure surface (reducing downtime of the host system) and then isolate all the services in Linux containers (mostly also Alpine except when required otherwise). The base system for those Alpine containers take around 8MB, which are ideal for this use case. For this, Alpine is perfect and if a Glibc base is needed, I can immediately launch a container with any other distribution on it. And if any service experiences catastrophic problems, at worst I can just restart or rebuild the problematic container, without causing any downtime on the host system or any other services.

I have a laptop that I installed Alpine on. Instead of installing the games directly on the host, I installed Steam on a container (Arch in this case) and use the hardware passthrough features of Linux Containers to play. There are even official Youtube tutorials from the LXD team on how to do this specifically for Steam. It wasn't, however, actually meant for desktop, which means that it has a narrow range of desktop choices and packages, even using the community repository (which I always enable, in fact).

I also occasionally have the finger slip to apt instead of apk. Muscle memory, yay. As for sudo, you can have sudo on Alpine, it's available on the repositories as well, despite not being installed by default.
nullplan wrote:Installation was surprisingly painless, though the Alpine installer is nothing for people that break out in hives at the sight of a console. Remember the old Debian installer, before they had the ncurses one? That is pretty much the Alpine installer. But it also has some features Debian is sorely lacking: When being asked to select a package mirror to use (a question you basically have to answer with zero context), you have the option to select the fastest one. That verifies that your internet connection is working, and filters out completely non-working ones as well.
This is one thing I quite like on Alpine also.
nullplan wrote:After installation I finally figured out how to make the BIOS boot from M.2 drive. There is a boot order list in the BIOS, but that did not contain the M.2 drive, so there was no way for me to put it up at the top of the list. Turns out that MSI was just being difficult: The boot order list contains only one entry for each type of drive, and further down you can select which drive is meant for each given type. So in the boot order, I had to put "UEFI Harddisk" at the top, then further down select the M.2 drive as the option for "UEFI Harddisk". Why the indirection? Because they could, I suppose.
Well, the hardware brands like to make simple things difficult.
nullplan wrote:Anyway, I wasn't done doing things the hard way. The base system install has no graphics system, so I decided to install Wayland. That was the first time for me. On my laptop, I am happily using Xorg and awesome. But Wayland is the future, so best to rip the band-aid off in one go. I would have used Hyprland, but Alpine has no package for it, so now I am using sway for the time being. The Alpine wiki makes reference to loading the right graphics modules and stuff, but apparently that is not necessary, as the kernel auto-detects the hardware and loads modules accordingly. I had never really used an AMD GPU on Linux before, so when the Wiki said to just pick "radeon" or "amdgpu" as driver, I was a bit stumped. Turned out not to matter for the above reason, but apparently "amdgpu" is the right one.

Also, when sway reports an error from the amdgpu driver about how it could not create some sort of context, that error message does not matter. Always helpful to have error messages that don't matter.
Some of the documentation on Alpine's wiki is a bit outdated. As I usually say to my students, for any given product there's the holy trinity of documentation when you need it. First it has to exist, then it has to be right, then it has to be up to date. Of the three, choose half of one. But AMD GPUs do work quite well on Linux, including Alpine.
nullplan wrote:The Wiki wanted me to install a greeter. After much back and forth, I had something working, but found that I could not log in. The reason being that my password contains a y, and I have a German keyboard. And if there is a way to set the keyboard layout generally for all Wayland compositors, I could not find it, but they default to American layout. I did set the layout in sway, but the greeter ran under cage, and there was no documentation for changing the keyboard layout in cage.

In the end, I decided to get rid of the greeter. I login with agetty on the command line, then start the graphics server, like it was 1995. Only the graphics server is now called sway instead of xinit.
Can't say I've been through the same. I use XFCE on Alpine and the XFCE session manager and I don't remember having had either problem. I still prefer to use X.org, though. Wayland is definitely not ready for prime time, and not just in stability, but also in the lack of some features, like global hotkeys.
nullplan wrote:Next issue was sound. Apparently, the current hotness is "pipewire". I had only ever vaguely heard about it, and I suppose something must throw a spanner in the works every now and again. After following the Wiki directions, I now have a system that works, but only in sway under dbus. I'm not a big fan of this bundling (why are graphics and sound now entwined?), but apparently it must be done, because pipewire depends on dbus, and I'm not starting dbus twice! The setup I have now works, but only once per boot. Thankfully I rarely log off the system without shutting it down entirely.
Can't help you with this one. Haven't tried pipewire yet.
nullplan wrote:Finally, the games. I decided to go with Steam (obviously). However, the Wiki instructions were somewhat false. It was necessary for me to install Steam in the system flatpak repository along with the user one, because otherwise there would be an error on startup. After doing that, it was possible for me to log in, but I did find that my gamepad was not recognized. That was because even though I had installed the steam-devices package, my user still had to be in the "input" group for SDL to recognize the input devices. God only knows how the compositors kept reading those event files!

My first test case was Solar Ash, a Windows game with no Linux support. Running it under Proton worked pretty much immediately, once the input file kerfuffle was sorted. And the game ran about as well as it did on Windows.

Next test case was EXAPUNKS, a native Linux puzzle game. That one turned out to be much harder, actually. I could start the game, but it would always crash after a couple of seconds. So it was time for me to get the debugger out. And the debugger I used was the only real debugger: strace. Unlike all the others, it does not try to misrepresent reality by claiming that C was BASIC, but rather, it only displays what syscalls the processes are making, and what the results are.

Using strace, I determined that the game was writing a crash report to /tmp. But I could not find it there. After much back and forth, it turns out that Steam does some black magic with mount namespaces and cgroups, and what EXAPUNKS saw as /tmp was actually $XDG_RUNTIME_DIRECTORY/<some longer path here>/tmp. Maybe there was also something going on with bind mounts. Anyway, there was an error message about dbus not containing the OpenURI function, so I was hoping that if I could provide that function, then the crash information would be displayed to me in firefox. That never happened!

First, OpenURI is contained in the XDG GTK portal, so I had to install the package xdg-desktop-portal-gtk. But that one by default provides OpenURI only to GNOME. I am using sway. I had to create an obscure config file to make it work, and then reboot the system. And even then, no crash report, but the error message about the non-existant OpenURI was now gone.

It turned out that EXAPUNKS was crashing and writing a crash log to /tmp/burduke-crash-log.html, then calling "xdg-open /tmp/burduke-crash-log.html". xdg-open would find the file under that name and run the OpenURI function through dbus. But dbus would escape the sandbox Steam had made, and the file name would not be translated, so by the time it reached Firefox, the file could no longer be found (because of the aforementioned mount namespace trickery), and Firefox would just decide to do - nothing. Lovely.

Once I had the file name, though, I could search for the file, and I did find it. And then I looked at it, and the reason it crashed was that the type "System.Console" could not be created.

See, EXAPUNKS was written in C#. And on Linux, it is executed under Mono, of course. And apparently someone at Mono needs to get a kick in the arse. It turns out that if the TERM variable is set to a string the system doesn't have the terminfo for, then Mono will fail creating the System.Console type, with either the exception "There was an exception creating the type "System.Console"", or sometimes the exception is even printed, and then it is a chain of things resulting finally in "Exception: Bad magic number 542." This despite the fact, that in the overwhelming majority of cases, System.Console is only used to print simple strings, and that works the same on all terminals. And because I was using Wayland, my terminal emulator was now called "foot". The terminfo for "foot" was in my local terminfo database, of course, but flatpaks run in their own environments I can't change, and I have no idea how I should do so.

So, closing Steam and restarting it setting TERM=xterm allowed me to get further. Modifying EXAPUNKS' loader script to also set TERM=xterm (because it somehow got reverted when starting the game in Steam) finally allowed the game to work. What was the message printed to the terminal, that was so important it had to crash the application? "The key could not be found in the dictionary", printed 50 times. Not saying what key or what dictionary. Apparently it was read on some kind of timer after starting the game.
Read above. Here I'd definitely advise you to use containers to run Steam. You could set up a Debian or Ubuntu container (ew) or an Arch one. You'd be able to avoid flatpak entirely. As for mono, you might be able to use DotNet Core (not called that anymore - now it's just Dot Net, packages dotnet-runtime and/or dotnet-sdk). The package is in the repository, but make sure to disable telemetry before using it (https://learn.microsoft.com/en-us/dotne ... /telemetry).
nullplan wrote:There you have it. Gaming is definitely possible on Linux, even with distributions that are definitely not meant for it. Next step for me is going to be to actually start using the two hard disks I have in the system, as additional storage. I have an LVM tutorial queued up already. I'll see how it goes.
In my main desktop I'm actually in the process of researching and moving from Manjaro to Alpine, running Xorg itself in a container (yes, it's possible, with Linux Containers PCI Passthrough) and isolating most services in Alpine containers as much as possible, resorting to Arch ones when necessary. It is a pain in the nikta to configure (not that it's hard, just boring) but once installed I'm hoping for a long lasting installation with close to no problem spillover. On the server side, I've been happily using it for a few years, after getting fed up with Ubuntu Server and giving up on the hassle of installing Gentoo (although that was my favorite distribution for almost 20 years). I have also written a few Alpine related tutorials but mostly in Portuguese.
Writing a bootloader in under 15 minutes: https://www.youtube.com/watch?v=0E0FKjvTA0M
nullplan
Member
Member
Posts: 1760
Joined: Wed Aug 30, 2017 8:24 am

Re: Blog: Gaming on Alpine Linux

Post by nullplan »

Sorry for the late reply; things were a bit hectic the last few days.
BigBuda wrote:As for sudo, you can have sudo on Alpine, it's available on the repositories as well, despite not being installed by default.
I know that I could; I did find the package. But the default choice is doas, and I have no specific need for sudo; I only need a way to run root commands without logging in as root.
BigBuda wrote:Wayland is definitely not ready for prime time, and not just in stability, but also in the lack of some features, like global hotkeys.
I'm told the situation with global hotkeys got better, depending on your compositor of course. I saw Brodie Robertson show off his setup once (where he has all sorts of OBS shortcuts set up in Hyprland), but I can't find the video now. The man is very prolific. It's like looking for a specific grain of sand in a desert.

Anyway, yes, with X11, you just set the keyboard layout once in the server config, and then it is in use for everything in the system. With Wayland, each compositor has to read the keyboard on its own, and thus must be told the keyboard layout separately. Funnily enough, the Linux console gets its keys configured by a boot script.
BigBuda wrote:Can't help you with this one. Haven't tried pipewire yet.
I haven't earnestly looked into it yet, because I rarely need to log out on the system, ever. I boot up, log in, play, and shut down. But I suspect something of the earlier instance was left over and not cleaned up properly, holding onto the sound card, so that the new instance cannot do so itself. In that case, all that would be needed is a better cleanup script.
BigBuda wrote:Here I'd definitely advise you to use containers to run Steam.
Well, I run Steam in a flatpak. Is that not sufficiently containerized? I know from the exploration of the crash with strace that Steam and/or flatpak are pulling some deeply black magic with the file system, because of the whole file redirecting thing I simply don't know how they did. It wasn't chroot (because the process root was unchanged). Maybe some sort of bind mount? But I thought you'd need to be root for the mount system call? The mounts table for the game was definitely larger than the one for all the other processes, but I couldn't make heads or tails of it.

Running in a Debian container would likely also not have solved the Mono crash, which was caused by the old Mono version the game brought along and the unfamiliar setting of $TERM. Both issues would be present in any container as well.

BTW, the base system (everything managed by apk) now comes out at 1.5 GB. With sway and everything. Very impressive!
Carpe diem!
User avatar
BigBuda
Member
Member
Posts: 104
Joined: Fri Sep 03, 2021 5:20 pm

Re: Blog: Gaming on Alpine Linux

Post by BigBuda »

nullplan wrote:Sorry for the late reply; things were a bit hectic the last few days.
I'm told the situation with global hotkeys got better, depending on your compositor of course. I saw Brodie Robertson show off his setup once (where he has all sorts of OBS shortcuts set up in Hyprland), but I can't find the video now. The man is very prolific. It's like looking for a specific grain of sand in a desert.
Let's hope so, because most distros are trying to shove Wayland down our throats and it's only a matter of time they start removing Xorg definitely and that'll eventually come to Manjaro as well (the one I use as my main desktop).
nullplan wrote:Well, I run Steam in a flatpak. Is that not sufficiently containerized? I know from the exploration of the crash with strace that Steam and/or flatpak are pulling some deeply black magic with the file system, because of the whole file redirecting thing I simply don't know how they did. It wasn't chroot (because the process root was unchanged). Maybe some sort of bind mount? But I thought you'd need to be root for the mount system call? The mounts table for the game was definitely larger than the one for all the other processes, but I couldn't make heads or tails of it.

Running in a Debian container would likely also not have solved the Mono crash, which was caused by the old Mono version the game brought along and the unfamiliar setting of $TERM. Both issues would be present in any container as well.
It's reasonable to accept the possibility that a certain framework will react differently to different base systems, especially where LIBC is involved, namely because Alpine uses MUSL instead of GlibC. It may not make any difference, but then again, without trying, who knows? In any case, I avoid both Flatpak and Snap. I'd rather have native distribution packages for everything and containerize as needed. Linux Containers is a bit different from Flatpak in this case. For instance, I assume Flatpak as well as Snap both mount some type of overlay filesystem so that the applications can access the user's documents. Personally, for a few applications - Steam is one of them because it's loaded with components that cannot be properly audited easily, as are the games - I'd rather have them in Linux Containers and not give them any access to my files or any other privileges at all (because there's always "DRM" and "anti-cheat"... "functionality" - cough cough). I do know that any protection system can eventually be broken, and a jailbreak might occur in a container, but so can it be done in a VM, and other types of attacks exist between discrete physical machines. If left unattended, it's always just a question of "when" and not "if", but until then, or until an update, there's at least some isolation.
nullplan wrote:BTW, the base system (everything managed by apk) now comes out at 1.5 GB. With sway and everything. Very impressive!
Yeah. that's one thing they're really good at. Besides, it loads really fast and the fact that it's free of systemd makes it even sweeter.
Writing a bootloader in under 15 minutes: https://www.youtube.com/watch?v=0E0FKjvTA0M
User avatar
eekee
Member
Member
Posts: 872
Joined: Mon May 22, 2017 5:56 am
Location: Kerbin
Discord: eekee
Contact:

Re: Blog: Gaming on Alpine Linux

Post by eekee »

Interesting, especially I was just thinking of installing Linux on my old tower to run a couple of games. (It has better graphics than my laptop.) On reading this... :)

I can understand Mono needing to know the terminal type. It doesn't know when it'll be called on to emulate certain features of Windows consoles. Ignoring the issue until its needed would be terrible; a program might want one of those features for the first time when its user is in the middle of something. Mono couldn't just crash the program there and then, expecting the user to drop what they're doing and fix it. The only good solution is to make sure the terminal is configured correctly up front.

I know exactly how annoying it is to receive explanations like that. :twisted: I'm sick of it. After about 20 years of these frustrations, on many issues I find myself blaming POSIX itself for it's hacked-together, least-common-denominator, historically-tainted architecture. All of these accusations apply more to terminal handling than any other part of the system. The operating system should know how to drive its hardware, and that includes terminals.

Besides this, I was happy when OpenBSD produced doas, thinking it'd be easier to set up than sudo. Coming back to POSIX recently, in the form of OpenBSD, I find doas is just as complex as sudo but with documentation which is harder to follow. Likewise for tmux and screen. I'm disinclined to trouble myself with them, and that means I make less use of POSIX operating systems or, again, terminals.

On the other hand, Windows has its own horribly useless error messages. :) I was doing something witch batch files the other day, when Windows reported, "The system cannot find the file specified." This is exactly as useful as 1970s Unix's, "Not found"! :lol:
Kaph — a modular OS intended to be easy and fun to administer and code for.
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
Post Reply