<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="makerobfeed/1.1" -->
<rss version="2.0"
>
  <channel>
    <title>Rob Landley's Blog Thing for 2025</title>
    <link>http://www.landley.net/notes-2025.html</link>
    <language>en</language>

  <item>
   <title><![CDATA[September 22, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#22-09-2025</link>
   <pubDate>Mon, 22 Sep 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>I have not been blogging for a while, because the world's on fire.
While I don't exactly want it to burn, I DO kind of want to check back in
when <a href=https://mstdn.jp/@landley/115255466834883648>the last
Boomer is dead</a> and the american dollar has lost its position as the
<a href=https://mstdn.jp/@landley/115171196282751924>global reserve currency</a>
and no longer gets used to
<a  href=https://mstdn.jp/@landley/115221729730561951>colonially</a>
impose
<a href=https://mstdn.jp/@landley/115165724358112596>victorian
prudishness</a> on the entire world, and both
<a href=https://mstdn.jp/@landley/115169499324406095>christianity</a>
and its <a href=https://mstdn.jp/@landley/115147176149028234>successor</a>
religion <a href=https://mstdn.jp/@landley/115159511957190450>capitalism</a>
go on the trash heap next to the <a href=https://en.wikipedia.org/wiki/Asebeia>worship of Zeus</a>
and the <a href=https://en.wikipedia.org/wiki/Slavery_in_ancient_Rome>Pax Romana</a>.</P>

<p>I've been posting a little to mastodon (and even
put up my own <a href=https://landley.net/toot/>archive</a>, which I
should probably break into years and link from the top level page, which
I haven't touched in well over a decade), but fell over 2 weeks behind on
email because I just didn't want to open my laptop.</p>

<p>What happened: I finally got my driver's license switched over from Texas
to Minneapolis, at which point mail delivery stopped for a month because
the local postmaster insists that you MUST DOX YOURSELF IN YOUR MAILBOX
or no mail will be delivered (except it _was_ delivered for the first month?)
so apparently sending stuff to a PO box with no name at the top is no
longer allowed in St. Paul or something. Presumably junk mail to
"resident" no longer gets delivered? So I dunno if the new license
has yet to arrive, or bounced. I dunno which forwarded mail from the
old place bounced and needs recovery somehow? I managed to scrape up the
spoons to go down to the post office once and try to sort it out, but
they just explained the "policy". No fix for the already bounced mail...</p>

<p>I attended a labor day protest protest, because that's spite not ambition,
but the <a href=https://www.fiftyfifty.one/events>no kings</a> organizers
seem fucking useless (I'm intentionally swearing more in honor of Visa
and Mastercard and Project 2025: <a href=https://www.youtube.com/watch?v=1rP-U-ZbuzE>deal with it</a>)
and they didn't link to the gun control rally 2 blocks from my house and
instead said the protest at the airport (Delta's pilots union being mad
at Delta, in an UTTERLY TINY concrete sidewalk between pavement and
a building) was _the_ protest. Better than not protesting, but I
miss having good info.</p>

<p>I interviewed for a job out in a suburb west of Minneapolis, which
I originally wasn't interested in (despite the tech seeming
right up my alley) because Google Maps INSISTED there was no way to
get from here to there via public transit, when there
<a href=https://swtransit.org/686/>totally is</a>, even an end to end
<a href=https://swtransit.org/sw-prime/>shuttle service</a>, and get this:
it all uses the same monthly bus pass Fade's already using for HER commute
to work. And Google still hasn't noticed it exists.
(I miss Google. Those 12k people they fired were load bearing
and it has spiraled WAY the hell down since then.)</p>

<p>I keep saying if I want to save for retirement I should just go stock
shelves at Aldi's, because I _know_ they're not actively evil (like
T-mobile they're <a href=https://en.wikipedia.org/wiki/Deutsche_Telekom>owned by germans</a>
who are largely secular including about capitalism),
the commute is a 5 minute walk, it's exercise, at the
end of the day I could say <a href=https://en.wikipedia.org/wiki/Bullshit_Jobs>what I'd done</a>
to make people's lives better (or at least not WORSE) and thus presumably
sleep better at night, and they even offer <a href=https://careers.aldi.us/benefits>dental</a>.
(We're just about breaking even on just Fade working full time, but
not saving for retirement. I don't trust social security to still be
there and recently learned that my sister STILL hasn't fully paid off
her student loans... raising 4 kids after your husband divorces you for
$BLONDE du jour will do that, I guess. I would LOVE to go back to work
for Jeff full time but he's prioritized his funding for the japanese
condingent, and I can't say I blame him: I'd prioritize non-US workers in
the current environment too. There's a sort of "opposite of ITAR" going on
among asian and european high-tech customers this year.)</p>

<p>Yes I could do Rust and Python 3. Yes I could smile at Google
<a href=https://www.reddit.com/r/GooglePixel/comments/1n0h5cp/google_is_removing_the_ability_to_sideload/>removing
sideloading</a> while the EU is once again trying to <a href=https://home-affairs.ec.europa.eu/news/commission-presents-roadmap-effective-and-lawful-access-data-law-enforcement-2025-06-24_en>outlaw Signal</a>
by mandating backdoors in all encrypted communications.
(Requiring developer verification with government issued ID is functionally
equivalent to banning the installation of apps not legal within your
jurisdiction.) But I spent my programming career chasing FUN, and all
that just isn't.</p>

<p>Linux paid nothing before about 2002, 4 years after
I switched to it as my full time desktop OS and development environment,
and it paid less than Windows work did for another decade after that.
When Unix was 30 years old, it was geriatric and dying full of arrogant
greybeards defending their niches. Linux is now 35 years old,
and the osteoperosis is <a href=https://www.theregister.com/2024/07/15/opinion_open_source_attract_devs/>not a secret</a>.
(Yes, that is a DIFFERENT "greying of linux" article from the the
one the same author wrote <a href=https://www.zdnet.com/article/graying-linux-developers-look-for-new-blood/>ten years earlier</a>,
but it's not just him. Linus's <a href=https://knowyourmeme.com/memes/how-do-you-do-fellow-kids>embrace</a> of rust and LLM code has been an
<a href=https://linux.slashdot.org/story/24/09/16/2047217/linus-torvalds-muses-about-maintainer-gray-hairs-next-king-of-linux>explicit strategy</a>
to attract younger developers, which like all the previous attempts
<a href=https://knowyourmeme.com/memes/how-do-you-do-fellow-kids>hasn't
really worked</a>. The average age of Linux developers has always been
the same as Linus' age, and even he
<a href=https://www.businessinsider.com/profile-linus-torvalds-inventor-linux-software-operating-system>acknowledged this</a> as a problem a few years
back.</p>

<p>And now Linux is turning into the "here's a nickel, buy a real computer"
unix community from the old Dilbert cartoon (back before yet another middle
aged financially comfortable white male ossified into a loon) and I'm
just not interested.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#22-09-2025</guid>
  </item>
  <item>
   <title><![CDATA[September 8, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#08-09-2025</link>
   <pubDate>Mon, 08 Sep 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Noticed the "basenc" command and considered adding it, but
"echo hello | basenc" says I have to specify an encoding type (no default)
and it only offers --longopts not short options, which made me lose interest.
(Too gnu/dumb to live. That's not unix.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#08-09-2025</guid>
  </item>
  <item>
   <title><![CDATA[September 3, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#03-09-2025</link>
   <pubDate>Wed, 03 Sep 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Posted publicly about how <a href=https://lists.landley.net/pipermail/toybox/2025-September/009803.html>disgusted I am with Google</a>.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#03-09-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 27, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#27-08-2025</link>
   <pubDate>Wed, 27 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Ok, find -depth and -xdev are already acting global, and the
-mindepth/-maxdepth "global" behavior is crazy:</p>

<blockquote><p>
$ find toys -name x -o -mindepth 2 2&gt;/dev/null | wc -l<br />
277<br />
$ find toys -name x -a -mindepth 2 2&gt;/dev/null | wc -l<br />
0
</p></blockquote>

<p>And <b>find . \! -maxdepth 2</b> is also always-fail.
The "global" argument is acting as an always-true NOP with a second
(unrelated!) test done at the start.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#27-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 25, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#25-08-2025</link>
   <pubDate>Mon, 25 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Bug report in find, the OTHER side of the "warning: you have specified a global
option" spam gnu/stallman/ftaghn emits. I'm already parsing the command
line in two passes, so the first pass needs to set flags for this and
then implement the behavior at the start of the loop.</p>

<p>The find man page says the global options are -d/depth, -maxdepth, -mindepth,
-mount/-xdev. (And several others like -noleaf and -noignore_readdir_race
which just should not exist, and of course --help/--version which are
handled separately and it claims to have a single dash version of which I
don't care about.) I'd probably implement -files0-from if it didn't
have such a dumb name, but... dude. No.</p>

<p>No, -files0-from is not a typo.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#25-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 24, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#24-08-2025</link>
   <pubDate>Sun, 24 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Spent the day over at my sister's going through Mt. Boxmore. Got one and
a half boxes emptied, burning quite a lot of it (did EVERYTHING printed in
1998 have your social security number on it?) and took two boxes and one
packed suitcase back to sort at the apartment.</p>

<p>Plus I abducted three pots of her dirt for our new porch. I'm hping to
grow my own tomatage instead of paying over $1.50/pound for romas
harvested so green they're cardboard.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#24-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 23, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#23-08-2025</link>
   <pubDate>Sat, 23 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Did a full build of all targets, I think I have the patches to make 6.16
work. I should cut a release with what I've got.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#23-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 22, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#22-08-2025</link>
   <pubDate>Fri, 22 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I am NOT posting a <a href=https://lore.kernel.org/lkml/2025-08-22-witty-worthy-wink-sitcom-T5L8wA@cyphar.com/>snarky reply</a>, I am instead
blogging it. (And yes finding that was a pain, I can't
ctrl-f for my name in lore.kernel.org's backscroll, I have to "view source"
on the specific message and cut and paste the message ID out of the
headers, which is not "msgid" as I keep thinking, but spelled out.)</p>

<blockquote>
<p><b>
&gt; I'm not sure what issue you're gesturing to exactly, but if you have the<br />
&gt; Message-ID you can link to it directly with<br />
&gt; https://lore.kernel.org/lkml/$MESSAGE_ID . For instance, this email<br />
&gt; will be available at<br />
&gt; https://lore.kernel.org/lkml/2025-08-22-witty-worthy-wink-sitcom-T5L8wA@cyphar.com
</b></p>

<p>If I have the message ID I can put that into the search bar on any search engine, yes.</p>

<p>Having local archives mitigates the ongoing loss of web discoverability as the community becomes more insular and favors the seniority of existing participants. Classic organizational senescence, sad to see it happen to ones I lived through but I'm getting up there myself...</p>

<p>(I'd say "using vague recollections and awareness of relationships between things to find stuff" is also a sign of age, but I was doing that in high school...)</p>

<p><b>
&gt; Also, lore.kernel.org has threading on the main page and on individual<br />
&gt; thread pages? Maybe I don't understand what you're referring to?
</b></p>

<p>If I remembered reading an email where probably Thomas Gleixner was replying to probably Linus about some idiosycrasy of io queue flushing heuristics between christmas and my birthday of I think 2022 (or similar trail of breadcrumbs in my blog, or a post on another list referring to but not linking to a conversation elsewhere), I used to be able to go to the lkml.iu.edu page, click on each week of january, and ctrl-f for gleixner or torvalds until I saw a message where he's replying to Linus and the subject looked relevant, then read it to see if that was it. (And if not try february, or 2021, or...) Especially in long threads, the relationships between the parts I half-remembered helped me fish out the specific message I wanted.</p>

<p>Scrolling back to a specific historical timeframe at all on the two surviving web archives is awkward, and the thread view doesn't say who authored the message (nor what timeframe of replies are collated).</p>

<p>*shrug* I eventually get used to the tools I have available, just lamenting the loss of something good because somebody reinvented the user interface wheel again. Happens. Not the first time something familiar and convenient went away to be replaced by pounding nails in with the back of a spoon. Lateral "progress" is always with us...</p>

<p><b>
&gt;&gt; lore.kernel.org somehow manages not to list "linux-kernel" in its top level<br />
&gt;&gt; list of "inboxes" at all. The wagons are circled pretty tightly...<br />
&gt;<br />
&gt; No it's definitely there, it's just labeled as "lkml" (they're sorted by<br />
&gt; latest message timestamp so LKML will usually be near the top).<br />
</b></p>

<p>The email you send to is linux-kernel@vger but it has a special case name in the list, which those in the know can find. Of course.</p>

<p>Personally, I'm not comfortable when the trick to searching for something is to already know the answer. (For example, rootflags= and rootfsflags= would sort alphabetically adjacent in kernel-parameters.txt so finding one would let you know about the other, but now it's been "improved" so you have to know initramfs_options= exists and is different from rootflags= because special case. Fine. Why not.)</p>

<p>*shrug* I stopped trying to swim upstream here a while ago. I just got cc'd on this for historical reasons...</p>
</blockquote>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#22-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 21, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#21-08-2025</link>
   <pubDate>Thu, 21 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I updated scripts/recreate-prereq.sh to work with the new kconfig
plumbing, but hit a missing bit in the new kconfig plumbing (allnoconfig
wasn't honoring KCONFIG_ALLCONFIG overrides). Took a while to figure
out what exactly was wrong...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#21-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 20, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#20-08-2025</link>
   <pubDate>Wed, 20 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Huh, lkml.iu.edu is down. I'm assuming it has something to do with the
<a href=https://www.nytimes.com/2025/06/05/us/republicans-indiana-public-universities.html>mass resignations</a>
and general unreliability of US-hosted infrastructure.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#20-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 17, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#17-08-2025</link>
   <pubDate>Sun, 17 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>And my laptop rebooted. The reason was I did a "git checkout v2.6.0"
in my one-big-git tree (because I couldn't remember Andre Hedrick's name),
and told thunderbird to download email at the
same time, and the two of them threw Linux so deep into swap that ctrl-alt-f1
couldn't give me a text console (to kill git) for 30 minutes, at which
point I held down the power button. (Jeff is convinced that gitea can't
serve linux repos because I used my one-big-linux repo as a test
load and the git process the server spawned ate all the system's ram
when we tried to clone it. There's some sort of bug or N^2 behavior
in git that gets triggered by this repo...)</p>

<p>I miss when the OOM killer actually worked. The system was stuck swap-thrashing
and completely unresponsive for half an hour before I declared it dead,
the hard drive light on the entire time (and it's an SSD, not spinning rust).
The mouse cursor did not move once, nor did any part of the display
update.</p>

<p>But they're sure they "improved" it, because the OOM killer USED to trigger
and that was bad, mm'kay. If the OOM killer had triggered, it might have
cost me some of my open windows, instead of closing ALL open windows
in all 8 desktops, and all the command line history, and the partially
composed thunderbird replies, so on.</p>

<p>Sigh, what was I in the middle of doing again...?</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#17-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 16, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#16-08-2025</link>
   <pubDate>Sat, 16 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Ooh, <a href=https://github.com/squeek502/zua>a 0BSD reimplementation of Lua
in Zig</a>. Tried to install zig (wouldn't mind an excuse to learn) to try
it out, but... zig is not in the debian repository?</p>

<p>Hmmm... Zig's web page (sadly on
<a href=https://github.com/ziglang/zig/wiki/Install-Zig-from-a-Package-Manager>ratelimithub</a>)
says the project's not at 1.0 yet and lists a bunch of distros you can
get it out of the repository of... alpine, arch,
fedora, freebsd, gentoo, SuSE, openbsd, mac homebroew, manjaro, mandrivia,
void linux, even slackware... but no mention of debian.
A reddit thread from <a href=https://www.reddit.com/r/Zig/comments/q0riwu/resurrected_deb_repo_ticket_for_mainline_deb/>4 years ago</a>
points at a debian bug thread that's still open, which says another
bug was merged as a duplicate of that one (lots of people wanting zig)
but Debian has of course done nothing.</p>

<p>I wouldn't call this a problem with zig, I'd call this a sign of poor
health at Debian. I've HEARD of zig for years,
one of the "go, swift, oberon..." crowd aiming to
replace the qwerty keyboard of C. I've never had a zig developer be dickish
about it in rust's patented "how DARE you not already be using the One
True Language for everything!?! HERETIC! UNBELIEVER!" manner, nor
attempting to hijack existing projects written in a different language
and convert them by force, which is why I'm interested in taking a look
at zig. (I'm fine learning new things. If I was willing to be coerced I'd be
posting about windows on facebook.) Everything I've heard fromm zig devs
is about how cool they thing zig is, not how they can't tell the difference
between C++ and C and thus hate widely and indiscriminately.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#16-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 15, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#15-08-2025</link>
   <pubDate>Fri, 15 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I was looking at <a href=https://github.com/search?q=license%3A0bsd&type=Repositories&ref=advsearch&l=>0BSD licensed repositories</a> and
Microsoft Github rate limited me. And 15 minutes later the rate limit was
still in place, because I hadn't logged in to the website.
(Which I can't do without 2FA, which ain't happening.)</p>

<p>Sites that stop being anonymously world browseable deserve to stop
getting new users, and then go the way of faceboot with an aging userbase
circling the wagons/drain. The main thing I can do to speed up the process
is stop using them myself, to diminish their network effects.</p>

<p>That said, this site has the info so I'll probably reload the tab
tomorrow...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#15-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 14, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#14-08-2025</link>
   <pubDate>Thu, 14 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>The toybox "readahead" command is subtly borked in a way I _actively_
don't want to have to care about, AND YET.</p>

<p>The problem is that passing a 64 bit value on 32 bit platforms with syscall()
has some hiccups calling older syscalls on some 32 bit architectures, and this
one is used as the _example_ in the the "Architecture-specific requirements"
section of "man 2 syscall".</p>

<p>Some 32-bit processors can only handle 64 bit values using even register
pairs, and eight old syscalls didn't arrange the argument order to
naturally align, so require architecture-specific padding, which the
libc wrapper inserts. Using the wrapper is less ugly than architecture
specific whack-a-mole in toybox, even working around glibc's refusal to
provide the prototype unless we declare Linux to be somehow owned by the
Free Softare Foundation... which was why I used syscall() in the first place
rather than fiddle with the prototypes.</p>

<p>The thing is, musl provides the prototype with _ALL_SOURCE, and in theory
if you match musl's prototype closely enough it doesn't complain. In
PRACTICE a lot of C headers stuff goes out of its way to use (inexplicably!)
use "long" on 64 bit platforms and "long long" on 32 bit ones, which
ARE THE SAME on LP64 systems but the compiler barfs about a distinction
without a difference. And unfortunately, musl's prototype uses off_t which
is one of those symbols that switches between the two so if I say
"long" it builds on 64 and if I say "long long" it builds on 32 bit.</p>

<p>Unfortunately, if I say "off_t" I'm still not quite safe because
musl's prototype is wrong. The syscall is defined in the man page with
off64_t (always, unconditionally, 64 bits) but musl uses off_t. The difference
is _LARGEFILE64_SOURCE which is the old open(name, O_LARGEFILE) nonsense from
the 1990s when file sizes first passed 2 gigabytes and an int wasn't big
enough to represent a file offset anymore.</p>

<p>Everything everywhere should have been using that by the time c99 came out
(let alone c11): the need to specify it WENT AWAY 30 YEARS AGO, but the legacy
gnu/dammit nonsense never threw the switch. (Well it's one of the zillion
things they special case with <b>#define _GNU_SOURCE_FTAGHN
ALL_HAIL_STALLMAN_IA_IA_WE_OWN_LINUX</b> but hell no.) I _think_ lib/portability.h
#defining _FILE_OFFSET_BITS 64 at the start of portability.h should also cover
it, BUT that doesn't make off64_t show up. (Nor does _ALL_SOURCE, which
means _ALL_SOURCE lies.) To get THAT (in musl) I'd need to
#define _LARGEFILE64_SOURCE which SEEMS LIKE THE SAME THING and yet somehow
isn't. (There's like 5 different Large File Support macros, all #defining
and #undefining and #ifdeffing each other in giant horrible staircases
in the glibc headers. I think the gcc headers under /usr/lib/gcc are
involved somehow too? (In the $ARCH-ftaghn directory, subdirectory]
$MAJOR_BUT_NOT_MINOR_VERSION, and then there's an #include under there
that you can check for things that are neither in /usr/include nor show
up in the "<b>:|cc -dM -E -</b>" list of builtin #defines.)</p>

<p>I really don't want to HAVE to know any of this, I just wanted readahead.c
to call readahead(). But I won't #define _STALLMAN_IA_IA for the same reason
I don't have a faceboot account, do not use windows, and will not be
scanning my ID for things like youtube.</p>

<p>(Today two links have popped up the
youtube app, despite me removing it from my phone's desktop yesterday
morning. I closed it both times before it really resolved whether or not
I was allowed to watch the video. If it pulled up the website as an anonymous
user I'd probably have let it go to see what happened. I can't uninstall
base OS apps from stock Android, but I should at least figure out how to
delete the association with the app so it stays in the browser.)</p>

<p>I'm so glad they could fix my phone. I'd have to care about GrapheneOS
or similar otherwise. (I showed my sister where "system safety core"
and the key uploader were on her phone, and it wouldn't let her delete them
because her Android version is too new. My brother's phone has a virus
checker that prevented them from installing in the first place.)</p>

<p>I suppose since the China tariffs got TACO'd yet again I should maybe
order this year's $200 motorola phone that can take an SD card and has
a headphone jack, just to have it ready for when I _do_ inevitably have
to come up to speed on LineageOS or whatever's current by then.</p>

<p>Anyway, toybox commit a3e5f1b1eaf2 which I haven't uploaded yet in part
because I <a href=https://mstdn.jp/@landley/115023782984779498>made
an account on codeberg</a> and haven't set it up yet. (Everybody
with a self-hosted site is complaining it's getting flooded by
AI scraper bots, and I dunno how dreamhost is about defending against
that...)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#14-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 13, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#13-08-2025</link>
   <pubDate>Wed, 13 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>It's mildly ironic that the day of the youtube boycott my phone's
unable to charge and almost out of battery. It's been funky about charging
since Monday, hallucinating an "unsupported audio device" in the slot
which is apparently a symptom of either a bent pin or fluff shorting
out a contact. It went from being unable to fast charge (not a big loss)
to being unable to regular charge (slow charge only) and last night it
couldn't even slow charge.</p>

<p>I took it in to the phone store where I got the port replaced in 2023
(CPR whatsis at the university, my laptop has no net at the moment
because no phone to tether to), and they said they'll replace the port
again under warantee, so yay.</p>

<p>The powerpc build was broken by <a href=https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f50b45626e05>a commit</a>
pulling in the same
stupid ELF library dependency that x86-64 grew. The easy fix is to
just yank the "select HAVE_STATIC_CALL_INLINE" from arch/powerpc/Kconfig,
the result boots and seems to run fine. (It's an unnecessary optimization,
doing some time of static PIE linking thing? Way back when I just assumed
everything was relative to dedicated base registers for each major segment
instead, but it seems to want to traverse ELF tables at runtime?
I've never quite dug through how static position independent executables
handle linking themselves, it kinda has to link in some subset of the dynamic
linker into the binary and then traverse its own ELF tables while running,
presumably replacing _start with something that calls the linker before
calling any other code that's going to care. I suppose I could just go
read it, but don't really want to.)</p>

<p>I was a little worried the powerpc linker code this commit added would
go nuts on uninitialized data, but presumably the list it wants to
traverse is empty. So that's a one line fix at least for this release.</p>

<p>The PROPER fix, for this and x86-64 both, is to dig into objtool and port
it to do its own ELF traversal and not need this stupid external library.
(The toybox readelf and friends already DO, it's not hard.)
But again, I don't really want to: modern linux code and community are a mess
and entirely unrewarding to ever touch.</p>

<p>Trying to test the new Ethernet driver for j-core, but after digging up
an sd card sled that actually _works_ (the one I had went bad, no idea why,
just dmesg saying "Internal clock never stabilized" followed by a large
useless register dump), I then had the problem that the first sd card I
grabbed (containing the chinese OS for the Orange PI) wasn't formatted in
a way the Turtle bootloader recognizes. Probably FAT32 instead of
conventional FAT, or something like that.</p>

<p>Retrenched to the Library (the Rondo Library at the Dale stop of the
Green Line, they've got their own free parking garage, and apparently
give free lunches for kids under 18 over the next month according to
the sign on the door, you'd think this place would be packed solid but
people pay to sit at starbucks instead, dunno why). They get credit for
me going through the little people scanner (and have the bathroom keys
on the inside of the scanner but the bathrooms on the outside, I see
what you did there) which counts towards their usage which gets them
funding, so I think spending time here actually helps them out.</p>

<p>The turtle with that SD card I have with me never says that it's trying
to load anything, just spits out the GDB loader
dump it produces when there's no sd card recognized. I've long been
tempted to just write a dumb little tool that connects to the serial port,
reads a local ELF file, and pushes the segments into the turtle's memory
and jumps to the start. I haven't got a clue how, but it doesn't seem
like there's a lot involved.</p>

<p>The bootloader source I have lying around has a main.c that is
absolute #ifdef salad. The first think the ELF loader section does
is try to load the device tree from the floppy, which I _know_ the turtle's
version isn't doing (it provides a DTB from the ROM image), but there's
a sharp edge for my plan: I have to load the DTB start address into
the right register bbefore launching the kernel, which means I need to
either write a DTB (of course the turtle DTB isn't checked into the kernel
source, I found out during my last go at this trying to write a kexec for
turtle that the turtle device tree source is in <a href=https://github.com/j-core/jcore-soc/blob/master/targets/boards/turtle_1v1/board.dts>the VHDL
package</a>,
so it can build it into the ROM. Still dunno where it lives in memory but I
can either track it down or ask Jeff when he wakes up.</p>

<p>Now I'm reading through the <a href=https://github.com/j-core/bootrom/blob/bfcdcb00880a/gdb/gdb.c>ancient</a>
GDB loader source, which starts with a big comment attempting to explain
the protocol. GDB protocol transactions are <b>$DATA#XX</b> where "DATA" is your
command byte and any arguments, and the XX is a two byte hex checksum
(in its primordial meaning of "add together all the bytes of the data and
use the bottom 8 bits"). The receiver will write back a + if the checksum
is correct and - if it wasn't. The hex uses lower case letters.</p>

<p>It's possible the return values (other than the + or -) are also
encapsulated in the $BLAH#XX format? Dunno yet, the protocol might or
might not be bidirectional that way. (If I reply with - would gdb
retransmit its reply? I highly doubt the bootloader code is doing anything
fancy.)</p>

<p>The commands are:</p>

<ul>
<li><b>g</b> - reads all registers, you get back a big fixed length hex dump
of all the register contents ("in the internal order for gdb" which I'm
assuming is 8 characters each of r0 through r15.</li>
<li><b>G</b> - write all registers, gotta follow it with the same big hex dump
the read command produces. It replies OK for success or starting with E for
error. (Ther eare presumably numbers after that but eh?)</li>
<li><b>Pn...=r...</b> - write register n with value r. Do you actually include
r and n or just the numbers? Is n hex or decimal? The r is hex, appropriate
number of digits for the register size.</li>
<li><b>mADDRESS,LEN</b> - read LEN bytes of memory starting at ADDRESS,
returns a hex dump of the contents (which can be shorter than requested
but doesn't say why, I'm assuming memory fault?) or E something on error.</li>
<li><b>MADDRESS,LEN:XX...</b> - the write version of m's read,
followed by : and then the hex payload.</li>
<li><b>XADDRESS,LEN:...</b> - a write command that just sends the literal
data instead of hex encoding it.
<li><b>cADDRESS</b> - continue from address (a goto), if no address
resumes from the last breakpoint.</li>
<li><b>sADDRESS</b> - single step, I don't think we've implemented that yet.</li>
<li><b>?</b> - ask why we stopped (replies SXX with the signal number).</li>
<li><b>tAA:PP,MM</b> - search backwards from address AA for pattern PP
using mask MM. I have no idea what kind of pattern or mask are involved here,
but I'm guessing the backwards means it's for finding stuff on the stack?</p>
</ul>

<p>Note that c and s both send the same SXX when they break into the debugger,
and we can ALSO get <b>TAAn...:r...;n:r...;n...:r...;</b> where
AA is the signal number, n... = register number, and r... = register contents.
(Or we could get <b>WXX</b> if the process exited, with its exit status, which
isn't something a hardware debugger is going to do. And the client can say
<b>Otext</b> to print a string out on the gdb console, which again seems
unlikely to come up here.</p>

<p>And responses can be run length encoded using *, which repeats the previous
hex digit (nybble, not byte) by the second byte minus 29. (So "0* " means 0000
because space is 32 and 32-29 is 4. A run length of less than 4 is just sent
literally and everything up through ascii 126 I.E. ~ is printable, so... ok?
Seems almost exclusively a way of dealing with long runs of zeroes, but sure,
why not.)</p>

<p>So what I need is several <b>$XADDRESS,LEN:...#XX</b> commands to load
the ELF segment data, then some <b>$Pxx=xx#XX</b> commands to set up
register values, then <b>$cADDRESS#XX</b> to jump to the start of it,
then exit so <b>tool vmlinux &amp;&amp; microcom</b>
can fall through to microcom.</p>

<p>Assuming I can either figure out where the device tree binary lives in
the ROM image, or I can feed my own into the tool, or statically link it
into the kernel, or...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#13-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 12, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#12-08-2025</link>
   <pubDate>Tue, 12 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>Editing a zillion old blog entries before youtube goes away and I can't
verify that the link to the video I saved actually goes where I
think it does.</p>

<p>There's apparently a boycott tomorrow. I'm <a href=https://mstdn.jp/@landley/115018072473713022>thinking of</a> just uninstalling
the youtube app on my phone. I could theoretically still watch some
youtube videos on my laptop (after the boycott day, anyway) but I've
never logged in to youtube on my laptop (because no) so it's all
anonymous browsing. No subscriptions, no to-watch lists, no history or
likes giving the algorithm a hint what to show me more of...</p>

<p>Search is a hard problem, one which slashdot's comment section addressed
surprisingly well back in the 1990s by handing out 'moderator points' to
users (randomly, 5 at a time, I think I got some twice?) who could spend them
promoting good comments (or voting down bad ones), without making it a full
time gig or really gameable. Google followed up a few years later with
the original pagerank algorithm, based on the observation that sites that
link to something were upvoting it, and sites that link to the linkers
are upvoting them as authoritative (so second derivative credibility).
Which alas the forces of capitalism immediately gamed and turned into an
arms race. The metric became a target, Goodhart's Law applied. (Spammers are
just the advertiser cheap sets, trying to get their message in front of you
without as much money to spend as the big boys, it's otherwise EXACTLY the
same thing, and it's because THEY are trying to make money. Money corrupts,
absolute money corrupts absolutely.)</p>

<p>Capitalism is the modern religion that replaced The Church as
"the organizing principle behind everyone's lives". God botherers still
knock on doors to hand you copies of the watchtower, the door to door
salesmen of god. (Omnipotent, omniscient, omnipresent... invisible?
Is in hiding for some reason, allows evil, inexplicably needs YOU to
run errands and spread "the word", never even sends one of these angels
that old book* says used to show up to hotel clerks and farm hands to
resolve major theological disputes. How is a lack of information "free will"
again? If Michael and Gabriel didn't show up to Vatican II, maybe you're
just making all this up.)</p>

<p>* No, not the Illiad. No, not the egyptian book of the dead. No not the
Elder Eddas. No not the ancient indian, chinese, or japanese writings
about their gods. No not the preserved aztec and inca writings. Strangely,
the local god of the east shore of the mediterranean (well, one of them
anyway) doesn't show up in
anybody else's writings. The people went everywhere, regularly displaced
by being on the major invasion route between the greek, egyption, persian,
and roman empires and thus selectively pressured to making their religion
portable. Just a coincidence, of course...</p>

<p>Anyway, capitalism's become as much of a problem as the crusades, spanish
inquisition, divine right of kings, witch burning, blood libel,
and so on were when the previous religion was past its sell-by date.
The religion of numbers insists that billionaires are superior people
with the right to pass all their wealth and power to their heirs untaxed,
Citizens United was "one dollar one vote", corporate personhood... Nobody's
nailed 95 theses to Larry Ellison's door yet. But the censorship is gearing
up to make sure the modern iteration of the printing press can't distribute
any copies if they do. Gotta samizdat them.</p>

<p>Spent $3.50 on some headlight repair tape at the auto shop across
the street, but it was so old it's stuck to the backing. (The electrical tape
I had across my phone's front facing camera got old and fell off, and the roll
is packed in the storage cube.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#12-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 11, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#11-08-2025</link>
   <pubDate>Mon, 11 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=home>
<p>Ok, hopefully we've FINALLY gotten the tax lady all the info we needed.</p>

<p>The reason the library was closed was "staff shortage". Which I believe
means somebody called out sick and they're running on a skeleton crew.
One of the few third places left, and it's hanging on by a thread. Wheee.</p>
</span>

<span id=politics>
<p>And the cyberattack on St Paul (the State Capital of Minnesota) is now
confirmed to be <a href=https://bringmethenews.com/minnesota-news/mayor-says-ransomware-caused-st-paul-cyberattack-but-city-didnt-pay>ransomware</a>.
The FBI is, of course, <a href=https://bringmethenews.com/minnesota-news/hackers-post-43-gigabytes-of-st-paul-data-after-city-refuses-to-pay-ransom>doing nothing</a>.</p>

<p>Sigh. Russia is making drones and launching them at Ukraine to murder people,
the fact they're using child labor to do it is
<a href=https://www.dw.com/en/report-child-labor-used-to-build-russian-drones/video-73595228>not the problem</a>. (They're targeting playgrounds and
maternity wards at the other end! They've been doing that for THREE YEARS.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#11-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 10, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#10-08-2025</link>
   <pubDate>Sun, 10 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>Curled up in a ball pretty much all week over stress from the ongoing
censorship stupidity. (Owned platforms are not public spaces, they are
preemptively complying with stupid laws that haven't even passed yet.
At least Wikipedia is out there fighting the good fight.)</p>

<p>I'm aware it's clearly going to go like prohibition (and the comstock act,
and McCarthyism) and self-destruct bigly, but all those took years to work
through and destroyed many lives. The Boomers are not dying fast enough.
(Larry Ellison is 80, but is trying VERY hard to do to his son what
Fred Trump did with Donald, Fred Koch did with his asshole sons, what
Rupert Murdoch is trying to do with Leland... generational wealth and power,
billionaires trying hard to recreate monarchy because we deploy neither
guillotines nor inheritance taxes.)</p>
<span>

<span id=home>
<p>The Cub Foods on Hamline is closing, and having a 30% off clearance sale
on everything which means some things are a good deal, some are
clearanced down to about what Aldi's sells them for anyway, and
some are still more expensive than you can get elsewhere. But I've stocked
up on blueberry caffeine cylinders, grape jam, and ready made instant
pudding cups. So I guess that's something. (I checked the clearanced
chicken nuggets: the ones at Aldi's are half a cent per ounce cheaper.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#10-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 9, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#09-08-2025</link>
   <pubDate>Sat, 09 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>The library was closed today. No warning, just a construction paper sign
on the door. I should ask them why on Monday.</p>

<p>Since I went to all the trouble of getting a mastodon archive to html
converter working, I put <a href=/toot>the result</a>
up on my website. I should probably link it from the top level nav bar,
but I haven't touched my top level web page in YEARS. (I should completely
redo it, I know. So many things I _should_ do...)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#09-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 7, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#07-08-2025</link>
   <pubDate>Thu, 07 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>Of course youtube is going to extend the UK's mass doxxing to
the USA starting <a href=https://9to5google.com/2025/08/07/youtube-ai-age-verification-what-to-know/>on the 13th</a>.
(No, don't say "always welcome" you assholes. Do not preemptively salute.
Youtube is not a substitute for parents. No for-profit corporation is
EVER going to be a substitute for parents. I read The Ship Who Sang
and The White Dragon in 4th grade.)</p>

<p>And of course the people doing the censorship are
<a href=https://youtube.com/shorts/s2O-0F4O9qE>lying about it</a>.
They always do.</p>

<p>I'll miss youtube. But I've never had a facebook account or a windows
PC, I'm not gonna provide my ID to youtube for the privilege of
watching Colbert clips there.</p>

<p>A whole lot of organizations need to transplant their content OFF
youtube. <a href=https://youtu.be/BUOzUTXFlQA>This ted talk</a>
seems unlikely to survive there. (Again: women! You are
"protecting" women from expressing themselves in professional
settings. There is no excuse for this.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#07-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 6, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#06-08-2025</link>
   <pubDate>Wed, 06 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>And the UK is censoring the internet, pushing it all over its borders.
Adult creators there have been <a href=https://www.girlonthenet.com/blog/age-verification-whats-the-harm/>eloquently warning</a>
this was a problem, but Starmer declared Palestine Action a terrorist
group and is arresing grandmothers for holding up a two sentence plackard,
so clearly they can be trusted doxxing everyone everywhere.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#06-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 5, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#05-08-2025</link>
   <pubDate>Tue, 05 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=health>
<p>Slowly unpacking the new apartment, and figuring out which stairwell
leads to "dog jail" (the fenced square of astroturf we're supposed
to take Adverb to, so he can inevitably pee on the bushes right outside
of it.)</p>

<p>The electronic key fobs are still stuck in Tariff Hell, Canada, so I have to
use the phone app to get into the apartment. It's three checks: the front
door, the elevator, and then the apartment door. Sad living in a gated
community but this is the one Fade liked most. And it does have some nice
common work areas downstairs, which I've used a few times (mostly to
edit back blog entries for posting, and catch up on email).</p>

<p>There's a BUNCH of hints that nobody has lived in this particular apartment
since it was built (which wasn't long ago, the building isn't full yet and
is still running ads), although I didn't know that when we applied here.
It was just right next to Fade's bus stop to her work and within sight
of the only reasonably priced grocery store in the city (because Aldi's
is a German owned chain, not american, so has yet to enshittify; T-Mobile
was German too until Softbank bought it a few years ago). Fade did:
she watched it being built while she commuted to work last year, it's visible
from the bus stop.</p>

<p>Not only is everything pristine and unscuffed, but the water in the sink
tasted funny (a bit like rubber) the first couple days, and they warned us
that the first time we used the stove it would trip the breaker multiple times
until it "got used to it". (I think the new part is offgassing or something?)
And the air conditioner fan ran constantly until they came and reprogrammed
its microcontroller (the guy phoned somebody about how they'd fixed that
problem last time, and this time they took notes for doing it again).</p>

<p>We've now moved from the Minneapolis side of the line to the St Paul side,
which means I can get a library card at the library I know how to get
to (the one next to the Asian market, which is not only on the green line
but now a reasonable walk from the new place)... except when I went they
can't get me one because of the St. Paul cyber attack, which remains unresolved.
They said I can get a digital thingy on the website, but they don't know
when I'll be able to apply for a physical card. (No, I can't go down
to the state capital and fill out a form there, the relevant computers
are basically toast. See "cyberattack", above.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#05-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 4, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#04-08-2025</link>
   <pubDate>Mon, 04 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>[Editorial note: I cut and paste this out of something I either decided
not to post to a list, or sent in a private email, but fell so far behind on
editing and uploading my blog entries that I no longer remember the context.
Still, this is what I was working on at the time, so...]</p>

<blockquote>
<p><b>&gt; But VHDL looks pretty "readable" for a programmer.</b></p>

<p>It is, that's why Jeff uses it instead of Verilog. (I tend to think of Verilog as assembly and VHDL as more like C, although Jeff says it's not C it's ada, which is why the toolchain build requires you to install "gnat" in the path.)</p>

<p>And Jeff came up with a tweaked version (sort of a VHDL++ except nobody wants to call it that because C++ went septic after about 5 years) that's some basic syntactic sugar which a perl script expands into something the compiler can understand, that's what converts *.vhd-&gt;*.vhm files. The perl script is
<a href=https://github.com/j-core/jcore-soc/blob/master/tools/v2p>here</a>,
by the way.</p>

<p>There's documentation for it somewhere. The extensions have to do with
<a href=https://download.gaisler.com/research_papers/vhdl2proc.pdf>the two
process method</a>,
Which boils down to latching all the I/O at each stage so you don't have to
worry about there being a MINIMUM clock speed the chip will run at (because
slower than that the signal's gone by, so the upstream capacitance has
discharged before the circuitry tries to read the result if you don't clock
it fast ENOUGH). Which was a problem Intel took in the teeth back around Y2K
when they hit a wall at 1ghz with the Pentium III. (Their minimum speed and
maximum speed converged on a very narrow window that kept CROSSING when things
like "ambient humidity" changed day-by-day, making their manufacturing yields
go through the floor, which led to the DUMBEST strategy of having the same
wallpaper in the cafeteria at their various fab sites because they didn't know
what affected yields. <a href=https://ieeexplore.ieee.org/document/630771/>No
really.</a>)</p>

<p>Sigh, I know I wrote a whole thing about that for The Motley Fool years ago,
but unfortunately Google can't find shit anymore (which was sadly an
intentional decision on Google's part, that came out
<a href=https://www.wheresyoured.at/the-men-who-killed-google/>during the
antitrust trial</a>
back when Lina Kahn was actually enforcing the <a href=https://www.archives.gov/milestone-documents/sherman-anti-trust-act>Sherman antitrust act</a>
of 1890.</p.

<p>I think my write-up was during
<a href=https://www.fool.com/archive/portfolios/rulemaker/2000/02/22/inside-intel-again-microprocessor-design.aspx>this week</a>
of
<a href=https://www.fool.com/archive/portfolios/rulemaker/2000/02/24/inside-intel-again-riscing-the-pentium.aspx>articles</a>...
Alas, I can't go to a specific day without guessing the article's full TITLE, because of course not.
Aha, I have it mirrored in a backup directory I've been meaning to index forever, the missing days were
<a href=https://landley.net/writing/mirror/fool/todo/rulemaker000223.htm>here</a>
and <a href=https://landley.net/writing/mirror/fool/todo/rulemaker000225.htm>here</a>.
Hmmm, that's not it though. These were just in passing mentions of the problem...
was it <a href=https://landley.net/writing/mirror/fool/todo/duelingfools00091301.htm>this</a>
or <a href=https://landley.net/writing/mirror/fool/todo/rulemaker000914.htm>this</a>...</p>

<p>(The problem with "I tried to explain this at length 25 years ago" is...
it was 25 years ago. I assume everybody knows, but instead we get
<a href=https://www.landley.net/history/mirror/institutional_memory.html>institutional
memory loss</a> and it's just sad...)</p>

<p>Anyway, poke me if you want more details but hopefully you've got the general idea. The speedrun explanation is:</p>

<p>Photolithography takes a big drawing of your circuits and focuses it into a small area, then uses chemicals to lay down wires and stuff. (You know how three color printing exposes the same thing 3 times? A modern process can easily have a hundred passes and lay down 5 or more layers of circuitry with insulation between them and the occasional wire going up/down between layers.)</p>

<p>Focusing the same circuitry into a smaller area naturally makes it faster, because how fast you can clock a processor is more or less a function of A) how long the wires are, B) how much capacitance each component has (and thus how much electricity it takes to fill it up so it performs its task). If you advance the clock before the electricity has made it down the wires and filled up the recipient circuitry, you get the wrong results. But if the upstream circuitry is basically discharging a capacitor into the wire and you wait TOO long, the signal's already gone past and dissipated before you get to see it. (There's always leakage into the substrate and so on, even with silicon-on-insulator.)</p>

<p>Pipelined circuitry has a bunch of stages feed into one another in sequence, so a signal takes multiple clock changes to make it from one end to the other. This lets you run the clock faster (each stage is localized and thus internally has shorter wires), and without pipelining big complicated hairballs may NEVER hit their timing because the minimum and maximum clock speeds cross (some signals are exhausted before others are ready, no matter how the place and route stage tries to jiggle stuff around (called "annealing") to avoid that).</p>

<p>A "latch" is extra circuitry to snapshot the state of a signal by storing it in more or less a tiny little SRAM bit until it's needed. The two process method automatically includes latches at each stage of a pipeline (or even smaller components of circuitry, is a question of where the circuit designer draws the boundary lines).</p>

<p>The downside of latches it it's extra circuity, extra transitors taking
up space and turning power into heat and taking time to fill up and discharge
their inherent capacitance. The upside is an unlatched signal goes away
again and you can miss it. Back when circuit designers drew masks by hand,
manual control of everything was expected and you worked out the timing
by measuring your lines. Tools that automate placement have never been
that smart, and modern circuits can have BILLIONS of them rather than a few
thousand to micromanage.</p>
</blockquote>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#04-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 3, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#03-08-2025</link>
   <pubDate>Sun, 03 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>A nice person sent me a toybox logo image they'd whipped up... which is
basically the busybox logo with "toybox" written on it. (Um... no.)</p>

<p>I got a <a href=https://github.com/landley/toybox/pull/560>pull request</a>
to add a very ugly special case function with two #ifdefs to main.c,
which I REALLY don't want to do. In theory something like that would go
in portability.c if it went anywhere, but it really seems like you shouldn't
need a patch for this?</p>

<p>You can add arbitrary files to lib/*.c and they'll get compiled and linked
in, and then in theory dropped out again by --gc-sections if they're not used,
but stuff in the "init" section would be used, so if you tag a constructor
function that _start calls out of the .init/.fini sections before calling
main() then...</p>

<blockquote><pre>
$ cd toybox
$ cat &gt; lib/blah.c &lt;&lt;EOF
#include &lt;unistd.h&gt;
__attribute__((constructor)) void thingy(void) { write(2, "Hi!\n", 4); }
EOF
$ make clean false
...
$ ./false
Hi!
$
</pre></blockquote>

<p>Except you still need to replace argv[], which looks
<a href=https://blog.linuxgamepublishing.com/2009/10/12/argv-and-argc-and-just-how-to-get-them/>kinda icky</a>.
(And more to the point, architecture dependent. Why glibc couldn't
just let you access __libc_argv and _libc_argc I have no idea.)</p>

<p>Ideally you'd just have a different entry point instead of main(),
but -Wl,-ethingy replaces _start not main (so still can't see argv[],
segfaults if you return from it, presumably skips some important setup
for malloc() and printf() and such if you don't hand off to _start
properly...)</p>

<p>I can CFLAGS="-Dmain(a,b)=other_main(a,b)" and #undef main in
the new lib/*.c file but that screws up the compile time symbol probing...
Aha! LDFLAGS=-Umain is only added when we're making
a binary, not for creating intermediate .o files. So the library and
symbol probes use it, but the main compile doesn't for the parallel builds.</p>

<p>Ok, replied to the pull request, and if that works for him maybe I'll
add a FAQ entry for people wanting to use whatever this fuzzer package
is? Let's see, "aptitude show afl" says "Description: transitional dummy
package for afl to afl++. This is a transitional package. It can safely be
removed once afl++ is installed." Good to know.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#03-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[August 2, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#02-08-2025</link>
   <pubDate>Sat, 02 Aug 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>I haven't been blogging regularly, in part because I'm exhausted from the
move but also because I'm tired. The censorship I was worried about
(Project 2025 explicitly had "outlawing porn" as a plank) has
gone mainstream: Visa and Mastercard attacked Steam and itch.io, the UK
Online Safety Act has triggered Youtube to demand photo ID in the USA
starting on the 13th. (It's the same "preemptive compliance" where
people took their shoes off at airports after that "shoe bomber" idiot weeks
before the TSA started demanding it.)</p>

<p>Youtube's copyright autodetection stuff that removes music from videos is also
censoring the word "suicide" (because Keir Starmer's interviews have all been
using that as his non-porn example of why minors have no rights and must be
controlled. Of COURSE any censorship mechanism once widely deployed will be
turned to censoring more and more stuff. All discussion of Ukraine and
Gaza will be going behind the photo ID paywall as soon as Youtube gets it
up. We didn't stand up for "sex work is work", we didn't rise up when
Mastercard extended its prohibition on "bestiality" to cover furries, and
canceling Colbert and declaring Palestine Action to be a terrorist organization
and arresting grandmothers is the EXACT SAME THING. It's a continuum of
fascism. "Give me a child until the age of 7 and I will give you the man."
Straight edge purity ring bullshit where the ONLY sexuality you can express
is gay or trans because a heterosexual 11 year old being "boy crazy"
must be STUDIOUSLY IGNORED until she learns to sublimate it into private
fetishes. (Did you know if you get your period and your hymen doesn't break,
and you ignore it for about 6 months, so the accumulted blood backs up into
your abdominal cavity, it can kill you? This was trivial to fix even back
in Roman times, but if you don't TEACH PEOPLE ABOUT THEIR BODIES it's
a BAD THING. Of course THAT link will go behind an ID censorship paywall soon.
A bright line that only ever expands, can be twisted into an excuse to
do ANYTHING, and if you question that line you are an inhuman monster.)</p>

<p>The right wing has used "protecting children" as an excuse for infantalizing
adults forever. Nazi Germany was "The fatherland" for a reason, "Fuehrer"
is the german word for father. Just like they used "protecting women" as
an excuse for mysogyny. They claimed that slavery was good for black people
who "couldn't manage their own affairs". It's the right wing playbook 101:
divide and conquer, we know better and get to dictate their lives.</p>

<p>I'm mad that the boomercrats are using this as an excuse to install spyware
on everybody's phones and require government ID to access the internet.
The status quo of "suicide girls" being a major cultural force 15 years
ago and "<a href=https://youtu.be/vWEskfjMBCg>the internet is for porn</a>" winning a Tony was not that long ago,
and lasted a quarter century (1993 to 2017) without causing significant
problems. The rise of gamergate incel nazis was ALWAYS about censoring
what they didn't want to see. (Kathy Sierra's "<a href=<https://web.archive.org/web/20141008045718/http://seriouspony.com/trouble-at-the-koolaid-point/>Trouble at the Kool-aid Point</a>"
was 2014, and was itself a 10 year anniversary piece.)
Maga isn't worse than what Reagan's crowd tried to pull (as George Carlin
<a href=https://youtu.be/og9DV0Si8bs>famously enumerated</a>: in 1998
Reagan had an Attourney General investigated by 3 special prosecutors,
trying to ban porn, etc), the fascist playbook
hasn't changed in forever. What's failed is the opposition, captured by
putocrats just like the Gilded Age that led up to both world wars.
Somehow the Pelosi pearl clutching prudes won't stand up and say "spending
your lives under house arrest except for work release where you go through
metal detectors, living under constant surveilance and not owning your own
bodies, is WRONG, and attempts to eliminate ALL RISK inevitably go too far,
and we need to find a BALANCE here and not endlessly double down on
absolute prohibitions that DO NOT WORK". And then suddenly being released
from prison into the world when you turn 18 means you're supposed to
hit the ground running instead of bingeing the things you could never have
before or otherwise panicing?</p>

<p>It's ironic that the UK is lowering the age of voting to 16, but they can't
see their fellow citizens naked or listen to the theme song to M*A*S*H for
2 more years. Here in the USA I keep waiting for the maggots to try to raise
the age of consent to 21 (like the drinking age, Mississippi has already
raised the marriage age to 21). Why isn't a naked 19 year
old child porn? (Not even having sex, just being naked, since that's what
fosta/sesta and the payment processors chased off Tumblr in 2017.) They
already clutch pearls about someone marrying younger than 30.
In Romeo and Juliet she was 13 (the nurse explicitly says "not yet fourteen")
and that was both sex AND suicide,
I'm surprised Shakespeare hasn't been banned yet. But you can't say such things
or else you are CLEARLY in favor of the grab 'em by the pussy guy who owes
Jean Carroll $83 million dollars for sexual assault
(and literally says he <a href=https://www.politico.com/news/2025/06/24/trump-carroll-judgment-appeal-00421059>doesn't have to pay because
he's president</a>).</p>

<p>And why are people so worked up about Trump (obviously!) being in the
Epstein files when there's a <a href=https://en.wikipedia.org/wiki/Donald_Trump_sexual_misconduct_allegations>wikipedia page</a> on the sexual assault
allegations made against the guy by at least 25 women since the 1970s.
(And <a href=http://youtube.com/post/UgkxZ61RPyQYvjT5bicNqe05wHhMzAPOdJ11>I'm told</a> there's far more that have been more effectively covered up,
such as the tabloid publisher who <a href=https://www.npr.org/2024/04/26/1247352050/trump-hush-money-trial-david-pecker>bought exclusives</a>
and never published them, a practice called "catch-and-kill" leaving women
under NDAs about their experiences.) This is public record. The man is a
monster. His supporters KNEW THAT when "grab 'em by the pussy" was a big
campaign issue in 2016 and they voted for him anyway. (Boomercrats: passing
MORE LAWS against behavior that wasn't PREVIOUSLY illegal isn't an excuse for
not prosecuting the existing already illegal behavior. You don't make up
for shielding the overlords by punishing the masses, it doesn't make
you look strong.)</p>

<p>This is the same party who impeached Bill Clinton for denying a consensual
relationship with a 22 year old, which only came out because she went "you won't believe
what celebrity I slept with!" to her friend who taped her and dragged
her life through the mud. She gave a Ted Talk about the experience,
with 22 million views on <a href=https://www.ted.com/talks/monica_lewinsky_the_price_of_shame>TED website</a>, despite Google listing the Youtube version
at the top and not having that link on the first page.
(The version on Youtube is about to be censored and
locked away behind a demand for government ID, I expect, along with plenty
of other <a href=https://youtu.be/BUOzUTXFlQA>ted talks</a>.)</p>

<p>It's not just sex being censored, of course.
<a href=https://youtu.be/_gZrvHCO83I>Copyright law is fucked.</a>
Most of the mechanisms being used to censor low-cut shirts and mentions
of the existence of suicide started with <a href=https://en.wikipedia.org/wiki/Viacom_International,_Inc._v._YouTube,_Inc.>Youtube vs Vericom</a>
and only ever expanded. (This stuff only ever expands: the Ferber decision
in 1982 was about "younger than 16", now 16 year olds in the UK can vote
but not see each other naked. The goal posts move, and if you object to
needing to retreat from the edge or try to figure out where the edge IS
(let alone why) the torches and pitchforks come out. And it's all preemption
and victimless crimes, sundown laws because somebody MIGHT do something
someday and thus we must all live in gated communities. Waiting to prosecute
people who actually A) did something B) to someone, that's CRAZY TALK.
We must PROTECT THE INNOCENT from being TAINTED BY KNOWLEDGE. They cannot
see! They cannot hear! They cannot read! So sayeth the censors.
Ever-expanding, ever-tightening. I'll know it when I see it, laws that
bind but do not protect, so self-censor ahead of the rising tide just
to be on the safe side...</p>

<p>And then all that <a href=https://mstdn.jp/users/landley/statuses/114440468635810087>corporate personhood</a>
nonsense and the Citizens United decision (an orwellian name which means the
exact OPPOSITE of what the ruling did: one dollar one vote)...</p>

<p>Stop trying to use the Ring against Sauron. Push BACK already.
A problem can be real yet the "solution" can be worse.</p>

<p>I fully admit this stuff is hard. Daring Fireball is currently
<a href=https://daringfireball.net/linked/2025/08/02/substack-nazi-notification>complaining</a> that substack doesn't
censor ENOUGH (part of a general theme that author has, also today making tsk tsk
noises at <a href=https://daringfireball.net/2025/08/the_substack_branding_and_faux_prestige_trap>Paul Krugman</a>
for moving from the New York Times to Substack because he didn't want
to host his own blog and Livejournal is no longer a serious option).
Not censoring enough is also a common theme on mastodon, with instances
blocking each other in full Homeowners Association snits. I dunno where the line is. But the line moving in
one direction consistently for 40 years without an obvious motivation
other than pearl clutching of the "<a href=https://www.youtube.com/watch?v=PSQOgJFw8RQ>satanic panic</a>" variety? Makes me
uncomfortable when it literally installs spyware on my phone, has
payment processors blocking otherwise legal purchases, multiple countries
reaching outside their own borders to censor content... None of whom
can really say what was wrong with the status quo back when "The Internet
is for Porn" won a Tony, other than a religiously motivated
"that sort of thing shouldn't be allowed".</p>

<p>Did you know that before Marlon Brando wore a T-shirt in the movie
"A Streetcar Named Desire", T-shirts <a href=https://www.realthread.com/blog/history-of-the-tshirt>were considered underwear</a> and you
could be arrested for wearing one out in public? And in the 1930s
police were still <a href=https://www.manisteenews.com/local-history/article/Men-s-topless-bathing-suits-became-a-hot-button-17404618.php>arresting men for swimming topless</a> at beaches in the USA. Women are still fighting for
<a href=https://en.wikipedia.org/wiki/Go_Topless_Day>that same right</a>
but misogyny has been a rising tide since <a href=https://en.wikipedia.org/wiki/Tea_Party_movement>about 2010</a>
largely due to the Boomers drying up and going senile.</p>

<p>Step one is to be clear which side you're on. "First they came for"
is always the strategy, find out what you WON'T protect and use it to set
precedent expandable to everyone/everywhere/everything.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#02-08-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 31, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#31-07-2025</link>
   <pubDate>Thu, 31 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>We have to be out of the old apartment by noon today. Haven't opened my
laptop except to download email and (manually) delete spam a couple times.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#31-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 29, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#29-07-2025</link>
   <pubDate>Tue, 29 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>I don't have time to <a href=https://www.theguardian.com/world/2025/jul/29/mastercard-visa-backlash-adult-games-removed-online-stores-steam-itchio-ntwnfb>curl
up into a ball</a> right now.
We have to move house. But so many people are
<a href=https://youtu.be/zEdL9PG93Bg>going to die</a>, and... how much music does
spotify have to ban?
<a href=https://youtu.be/wEPhcj76ccs>Molly Lewis's song about the Hawaiian
Goddess Kapo</a>,
Garfunkel and Oats' song about
<a href=https://youtu.be/__d03IqV4BE>Go-Karts and Masturbation</a>,
and their song
<a href=https://youtu.be/7yxQKxm76TQ>Fuck You</a>
which is different from the <a href=https://youtu.be/CAV0XrbEwNc>CeeLo Green</a>
and 
<a href=https://youtu.be/fHC05_9b0gw>Lily Allen</a> songs of the same name.
And of course Ice T's classic
<a href=https://youtu.be/_AGLigSIHmk>Let's All Get Buck Naked And Fuck</a>
which was in the Christian Slater Movie "Pump Up The Volume" which
has an IBDB page explaining why it got its R rating by among other things
<a href=https://www.imdb.com/title/tt0100436/parentalguide/?ref_=tt_stry_pg#profanity>listing</a> the profanity used
("21x fuck, 8x shit, 6x hell, 5x damn, 4x Jesus, 5x cock, 1x dick.") and
it's fine to put them there but not have them in the movie because
Boomers are completely brain dead at this point.</p>

<p>Dear Boomercrats: please stop implementing Project 2025 _for_ the magats.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#29-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 28, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#28-07-2025</link>
   <pubDate>Mon, 28 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>Finally reacquired my luggage, which didn't make the transfer through
Montreal because the plane from Japan got in an hour late. Those of us
transferring to the flight to Minneapolis that started boarding while our
plane was still on the runway got escorted through customs by airline
employees, but our luggage didn't make it.</p>

<p>And due to Canadian travel to the USA absolutely imploding (due to that senile
idiot's "We're gonna invade to make you the 51st state, along with greenland
and the gulf of mexico" rhetoric, plus the ICEtapo reaching across the
border to kidnap canadian citizens fishing in lakes... suddenly no
canadians feel safe traveling to the USA, they're buying local and refusing
US imports, all the snowbirds are selling their florida property... anyway)
Air Canada is down to one flight from Montreal to Minneapolis per day.
(And it's a TINY plane with like 1/10th the seats of the Tokyo to Montreal
one.) So the luggage couldn't come in until 8pm yesterday.</p>

<p>And THEN I was on the phone all morning trying to convince them NOT to
deliver it to the old apartment complex (both the old and new complexes
are gratuitously gated communities you have to badge into, I didn't ask
for this but it's where Fade wanted to live) but instead let me go back
to the airport and pick it up. Alas contacting a human on the same continent
as my luggage was... quite a challenge. ("Everything is outsourced" can be
sung to "Everything is Awesome", and that's when you spend half an hour
going through a phone tree to talk to a _human_ who can't help you.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#28-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 26, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#26-07-2025</link>
   <pubDate>Sat, 26 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<p>Flying back from Tokyo, just in time to help Fade finish moving
everything out of the old apartment and into the new one.</p>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#26-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 24, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#24-07-2025</link>
   <pubDate>Thu, 24 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>You know, if you <a href=https://en.wikipedia.org/wiki/Lists_of_state_leaders_by_age>rank world leaders by age</a>,
the top ten countries with the oldest leader (all octegenarians) are
Cameroon, Palestine, Saudi Arabia, Norway, Iran, Togo, Bangladesh, Kuwait,
Ireland, and Italy.</p>

<p>Of the four seeming success stories on the list,
Norway's king is symbolic (their <a href=https://en.wikipedia.org/wiki/Jonas_Gahr_St%C3%B8re>prime minister</a>
is a quarter century younger),
and of the two seeming success stores at the end of the list Ireland is a <a href=https://en.wikipedia.org/wiki/Ireland_as_a_tax_haven>tax haven</a>
puppeted by corporations and Italy has been <a href=https://www.bbc.com/news/articles/cljj4j84r9go>returning to fascism</a>.</p>

<p>Saudi Arabia's king is also symbolic: it's been de facto run by <a href=https://mstdn.jp/users/landley/statuses/110980488458778278>Mister Bone Saw</a> (who is 39 and basically staged a coup over 10 years ago) for over a decade.
That country is <a href=https://www.interfluidity.com/v2/4340.html>dutch disease</a> central: the USA allied with it in the region the same way Roosevelt
allied with Stalin and propped him up with lend/lease aid during World War II,
but the oil money can't overcome the fact the place is
<a href=https://www.youtube.com/watch?v=itAKlmZZb6w>incredibly</a>
<a href=https://www.youtube.com/watch?v=vyWaax07_ks>stupidly</a>
<a href=https://revealnews.org/article/what-california-can-learn-from-saudi-arabias-water-mystery/>run</a>.</p>

<p>Gerontocracy is bad, mm'kay. Here in the USA, replacing the oldest president
ever with the oldest present ever and then replacing _him_ with the oldest
president ever may have been a bad move.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#24-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 23, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#23-07-2025</link>
   <pubDate>Wed, 23 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>Really looking forward to the US dollar losing its role as the
<a href=https://youtu.be/nGQYm6gM2ks>global reserve currency</a>
and the payment processors enforcing <a href=https://youtu.be/DEflTJjtn5w>censorship</a>
on everybody getting uprooted and replaced.</p>

<p>It would be really nice if the <a href=https://mstdn.jp/users/landley/statuses/114878199052523118>fair access to banking act</a> passed too.
Or Josh Hawley did something useful for once and actually took action
against the payment processors he <a href=https://youtu.be/ks3wP1nlg6U>performatively
rails against</a>. (He talks a great game there, but is a maga republican.)
Or Dick Durbin's <a href=https://www.paymentsdive.com/news/durbin-marshall-senate-credit-card-competition-act-bill/740921/>credit card competition act</a>.
Sigh, there's been zillions of <a href=https://mastodon.social/@Alexgibneyfilm/109717862522835668>attempts</a> to address stuff but the guillotines
haven't come out yet because people are still waiting for the Boomers to
die of natural causes. (Which includes Trump and Putin.)</p>

<p>A good video that youtube will probably block soon,
<a href=https://youtube.com/shorts/5enCaqcnyKs>JadeBlairxox: Why mmm mmm workers only take cash</a>.
</p>

<p>As usual, Billionaires are the
problem. The Simpsons did an entire musical episode called
<a href=https://www.youtube.com/watch?v=z6RbdZKn3Rc>poorhouse rock</a>
with Hugh Jackman and Robert Reich and such, ending with "burn it"
as the suggested action to take, three years ago now. And instead, the
maggot party that did the mad hatter's tea party (clean cup! move down!)
let Musk and Trump and Citizens United and Corporate Personhood
buy another election via the classic "<a href=https://www.reddit.com/r/WhatIsThisPainting/comments/lfa41m/who_is_the_original_artist_of_this_political/>steal your cookie</a>
technique.</p>

<p>Society at large can't deploy guillotines until the Boomers get out
of the way.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#23-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 22, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#22-07-2025</link>
   <pubDate>Tue, 22 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>

<p>The minimal reproduction sequence for the ASAN segfault in devuan daedalus'
gcc (which I've tried to
<a href=https://codeberg.org/landley/toybox/commit/635f1e0391b0>work around</a>)
appears to be:</p>

<blockquote><p>gcc -xc - -fsanitize=address -static-libasan
-Wl,--as-needed -lcrypt &lt;&lt;&lt;'int main(){crypt("", "");}' &amp;&amp; ./a.out</p>
</blockquote>

<p>That compiles a single line main function that makes a call to crypt()
(cc -xc - tells it to compile stdin as a .c file, and then feeds the line
to stdin), and then -fsanitize=address enables the address sanitizer.
The -static-libasan is necessary because gcc's asan is so borked it can't run
the dynamic asan at ALL:</p>

<blockquote><p>
$ echo 'int main(){return 0;}' | gcc -xc - -fsanitize=address<br />
$ ./a.out<br />
==12158==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.
</p></blockquote>

<p>(Alas, the gcc developers went crazy and drove all the non-FSF zealots over
to LLVM years ago.)</p>

<p>But ASAN still MOSTLY works if you tell it to use libasan.a instead of
libasan.so, except there's a SEPARATE bug with --as-needed which discards
used symbols, but only in the presence of ASAN.</p>

<p>The reason the above toybox commit didn't manage to work around the
issue is llvm used "-static-libsan" instead of "-static-libasan", and
gcc only accepted one and clang only accepted the other, because of course.
And although Elliott added an alias to clang to accept the gcc version
it hasn't made it through to a released NDK yet.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#22-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 21, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#21-07-2025</link>
   <pubDate>Mon, 21 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Yay, I got <a href=https://mastodon.social/@normalmode/114848139918426986>pointed
at</a> vim's ":verbose set mouse" option which let me know that
/usr/share/vim/vim90/defaults.vim was overriding /etc/vim/* for some
reason. I changed the "set mouse=stupid" in that file to "set paste" and
now vim is behaving like it used to again.</p>

<p>Lateral progress: re-establishing the Not Stupid behavior of yore,
to prune back the unwanted "upgrades" that distros keep trying to upsell.</p>

<p>It's still subtly broken, though. When I manually re-wordrap lines I
tend to hit enter at the end of a word, meaning I inserted a newline before
the space, so there should be a space at the start of the new line. Vim
is "helpfully" deleting that space, which means my own habit of doing a
"cursor right, backspace" after every one takes out the first letter of the
word. (I DID NOT ASK YOU TO GET CLEVER. STOP IT. This is a TEXT EDITOR,
do what I told you to do without attempt to interperet stuff. I did "set paste"
to turn off auto-indent and yet you're STILL treating whitespace specially.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#21-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 20, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#20-07-2025</link>
   <pubDate>Sun, 20 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I'm getting spurious warnings from llvm, and the recommended way to suppress
them is -Qunused-arguments, except:</p>

<blockquote><pre>
$ :|gcc -Wall -Qunused-arguments -xc -
gcc: error: unrecognized command-line option ‘-Qunused-arguments’
</pre></blockquote>

<p>Speaking of "make it stop", here's yet more Boomers <a href=https://www.usatoday.com/story/news/nation/2025/07/20/drivers-education-laws/84615681007/>outlawing childhood</a>.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#20-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 19, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#19-07-2025</link>
   <pubDate>Sat, 19 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I think I've figured out part of the reason my anxienty's been spiking
this past week: I haven't had any fiber in my diet since leaving
Minneapolis. Rice balls, white bread sandwiches, meat, french fries,
corn soup... my digestion is increasingly unhappy with me.
(One of the downsides of being on the far side of 50.)</p>

<p>Huh. In 2020, 94% of the malware samples <a href=https://www.sciencedirect.com/science/article/pii/S1877050920319487>these guys</a>
looked at were compiled with my old firmware linux toolchain.</p>

<p>I feel a bit like Toyota's Hilux division must feel about <a href=https://en.wikipedia.org/wiki/Technical_(vehicle)>technicals</a>.
Should it be less easy to use? Not as good at its job? How do you make
"a hammer" less subject to misuse?</p>

<p>I took the toolchains in question off my website after that incessant
<a href=#04-07-2025>spam filtering</a> nonsense months ago, but they're out
there, and my last name is a relative unique word. (It would be more so
if Conan Obrien hadn't pulled it out of his ass writing the monorail episode
for The Simpsons, and some bodybuilder had decided to use it as a stage
name.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#19-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 18, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#18-07-2025</link>
   <pubDate>Fri, 18 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p><a href=https://www.congress.gov/bill/119th-congress/senate-bill/401/text>The Fair Access to Banking Act</a>
goes along with
<a href=https://action.aclu.org/petition/mastercard-sex-work-work-end-your-unjust-policy>the ACLU petition</a>. It is possible to fix things, we just
need to clean the Boomers out of the system first.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#18-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 12, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#12-07-2025</link>
   <pubDate>Sat, 12 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>

<p>I should do videos about toybox commands again.
In theory if I sort them by source code size (shortest job first) and
maybe group some related commands conceptually, I could start with...</p>

<blockquote><pre>
cat tac rev shuf
fallocate readahead
sync fsync
link unlink
sleep usleep
swapon swapoff
mknod mkfifo
uuidgen mcookie
basename dirname
who w
nice renice
mkdir rmdir
hd od hexedit xxd
pwd pwdx
uname ulimit prlimit getconf
</pre></blockquote>

<p>I edited another digression out of a <a href=http://lists.landley.net/pipermail/toybox-landley.net/2025-July/030787.html>mailing list post</a>
about the C standards committee looking at things that have long been
defacto standards, and might as well dump it here:</p>

<blockquote><p>
<a href=https://web.archive.org/web/20120915100832/http://llvm.linuxfoundation.org/index.php/Main_Page>llvm.linuxfoundation.org</a>
was 100% a trailing indicator: the Linux Foundation loves taking credit after the fact, a bit like the FSF.</p>

<p>If the C standards commitee thinks "building Linux as it has consistently shipped for a quarter century now" is something a standard C might want to be able to do... again, I honestly thought somebody would have noticed when putting together C11. That they would have at least considered it.</p>

<p>But then I'm weird, Back in 2001 I was trying to put together the simplest
Linux system capable of rebuilding itself under itself (and building
linuxfromscratch.org under the result)
<a href=https://landley.net/aboriginal/old/>first</a>
replacing 20+ packages with busybox and eventually got the busybox+uclibc
variant down to <a href=https://landley.net/aboriginal/about.html>7 packages</a>
before rebasing on toybox and aiming at 4 packages (kernel, compiler, libc, cmdline) built from a <a href=https://github.com/landley/toybox/blob/master/mkroot/mkroot.sh>400 line bash script</a>.</p>

<p>That's the context in which I maintained <a href=https://landley.net/code/tinycc/>my own fork of tinycc</a>,
because I was trying to get it to build linux, busybox, uclibc, and itself. (I already knew <a href=https://dwheeler.com/trusting-trust/>tinycc built gcc+binutils</a>.)</p>

<p>Trying to get a compiler that doesn't currently build vanilla linux to build vanilla linux is how you find out that Linux is running objdump on a .o file and processing the output through awk to generate a header file for boot structure offsets. (Since removed I think, but at the TIME it was the next missing chunk blocking the build when I downed tools.) Whether or not it's RIGHT, you'd think it's the kind of thing people would test and become aware of. I wasn't doing anything special, I was just being persistent and ornery in taking apart the bits I didn't understand yet...</p>

<p>I always assumed the "professionals" had 10x as much information to work with. I knew posix made a _choice_ not to be directly relevant due to Microsoft and IBM's big iron divisions giving them money to punch holes int he standard big enough to drive Windows NT and OS/360 through back when FIPS-151-2 gated navy procurement contracts. I didn't follow the C committee since the only copy of the standard I could afford was Herbert Schildt's annotated version and everybody universally barfed on that as a ghetto poor person thing so I wrote them off as "you must be this rich to bribe this committee"...</p>
</blockquote>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#12-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 11, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#11-07-2025</link>
   <pubDate>Fri, 11 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I did a fresh git pull of qemu (creating a new repo instance),
ran <b>./configure --prefix=~/bin &amp;&amp; make -j $(nproc)</b>
and then when I did "make install" it said "config.mak out of date, running
confgure".</p>

<p>Sigh. Overcomplicated committee nonsense... And it made a directory called
"~" in the qemu source directory, and installed in "bin" underneath that.
Bravo. Just *chef's kiss*. (Right, <b>git clean -fdx &amp;&amp; git checkout -f</b>
then <b>./configure --prefix=$HOME/bin</b> because IT CAN'T SCREW THAT UP
(the shell expands it before calling the command). Although technically
if it DOES re-run configure for the install stage it COULD forget the
--prefix entirely because that wasn't passed to configure this time (it has to
be fetching it out of the existing configure data so WHY RUN IT AGAIN...)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#11-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 10, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#10-07-2025</link>
   <pubDate>Thu, 10 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>Apple is copying Android's prudishness: facetime will now
<a href=https://metro.co.uk/2025/07/09/people-phone-sex-facetime-will-now-get-a-warning-apple-23617714/>scan for phone sex</a>. (Remember: outlawing
porn is part of project 2025, everybody needs to get back to wearing
buckles on their shoes and neck ruffs where showing ankle is scandalous.)</p>

<p>It's not that he was screaming, it's that
<a href=https://www.nbcsandiego.com/news/local/plane-san-diego-diverted-unruly-passenger/3863061/>he took off his shirt</a>, that's why they took action.</p>

<p>Today in "<a href=https://abcnews.go.com/US/bullying-tennessee-now-new-penalty-teens-losing-driving/story?id=123388452>kids aren't people</a>".</p>

<p>And <a href=https://youtu.be/p3jht3cHGPw>this is just not rational</a>:
a youtuber posted a video complaining that youtube's bot comments are
linking to material that violates youtube's TOS, and his complaint video
was itself age restricted for mentioning that material capable of violating
youtube's TOS exists. They age restricted his COMPLAINT.</p>

<p>His follow up video linked above is seperately stupid for explicitly
arguing that preemptive compliance does something OTHER than endlessly move
the overton window in a direction we don't want it to go. He believes
there's some way to be SAFE from fascists by cowering hard enough,
obsequeously enough, and quickly enough. This is demonstrably false:
pearl clutching assholes have <a href=https://en.wikipedia.org/wiki/Mary_Whitehouse>always
been with us</a> and you have to shout them down and render them irrelevant
by flooding the zone with a normalizing level of material proving
<a href=https://en.wikipedia.org/wiki/Kirk_and_Uhura%27s_kiss>by example</a>
that it's not harmful. People pleasers who take all complaints on board to
carve the public sphere down to the least objectionable gruel serve only the
billionaire slumlords trying to enslave everyone because they NEVER STOP
PUSHING. This is a classic
<a href=https://en.wikipedia.org/wiki/Dane-geld_(poem)>danegeld</a>
situation, you CANNOT APPEASE THEM. It doesn't work that way.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#10-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 6, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#06-07-2025</link>
   <pubDate>Sun, 06 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=comphist>
<p>I should explain how Stallman's pivot to Unix when ITS died makes
GNU being so UTTERLY BAD AT UNIX such an obvious consequence.</p>

<p>The "Incompatible Timesharing System" was a legacy mess RMS inherited from
MIT's old Tech Model Railroad Club after all the people who built it graduated
and moved on. It was named in snarky opposition to the "Compatible TimeSharing
System" that a different part of MIT had produced in 1961 for an early
<a href=https://en.wikipedia.org/wiki/IBM_709>IBM computer</a>. CTSS was
the first OS that could run multiple processes in parallel (then called
"timesharing", now not really called anything because the last widely
used OS that _didn't_ do that was DOS), which got that part of MIT invited to
participate in the Multices project along with Bell Labs (inventor of
the transistor) which eventually collapsed (they had a thirty six thousand
page specification written before the hardware arrived) and produced Unix
from its ashes (what's the simplest thing we can do that works, on a discarded
piece of junk somebody left behind in an attic when they moved to
<a href=https://en.wikipedia.org/wiki/Bell_Labs_Holmdel_Complex>Holmdell</a>
and all the ex-multics guys are stuck in that attic because
management is mad and sent us to our room and won't buy us any hardaware
to work on until we finish our time-out and really think about what
we've done and LITERALLY why did they move our office space INTO A LEAKY
ATTIC, that's just petty...).</p>

<p>But CTSS and Multics came was a different part of MIT than ITS did,
and ran on different hardware from a different manufacturer. Back
when <a href=/history/mirror/interviews/olsen.html>Ken Olsen</a>
worked at Lincoln Labs (a military contractor building on the success of
Howard Aiken's "Harvard Mark I" during World War II by trying to develop the
computing hardware the USA would need to fight World War III) he sent
discarded prototype hardware down the street to MIT (a
<a href=https://en.wikipedia.org/wiki/TX-0>test harness</a> for the
first transistor memory that could be used as a very simple computer,
Ken built it in 1955 and finished using in 1956) which was picked up by
the Tech Model Railroad Club as a fun new tool to further automate their
elaborate model railroads already full of switches and relays. The group
quickly pivoted to playing around with this new "computer" thing (calling
themselves the "artifical intelligence lab" when they applied for
university funding for space and electricity to run the thing), and
then built their own <a href=https://en.wikipedia.org/wiki/TX-2>bigger
version</a> in 1958.</p>

<p>(Note: Ken Thompson, inventor of Unix, is not the same person as Ken Olsen,
founder of DEC. We're talking about the DEC guy here, years before Unix.)</p>

<p>When Ken Olsen left to start his own company (Digital Equipment
Corporation) he hired graduating students from TMRC to work for him, and
sent the new computer they'd built (the PDP-1 circa 1959) to MIT to be the
TX0's successor (and keep the stream of future employees coming). The
MIT students had their first real video game running on it
<a href=https://en.wikipedia.org/wiki/Spacewar!>by 1962</a>, which DEC
found to be a great marketing tool for their hardware. As DEC developed
newer more powerful computers, Ken had DEC send one of each model to
the MIT lab he sponsored so he could continue to hire their graduates to
work for him. The 36-bit PDP-6 came out in 1964 and its compatible upgrade
the PDP-10 in 1966, and those were the machines ITS ran on at MIT's ex-TMRC
AI lab. But then the market changed direction.</p>

<p>CTSS ran on IBM hardware and ITS ran on DEC hardware, but both ran
on 6-bit hardware. Back when memory was REALLY expensive early computers
economized by using 6 bits to store each character of text (so their registers
were 18 bits (3*6) instead of 16 (2*8), and their larger successors were 36
bits instead of 32), and were programmed in octal (3 bits holds 8 values [0-7]
so if you write numbers in base 8 each 6-bit byte could be represented by 2
octal digits). 8 bits was a more natural size (power of 2) for computers to
work in (and 7 wasn't an option because it's prime, you couldn't split
7 bit bytes in half to represent them as 2 digits; hexadecimal may be
awkward but it's at least possible). Lincoln Labs had produced a 16 bit machine
with 8 bit bytes called <a href=https://en.wikipedia.org/wiki/Whirlwind_I>Whirlwind</a>
back in 1951, and Ken Olsen's first project when he joined Lincoln Labs was
producing a 16-bit
<a href=https://gunkies.org/wiki/Memory_Test_Computer>Memory Test Computer</a>
to test out the magnetic core memory for that machine. (His 6-bit TX0 was a second
test system to convince his bosses that transistors could be made reliable
enough to use as memory, an idea he then left Lincoln Labs to commercialize,
founding DEC.)</p>

<p>The advantage of 6-bit machines is they could store 25% more characters of
text in the same amount of memory, but the downside is that text sucked:
you could only handle upper and lower case at the same time if you
chose between having no digits or no punctuation. 6 bits is 64
characters, [a-zA-Z0-9] is 26+26+10=62 leaving 2 encodings for space and
period. You can't even have a newline unless you trade something else off.
If you drop the digits and just spell out "one two three" you can get back 10
characters for parentheses and colons and such... but you can't really do
math (and thus write programs) without digits. If you drop all the lowercase
letters you could have both digits and a reasonable assortment of punctuation
and control characters, BUT YOU WOULDN'T USE THAT TO TYPESET NEWSPAPER.</p>

<p>The gradual decline of 6-bit computers and their replacement by 8-bit
computers was a natural consequence of memory getting cheaper. The first 7-bit
<a href=https://en.wikipedia.org/wiki/ASCII>ASCII</a> standard was published
in 1963, and IBM announced its first 16 bit computer the
<a href=https://en.wikipedia.org/wiki/IBM_System/360>S/360</a> in 1964.
(Fred Brooks wrote a classic book called
"<a href=https://en.wikipedia.org/wiki/The_Mythical_Man-Month>The Mythical Man-Month</a>"
about his experience managing the development team creating the 360.) DEC followed
along 5 years later, producing the 16 bit PDP-11 in 1970, and in 1977
the 32-bit VAX-11/780 (Virtual Address Extensions to the PDP-11)
abandoned the PDP name and followed IBM's naming conventions instead.
(DEC had waited too long to switch to 8 bits and lost the market lead.)</p>

<p>By the time Stallman joined the MIT AI lab in 1971 the writing was on the
wall and the only real question was how to migrate off the legacy installed
base of 6-bit machines going forward. But Stallman didn't realize that.
He went all starry-eyed fanboy over the PDP-10 running ITS in the computing
lab and made the newbie mistake of considering the status quo when he
arrived to be the natural order of things, eternal and unchanging.
The Bell Labs Unix team that started work on an 18-bit PDP-7 in 1969
got the budget approval to buy a 16-bit PDP-11 in 1970 (nominally to create a
typesetting system for AT&amp;T's patent and licensing department, their
own OS development work was a happy side effect),
and had Unix up and running on it in 1971. Unix had already made the jump
from 6 bits to 8 bits by the time Stallman arrived at MIT.</p>

<p>RMS inherited ITS because everybody else graduated and left it behind,
while he stubbornly clung to and defended it. Stallman theoretically graduated
from Harvard (Bachelor's in Physics) and came to MIT to do a doctorate, but
was only an MIT student for one year before dropping out and just working
there. (Back in college I tutored at BCC for extra cash and did data entry
for Rutgers' physical plant as a "work study" supplement to my student aid,
but I didn't try to make a career out of either one.) Stallman only left his
comfortable niche at the MIT AI lab when that niche _died_ because the hardware
it depended on was so obsolete MIT decided to stop paying to house it.</p>

<p>The nail in the coffin was the cancellation of
<a href=https://en.wikipedia.org/wiki/Jupiter_project>Project Jupiter</a>,
DEC's successor to the PDP-10. The project stopped making commercial
sense by at least 1965, but hung on for almost 20 more years (DEC
unable to quite admit its glory days of 6-bit PDP systems were over) until
it was officially cancelled in 1983, which is was what forced Stallman to
rebase to his hated Unix in September 1983. ITS was written in assembly
tied to specific obsolete hardware finally being discarded, and could not
run without that hardware. Unix had always been outright SMUG about being
a portable OS written in a language that let it run on many different types
of hardware, and the DEC guys all hated Unix for that. Ken Olsen called it
Snake Oil, Dave Cutler "chief unix hater" at DEC left to go join Microsoft
and do Windows NT to fight against Unix, because Unix was a threat to their
livelihood: your hardware isn't special. Stallman absorbed that zeitgeist
and was in the unix-hating camp until he found himself without a
community, and like a drowning man climbed on top of a nearby swimmer to
stay afloat. All the while explaining how thankful they should be to have
him.</p>

<p>Not only did Unix already exist, but Emacs already existed, and despite talking
about the importance of licensing the first version of "Stallman's" Emacs was
James Gosling's Emacs with Gosling's <a href=https://www.youtube.com/watch?v=TJ6XHroNewc>copyright notices removed</a>.
The compiler that
became GCC had also already existed, and Stallman's tweaks to it went largely
ignored until Ed Zander's money-grubbing decisions
circa 1987 (when AT&amp;T's legal department forced Sun to rebase from BSD to System V,
and thus discontinue SunOS and force its customers to migrate to Solaris)
unbundled basic system services like the compiler to charge extra for them,
and its frog-marched userbase balked at being nickel and dimed so instead
grabbed something else they could hammer into usable shape, and THAT'S
what made gcc load bearing. (Even if you paid the
extra money to get the Solaris compiler, it was so terrible malloc()
returned a char * and you had to typecast it. At least gcc had the source
code so people could FIX that stuff, just like Unix Version 7 had regularly
come with source code until the Apple vs Franklin decision extended copyright
law to cover binaries leading to the 1984 breakup of AT&amp;T and a sudden
crackdown on all the unix source people had been trading for a decade.)</p>

<p>Linux used what was there to build an eclectic katamari, and Stallman fought
hard AGAINST Linux for many years. Like someone racing out in front of moving
crowds, shouting to pretend he was leading. But Netscape's source code release
had nothing to do with him, nor did they GPL it. Linus only switched to
GPLv2 in 0.12 to avoid having to write his own license, reusing the license on
that compiler the Solaris userbase had just made useful. IBM's lawyer Eben
Moglen wrote that license, not Stallman. RMS later screwed it up forcing an
unnecessary version 3 migration down people's throats.</p>

<p>Stallman has always claimed to be a visionary, but he didn't even
respond to the move from 6 bit to 8 bit machines until 1983, and was
against Unix until he lost ITS. He's a conservative reactionary attempting
to recapture a "glorious" (largely imagined) past. Capitalism embracing the
extension of copyright to cover binaries and thus industry trying to stamp out,
fence in, and strip mine the open source development that created unix
and the internet in the first place was a BAD THING, and he was right to
oppose it. But he opposed it because it was change, not because he
understood WHY it was bad. Given his druthers he'd be back at MIT running
ITS on the PDP-10 until he died. All his "visions" are backward-facing, viewing
history through rose colored glasses. And he was thrilled to embrace the
DMCA to give Copyleft teeth: jackboots are fine as long as he's the one
wearing them, everyone else must do what he says or they're committing
a sin.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#06-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 5, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#05-07-2025</link>
   <pubDate>Sat, 05 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Jesse Rosenstock's patches have me looking at taskset again, which is one
of those gnu/crap things that produces non-unix output, ala:</p>

<blockquote><pre>
$ taskset -p $$
pid 31360's current affinity mask: f
$ taskset -p 1 $BASHPID
pid 31360's current affinity mask: f
pid 31360's new affinity mask: 1
$ taskset -p
taskset: bad usage
Try 'taskset --help' for more information.
</pre></blockquote>

<p>All three of those are wrong and annoying:</p>

<ol>
<li>Literally all I want is "f" (I have 4 processors, all are enabled,
hence binary 1111 which is 0xf) but have to
parse the rest of that crap to get it. And it's english output, so suddenly
there's internationalization issues where there should be none.</li>
<li>All the information in the second line of output is
either redundant or echoing back what I just provided to it. (If there's
an error write to stderr and exit with nonzero status.)</li>
<li>If I want to know the current mask I have to feed it a PID,
which I don't need for whoami or ulimit or pwd or... Yes those are technically
all process attributes but "this process" should be the default.</li>
</ol>

<p>That third one is _subtly_ wrong. I hit it trying to write a test to
confirm taskset worked, ala </b>taskset 1 taskset -p</b> but the PID of the
newly launched process DOESN'T EXIST YET when the command line is parsed so
I can't supply information that hasn't yet been generated. Even $BASHPID
doesn't help here, the command line is resolved before the fork() so
while it will tell you your (subshell) pid instead of the parent shell's
PID, it can't know the child process's PID:</p>

<blockquote><pre>
$ readlink -v /proc/self $BASHPID
31660
readlink: 31360: No such file or directory
</p></blockquote>

<p>What if I want to check if something like "sudo" is changing the task
mask, or ssh to another system and look at the task mask there? I have to
launch a shell to query the shell's PID in the new context, and then assume
the shell isn't changing the mask for the child I'm ACTUALLY asking about.
This is a question I am trying to ask in a context, and the command needs me
to PROVIDE a context which isn't necessarily the one I'm asking the question
in/about. It happens naturally if they don't add the stupid extra step.</p>

<p>Teaching readlink that -p with no arguments should use getpid() as the
process to operate on is simple enough, but the logical output is JUST
the mask without the spew of english. After all, the taskset is about
to exit and the PID go away: it's useless information because by the time
it can be reported it's no longer useful. Plus, THIS IS HOW UNIX COMMANDS
WORK:</p>

<blockquote><pre>
$ pgrep init
1
$ nproc
4
$ whoami
landley
$ hostname
driftwood
$ date +%s
1751750812
$ getconf PAGE_SIZE
4096
$ uname
Linux
$ ulimit -n
1024
</pre></blockquote>

<p>You output JUST THE REQUESTED INFORMATION so I can do stuff like
<b>make -j $(nproc)</b> without having to stick a sed invocation inside
the parentheses to chop out the data I need. That's how unix has worked
since Bell Labs.</p>

<p>Unfortunately, Richard Stallman and thus the FSF has never understood this.
Stallman only pivoted to Unix when ITS died, before which he'd repeatedly
publicly disparaged Unix. He's really not a unix guy, he's a taking credit
for other people's work guy. He never LIKED unix, he just needed it as a
fallback position when what he'd been doing before blew up in his face.</p>

<p>So making <b>taskset -p</b> without arguments print JUST the current mask
seems obvious. I'm also thinking of adding a capital -P option to act like -p
with scriptable output, except... When you set it, the logical thing to
do is not print any output at ALL because we don't care what it WAS
(touch doesn't print the old timestamp, chmod doesn't print the old
mask it just replaced, chmod doesn't print the old ownership...)</p>

<p>There's a "not breaking old behavior programs expect, no matter how
stupid it was" vs "doing the right thing for new stuff". Previously
-p without arguments was an error so havving taskset produce new output
that ISN'T crazy is slightly inconsistent with how -p behaves with
arguments, but... lesser evil. A new -P should do the right thing, but
what is the right thing? Either produce no output (it's setting, not
querying), or only have a query function. If it's just querying then
you could </b>taskset -P $(pgrep bash)</b> and have it spit out the masks
for a bunch of processes at once... but should it then print which PID
each mask goes to?</p>

<p>The way grep works, if you only ask about one file then it just outputs
the matching lines, but if you ask about more than one file it prefixes them
with the filename: to identify which file each maching line came from.
There are explicit flags to control this behavior (-h will hide the
filename and -H will force the filename even with just one input file),
but the default tries to automatically do "the right thing".</p>

<p>I don't want to add taskset -h and -H, but I don't want the output
to vary if pgrep only returned one matching file so it says "f" instead of
"123 f" and whatever's trying to parse it has the format change out from
under it.</p>

<p>Sigh: reality is complicated. Stuff like UTF-8 (also from Ken Thompson)
are generally the result of a lot of thinking to WIND UP with "simple".</p>
</span>


]]></description>
   <guid>http://www.landley.net/notes-2025.html#05-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 4, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#04-07-2025</link>
   <pubDate>Fri, 04 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>

<p>Yay!</p>

<blockquote>
<p>Thank you for contacting Spamhaus,</p>

<p>You have our sympathy for being the victim of such sloppy dealing by an AV company.</p>

<p>I've removed the listing for your domain, and tagged it so it should not get re-listed. The listing still came from our malware team, so I'm going to put the mild roaster in the fire to heat up and ask them what's going on. Seems like indeed your compiler was flagged as malware, again.</p>

<p>Note that currently this is flagged as infected on your site: /aboriginal/downloads/binaries/cross-compiler-m68k.tar.gz</p>

<p>As that cross compiler is used a lot to generate malware, someone has probably made the wrong conclusion again. However, that also makes your compiler a target for other malware operators... if they can infect the compiler, that would give them instant access to a lot of interesting devices. Can you please make sure that that tar file contains what you think it should contain? There are a bunch of binaries in it that we cannot verify. (You may consider PGP-signing your downloads).</p>

<p>Regards,<br />
Patrick McIntyre</p>
</blockquote>

<p>And my reply:</p>

<blockquote>
<p><b>&gt; As that cross compiler is used a lot to generate malware,</b></p>

<p>I'd apologize but... I made an easy to use general purpose tool. People used it. Some of them are not nice people. I'm not really in control of that part.</p>

<p><b>&gt; someone has probably made the wrong conclusion again.</b></p>

<p>The compilers for different architectures in the same release were all built in the same work directory, so it presumably leaked the same string the rule used as its identifier. I doubt there's a lot of m68k malware active in the wild.</p>

<p>It's not always the same string (over the years I've had different working
directories for different releases) which is how I know it wasn't just ONE
antivirus researcher who thought /home/landley made a good fingerprint. I
think the first time I bumped into the issue was "why is my nearly unique last
name in a <a href=https://www.freepatentsonline.com/y2018/0255081.html>patent
application</a>?" and that used /home/landley/work/ab7/build/temp-armv6l/gcc-</p>

<p>(A german immigrant named Landecker going through Staten Island during World
War I decided a less German sounding name might be a good idea so he made
something up, and I am the proud bearer of that tradition. There's like three
of us on the planet. Although a couple people made up the same thing as a
stage name, and Conan O'Brien blamed a monorail on it.)</p>

<p><b>&gt; However, that also makes your compiler a target for other malware<br />
&gt; operators... if they can infect the compiler, that would give them<br />
&gt; instant access to a lot of interesting devices.</b>
</p>

<p>I dunno about "instant", but yes supply chain attacks are a big deal. A lot
of the work I've done has involved trying to
<a href=http://lists.landley.net/pipermail/toybox-landley.net/2020-July/011898.html>secure supply chains</a>
against Ken Thompson's "trusting trust" attack.</p>

<p>At this point I'm reasonably happy deleting the 10+ year old binaries off my website and pointing people at https://web.archive.org/web/20171205071925/http://landley.net/aboriginal/downloads/old/binaries if they want copies. The old ones are not recommended for new projects, just... convenient. (And if they can retroactively suborn archive.org we have bigger problems.) Hmmm, I can stick a pragma redirect in index.html of downloads/old and then point the aboriginal/downloads/binaries symlink at that directory instead of the release directory... Done. And the binaries themselves have been taken off the site.</p>

<p>As for the new ones in https://landley.net/bin I was thinking of putting sha512 hashes either in a hashes.txt file or in an index.html file providing the links, but I'm not sure what that proves? (How hard _are_ hashes to spoof these days? There's a whole lotta cloud out there, and state actors are very much in play.) Even if the site has a hash right next to the link so you can right click, download, then run sha512sum immediately and compare them... if they can replace one file in that directory they can probably replace all of them on the same site, so I'm not sure what it proves. And even then manual verification is a thing most people don't actually do. I'd need to host the index.html and tarballs on two different servers so they couldn't just trivially replace one and not the other, except if the hashes are in the index.html file then they can replace the _links_ and if the hashes.txt is what's separate even fewer people would bother checking it (and again, they could suborn manual navigation to the hashes)...</p>

<p>All the repository infrastructure where yum or some such can automatically verify the key with chain of trust takes away the "Hey Mr. package maintainer: to reproduce this issue that only happens on hardware you've never seen, wget https://tarball, run these three lines to build the right type of binary from your package source code, and then run the resulting binary under qemu-blah."
And yes, I did some subset of that yet again
<a href=http://lists.infradead.org/pipermail/linux-arm-kernel/2025-July/1042138.html>earlier today</a>.</p>

<p>This spam filtering issue may be what hiccupped
<a href=https://lkml.org/lkml/2025/7/4/1675>this lkml web archive copy</a>
and it's quite possible half the recipients didn't get it. (Dunno! I also dunno why for my flight to japan yesterday I couldn't get the customs email despite retrying twice so I had to send it to my wife. I hope this clears that up.)</p>

<p>Aboriginal was about providing system images where they could boot a VM that
let them build and test their package, and these days I have my new
<a href=https://github.com/landley/toybox/blob/master/mkroot/README>mkroot</a>
subproject performing a similar role (it's not at parity with the old one yet,
I'm working on it), but you still need the separate cross and native toolchains in order for the other guy to build their thing so they can reproduce the issue so they can diagnose and fix it. (And if they decide they like it and want to pull my stuff into their automated regression testing, I made plumbing for that too! But it all still needs the compilers.)</p>

<p>If I go "ok, I'll put up a debian repository, strong keys automatically checked" and the package maintainer to whom I'm trying to give a reproduction sequence for an issue that only happens on a big endian 32 bit system that cares about unaligned access... If they use Arch and I don't use Arch... Yeah.</p>

<p>I've always found dealing with gpg fraught. The key signing infrastructure that kernel.org used to use went away some years back, and I don't remember what replaced it (or how to fetch a specific user's public key in a secure manner other than having them email it to me which proves what exactly?), and I haven't gone to the right conference parties to get a new key of my own signed for _years_... And having them verify a gpg signature on a tarball if people won't check a hash... how is gpg going to improve matters.</p>

<p>I agree it's a problem, one I've thought about. I don't always how to provide security and convenience at the same time, and the convenience is why it gets used. A fig leaf to make people feel more secure without _being_ more secure doesn't sound good. I can't secure people's supply chains FOR them. I can try to show them how I'd do it, but generally that means building your own binaries for actual deployment to customers...</p>

<p>So far Dreamhost has been pretty good about not having its servers hacked,
I go to a certain amount of effort not to upload crap to it, I irregularly
check that what's there is what I think is there, every time I get new
hardware I rebuild everything from scratch on a fresh install and go through
my backups to go "this is what I think it is, right?", and I basically just
assume everything is compromised all the time and try to act accordingly.
(My laptop has a band-aid over the webcam, and my phone has painter's tape
on both of its. I stayed on chrome longer than I should have because
"pkill -f renderer" crashing ALL THE TABS and then clicking "reload" in the
one I cared about using right now was probably not in most attacker's
counter-threat models. On more than one occasion when people I didn't know
gave me binaries to test I ran them under qemu application emulation running
inside a VM booted from an ISO image, or from a debian cross install for a
different architecture. Yes,
"<a href=https://dwheeler.com/trusting-trust/>countering trusting trust via diverse
double compiling</a>" AT RUNTIME. And I still just assume everything's
_already_ exploited. You worry about system management mode or GPU-resident
malware, I'm going "There's at least 7 processors in this laptop outside its
SOC" and vaguely remember watching somebody in a BOF talk about using a badusb
variant (except the embedded 8051 processor in an sd card version) to reflash
disk controller firmware in a way that searched and replaced specific data
under specific circumstances as a small part of a large chain. A quick search
for "the genere" found <a href=https://www.malwaretech.com/2015/05/hard-disk-firmware-hacking-part-5.html>a random example</a>
from 10 years ago.</p>

<p>There are domain experts who have FUN with this stuff. (Many of whom are women who escalated from protecting their drink from roofies to protecting their router from stalkers to getting paid for many years of accumulated expertise acquired at least partly in self defense.) People told war stories about a drone looking through a window at the reflection of a blinking ethernet transceiver link status LED to exfiltrate air-gapped data in 2010.</p>

<p>I can't FIX that. If the kind of people my grandfather spent 40 years working for decide to exploit my laptop so I'm uploading pre-exploited binaries without knowing it, I doubt I can stop them. (Of course given that I break everything, constantly, it's likely to go a bit weird before long and the chance of accidental discovery because I or the kind of people I interact with vindictively Root Caused A Thing is nonzero...)</p>

<p>But "safe"? I can only do my best. If I seem a bit laissez-faire about
https://xkcd.com/538/ it's because I know just enough to try not to screw up
MY little part on purpose. "Here's how THAT breaks" is a hole with no bottom
around here. You 80/20 it, hand off to the people with clipboards and clean
room suits (sighing when they file it unopened again), and move on.</p>

<p>(P.S. since this is turning into a conversation, is this a public URL I can point my open source users at? I try to get the information out there so other people can follow along. Open source development and all that...)</p>
</blockquote>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#04-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 3, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#03-07-2025</link>
   <pubDate>Thu, 03 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>In Toronto airport, waiting for the flight to tokyo. (Out of the states,
clear of ICE and the TSA for the moment.)</p>

<p>The linux-6.15 powerpc build broke, trying to pull in the stupid extra ELF
library I've been patching out of x86-64 for years now. And armv7l broke by
segfaulting during the link. Both of them build fine in 6.14 with
the exact same toybox, so each is a kernel commit I need to bisect to.</p>

<p>Powerpc broke because of <a href=https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f50b45626e05>a commit</a>
implementing inline static calls (whatever that means) which adds
select HAVE_STATIC_CALL_INLINE if PPC32 which
apparently is triggering the objtool horror. Can I PPC32 &amp;&amp; !FRAME_UNWINDER
and it works again.</p>

<p>The airplane had an hour of turbulence that prevented them from serving
us the second meal. Mostly rereading murderbot on the flight, packed to
the gills in a middle seat with no elbow room to laptop much.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#03-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 2, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#02-07-2025</link>
   <pubDate>Wed, 02 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>Yesterday's tangent forkbomb is what my style of development's always been
like. Keep digging until the hole goes through, then when you see daylight
back up and try to remember where you started and why. It's sort of reassuring
to be back... except for the need to go to japan soon so I have to park all
this (and return to moving house again). And of course the whole "I may never
be employable again" thing that makes it hard to justify the time. (After
both the dot-com crash at the start of W's tenure and mortgage crisis
at the end of his 8 years, I was young enough not to face age discrimination,
single enough to live in a broom closet (with the option of crashing with
relatives if necessary), and we didn't have any inflation to speak of.
Now we're facing what may be a new Great Depression (Orange Hoover is
even replaying the Hawley-Smoot tariffs, except this time he's also the America
First candidate trying to make nice with the nazis) which took 10 years to
dig out of.</p>

<p>Age discrimination has some real underpinnings: I don't really want to
learn AI or Rust because they're not fun. But is that NEW? Back around Y2K
"I don't do Windows or use AOL" made me only semi-employable.
I left a good solid career job (with health insurance, 401k, and employee
stock purchase plan) at IBM to pursue Java (working at a start-up) because
I was chasing the FUN work, then I left Java behind while it was still really
hot because Linux was more fun (and Sun was trying to be Microsoft),
gradually distanced myself from C++,
refused jobs at Faceboot and Amazon even 10 years ago... Today I'd LOVE an
excuse to get into Lua, and have largely wandered away from Python (well,
it left me: Python 2 remains great, Python 3 ain't stable, which took all
the fun out of it.)</p>

<p>I've always gone for "interesting"
over "lucrative", and periodically thought about getting a day job
working in the video game arcade on the drag (before it was evicted by
the Cult of Scientology next door) or a bookstore or coffee shop. I
envied the night watchman at the UT student center (back when it was
open 24 hours) who patrolled the building once an hour but otherwise
sat at his desk reading. But people kept offering me money to program
for them, and it paid so much more than my other side hustles (teaching
programming courses at ACC and writing columns for The Motley Fool)
that "do this to refill the bank account then take some time off"
was always a better use of time. (When I bought the condo on west
campus in 2004, my monthly fixed expenses were $660/month with just food and
electricity on top of that. I had no health insurance, but that wasn't quite
the crisis it is today.)</p>

<p>Another real reason for age discrimination is cost: working full-time,
I was earning 4 times what Fade makes (and she's got a doctorate).
Then again, one of the best pieces of advice I ever got was "let the employer
name the figure, if you ask for too much you won't get the job and if you ask
for too little they'll give it to you". That's what I got offered. I didn't
usually work full-time before buying the big house in 2012 (didn't need
to, short contracts with months of downtime between them is how I had
time to do so much open source work, plus I wasn't really saving for
retirement), and after that most of the money I made got eaten by the house
(they're EXPENSIVE, especially when the climate decides major natural
disasters are now an annual event). Plus the J-core work for Jeff paid
less than the company I left to work go for him in 2014 (but the tech
was WAY more fun), and then that figure got cut in half the first time
SEI collapsed (shortly after the 2016
election when advancing renewable energy technology suddenly had headwinds
from the CEO of Exxon becoming secretary of state). When I went to work
for Jeff I had $40k cash savings, which threw itself on the first of
the four house floods in 2015. Then we ran up a $50k home equity loan over the
pandemic...</p>

<p>I've never been motivated by money, but I've periodically had to
worry about a LACK of money. And it's not something I've ever wanted to inflict
upon Fade, that's why she pays all the bills. Regular late notices stressed her
out. (I had the money, but never did the paperwork on time.) And she's not
comfortable living in basically a broom closet in an old building like I've
often done.</p>

<p>Urgh, Orange Fuhrer's Big Billionaire Bill passed the senate. I need to
switch to Fade's health insurance, which I think I can do in September because
that's her contract renewal thingy? (Hideously expensive, but the US
healthcare system is about to collapse...)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#02-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[July 1, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#01-07-2025</link>
   <pubDate>Tue, 01 Jul 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>[Note: First time I edited and uploaded these entries I labeled each day
in June "July", although the links had the right month number. Yeah I can
count. Yes I'm more than a month behind editing and uploading so did it
as a historical batch. I should... make tooling or something.]</p>

<p>Got the travel plans email: I fly to tokyo on the 3rd and fly back on the 26th.
(Which means I arrive on the 4th due to the international date line,
and arrive ack on the 26th for the same reason. In one direction 12 hours
of travel takes 36, in the other it takes negative 12. This is probably why
flights from the USA to Japan leave in the morning (so 12 hours "later"
you arrive in the evening ready to crash from exhaustion despite the jetlag),
and flights back leave in the evening (so 12 hours "earlier" isn't 3am).</p>

<p>Trying to tie off the toybox work I've been doing, but... over in xzcat
it's doing unaligned variable access but not using the peek() function
lib/lib.c has for that. But this is performace-ish critical code (or at
least a CPU intensive thing in a big loop where you notice extra
expenses) and lib.c's peek() returns "long long" with the hand-rolled version
in xzcat returning 32 bit "unsigned". The expand and then trim back down is
expensive on 32 bit platforms. Looking at peek() and poke() all but
2 users of the first are already 32 bit, and there's only ONE user of
poke (it's ifconfig) which says it probably shouldn't be in lib.</p>

<p>So I removed poke() and replaced it with memcpy(), except it needs a
slightly non-obvious big endian adjustment ala
<b>memcpy(dest, ((char *)*src)+IS_BIG_ENDIAN*size, size);</b> (which is
basically why experienced programmers usually hate big endian). I definitely
want to test that before pushing it, so I cloned a clean repository and
did a mkroot build of 4 architectures (32 and 64 bit little and big endian)...
and my first guess at CROSS=i686,powerpc,aarch64,s390x didn't work because
I never implemented CSV for CROSS. (Oops.)</p>

<p>I can actually do that in one line: <b>[ "${CROSS/,/}" == "$CROSS" ] || { TARGETS="${CROSS//,/ }"; CROSS=all; }</b>
which goes "if $CROSS has a comma in it, turn the commas into spaces and
make that the list of available targets, and then set CROSS=all so we build
all available targets.</p>

<p>And then when I tried to check that in, the powerpc build failed. Because
it's trying to #include <gelf.h> which is that stupid extra ELF library
I patched out of x86-64: now it's spread to 32 bit powerpc. Wheee. I need
to update that patch. Ok, let's JUST build s390x for now so I have a 64 bit
big endian target to test. Which built! And didn't boot. Why didn't it
boot? Because CONFIG_SH and CONFIG_ROUTE aren't set, which I
<a href=https://codeberg.org/landley/toybox/commit/8c6692585994>thought I had
fixed</a> but apparently not!</p>

<p>Ok, the reason it's failing is I'm doing <b>make defconfig KCONFIG_ALLCONFIG=&lt;(echo $'CONFIG_SH=y\nCONFIG_ROUTE=y')</b>
and "make defconfig" is calling kconfig twice: the first invocation
(kconfig -h to write generated/help.h) consumes the &lt;() output,
and the second one (kconfig -d to produce the defconfig .config file)
sees an immediate EOF. So the code works, the invocation doesn't.</p>

<p>Ok: -h should not be consuming the KCONFIG_ALLCONFIG data,
move the -h processing before the getenv() and fopen() (and have it return
instead of continuing) so the first invocation doesn't even open the file,
and... yay, it produced a config with SH and ROUTE set! Alright,
let's do a "make distclean; mkroot/mkroot.sh..." and it broke because
scripts/install.sh got called with an empty generated/help.h file.
No wait: one that only contains the line for the "basename" command.
What? Ah, don't return IN the for loop, return after it. I broke -h
moving stuff around, of course.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#01-07-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 30, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#30-06-2025</link>
   <pubDate>Mon, 30 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>Now the censorious payment processors are <a href=https://youtu.be/cimiBN1Ipzs>going
after</a> the
<a href=https://youtu.be/EPzdnW_g8yk>furries</a>,
which seems <a href=https://youtu.be/PycBjZPtK1Y>ill-advised</a>
but if they were smart they wouldn't be in maga.</p>

<p>It's like the "secure your account!" spam emails with a link that actually
goes to some russian website. The drive for security itself BEING the exploit.
There can never be ENOUGH, you are never actually safe. Comet could strike
tomorrow. There is a level of risk we live with, snake oil salesmen drumming
up a panic are selling something.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#30-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 29, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#29-06-2025</link>
   <pubDate>Sun, 29 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I've been writing long emails to the toybox list instead of blogging.</p>

<p>I've actually had FOCUS recently, which is... something I'm out of the
habit with. Fade microwaved a chimicanga for dinner because I started
answering email and looked up and 8 hours had passed. (She interrupted me
twice to make sure I was ok and I went "just let me finish this" and...
another 4 hours went by.)</p>

<p>So. Much. Eyestrain. (I mean she's got ADHD too, this is actually a sign
of mental HEALTH for us weirdoes. But it's been quite some time since I
could really get into the zone, as it were. In college, a professor loaned
me Czimenhalyi's book "Flow" (which is where "flow state" got named from,
apparently originally rock climber's terminology for it), and packing up
in Austin I found it still unread on the shelf. It's in a box somewhere.
I'd apologize to the professor if I remembered her name or had contact
info... At the same time, part of the reason it's unread is "I don't have to
read it, I lived it...")</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#29-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 28, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#28-06-2025</link>
   <pubDate>Sat, 28 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<P>Excellent historial video from J. Draper's "London History Show" titled
<a href=https://youtu.be/SJ_DsLtE-mM>Victorian Ladies Don't Poop</a>.
It's all about how the rise of public toilets in victorian london
was male-only for over a decade as a way of controlling women and excluding
them from public life, "for their protection". The exact same condescention
rich old white men have for everyone who ISN'T a rich old white man today.</p>

<p>The central idea of fascism is that people can't be allowed to run their
own lives. White Diamond's "I only want you to be yourself! If you can't do
that, I'll do it for you!" manifests itself in SO many different ways,
but it's always the same idea. From "democracy must be represenative
rather than direct, with first past the post instead of instant runoff to
preserve a two-party system, and layers like the senate preventing mob rule"
through to outright dictatorship.</p>

<p>And here's an oldie but goodie, <a href=https://youtu.be/3nh-jvm2GPg>150
years of mannish women causing a moral panic</a>.
Nothing about this is NEW. Espeically not Schumer and Pelosi, they
are SO FAR past their sell-by date...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#28-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 23, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#27-06-2025</link>
   <pubDate>Fri, 27 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Supreme Court upholds Texas' online age verification for porn sites, in
a <a href=https://abcnews.go.com/Politics/supreme-court-upholds-online-age-verification-porn-sites/story?id=123224921>6-3 ruling</a>,
all the Trump judges vs the 3 sane ones. You'd THINK this would
tell the rest of us something, but no. Pelosi and Schumer are SO HAPPY to
be in bed with the mor<strike>m</strike>ons.</p>

<p>It's not about tracking. It's about de-anonymization. (And shame,
and loss of bodily autonomy, and kompromat, and...)
You can't blame advertisers when <a href=https://youtu.be/gPK7yOfRAaU>Tubi
has</a> the "raunchy, uncensored, and unrated flicks".</p>

<p>The right wing loons are always a tiny loud minority.
<a href=https://youtu.be/FF7aNx0_XQI>More than half of US
school book bans traced back to just 11 hateful people</a>.
You have to STAND UP TO THEM. The Boomercrats are not doing so.</p>

<p>The Boomers will die. Until then, maybe it's best if all the infrastructure
feeding Billionaires rots. The pax americana is a net negative,
the country that did the trail of tears can't be trusted with it, and
should recede into history like the british empire and roman empire did.</p>

<p>(A dozen years ago it came out that the publishers of
<a href=https://www.theguardian.com/commentisfree/2013/may/02/anne-franks-diary-pornographic-uncomfortable-truth>the diary of Anne
Frank</a> edited out things she wrote about sex, before dying in a nazi
concentration camp at age 15. At the time,
the culture was open and sex-positive and we thought this censorship
was "forcing women to wearing burquas" levels of shameful. Then the shriveled
up Boomers passed Fosta/Sesta in 2017 and started the reich-wing crackdown
on everbody to HIDE YOUR SHAME, don't ever talk about anything, sex is only
in marriage only for procreation and you should deny and repress everything
else and I'm annoyed how many people are BUYING INTO IT just because the
current zeitgeist is "geriatric fascist" and they go along to get
along with all the pearl clutching. They keep rotating their attacks against
sex work, payment processors, trans people using bathrooms, age verification,
but it's ALL THE SAME ATTACK. The conclusion never changes, the reasons
leading up to it do, until they find reasons you're afraid to oppose.
Doesn't matter whether they're attacking abortion, birth control,
gay marriage... It's all ONE THING.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#27-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 23, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#23-06-2025</link>
   <pubDate>Mon, 23 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Going through Oliver's xz commit list from February of last year.</p>

<p>I didn't burn out because of Oliver. 2016-2020 were very stressful
even before the pandemic, because orange man bad was generally terrible
and because it made the CEO of Exxon was secretary of state while
and I was working for "Smart Energy Instruments" making syncrophasors.
(Kinda derailing, and I even though I swore I wouldn't ride down another
startup...) Selling a house is stressful, even when you're not
baving to move out of a state where the governor's gone outright fascist
after decades of <a href=https://www.cnn.com/2003/ALLPOLITICS/05/13/texas.legislature/>gerrymandering</a>. Then Biden... watching an 82 year old man who campaigned
on DEFINITELY only serving one term gear up to run again
(egged on by octegenarians and septuagenarians in the house and senate as
a Nonagenarian died in the saddle) with his fallback position being the
ex-cop love child of Hillary "I am Inevitable" Clinton and Barack "change"
Obama (the sitting VP may be many things, but "change" ain't it), who then
spent the last month of her campaign celebrating the endorsement of Dick
Cheney and talking about how many republicans she was going to appoint to
her cabinet (_after_ MAGA and the tea party before it had spent a full
decade purging their ranks)... Quite often, I don't WANT to be right.</p>

<p>FDR (who <a href=https://en.wikipedia.org/wiki/1936_United_States_presidential_election>won 98.5% of the popular vote</a>
on a platform of "<a href=https://www.fdrlibrary.org/documents/356632/405112/afdr067.mp3>I welcome their hatred</a>" and yes that speech was his closing
argument <a href=https://en.wikipedia.org/wiki/1936_Madison_Square_Garden_speech>three
days before the election</a>)
beat down the supreme court by threatening to expand it, but Biden ruled
that out in favor of sending a strongly worded letter.
AOC is so closely modeled on FDR she calls her big bill
the "green new deal" (I.E. the new new deal), and Pelosi decidated her
golden years to making darn sure that when the new guilded age collapses
into the new great depression, and the choice is between left populism (FDR
or Teddy Roosevelent) and Right Populism (Stalin or Hitler), there would
NOT be another FDR giving "I welcome their hatred" speeches at
the plutocrats raising the top tax rate to 90% and hiring everybody in
the country with a pulse to go build infrastructure and do science.
Nope, this time only right wing fascists need apply, because otherwise
billionaires might get taxed!</p>

<p>Google's 12k layoffs (because it "worked" for Twitter) starting another
dot-com crash in my industry didn't help. Not that I've really shaken the
tree to try to find a position, now that Fade's graduated and gotten
a job with her shiny new doctorate, I'm happy being her stay at home wife.
(She commutes to the office every day, I cook and do the dishes.)</p>

<p>If the political situation wasn't crazy we'd probably look into fertility
treatments to try to have kids before menopause, but with fascism being
what it is... Kids have no rights these days. Sending someone off through
metal detectors to active shooter drills, losing custody if they're
ever seen playing a block from home without their parole officer standing
guard (or left in the house for the length of a grocery run)...</p>

<p>Once upon a time I thought "if the kid's anything like me, wave them at Kahn
Academy and they could probably pass the GED at 7" but they changed it so
you're <a href=https://www.ged.com/blog/what-are-the-requirements-for-getting-your-ged/>not allowed</a> to take the GED until 16. Because what they MUST learn is
commuting to an office and sitting at a desk always and forever is
<a href=https://davidgraeber.org/articles/on-the-phenomenon-of-bullshit-jobs-a-work-rant/>the natural order of things</a>.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#23-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 22, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#22-06-2025</link>
   <pubDate>Sun, 22 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Got the elephant through the snake, or at least I got my alias prefix
toysh change passing the tests and checked in. (With a TODO that the
trailing space to continue logic is wrong and I don't currently care.)
I have a zillion open tabs with yet more tests I ran, which should all
be marshalled into actual regression tests, and I'm working on that, but
there's other dirty bits in the tree that I should clean up for a release.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#22-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 21, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#21-06-2025</link>
   <pubDate>Sat, 21 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>So I've mostly worked through the prefix assignment rework allowing !
and redirects to intermix with prefix assignments. (I'm aware ! is a whole
decision tree of things starting with ! mostly because I saw a video
on it [I had a link but lost it with my youtube account], but RIGHT NOW
that's staying in its box on the todo heap.) But testing of course revealed
flaws in the alias plumbing I'd done to expand things before run_command()
gets a stab at it.
(They're separate layers: input strings get turned into pipeline lists
by parse_line(), and then run_lines() consumes said pipeline lists providing
individual ones as input to run_command() once the flow control statments
are resolved.</p>

<p>And working through THAT, I had a note that trailing space chains alias, but
how does that work with recursive alias
resolution? If an alias resolves to another alias, and that second alias
doesn't have a trailing space but the first one did... do I have to keep
track of the endpoints of each nested level of alias resolution to implement
this crap?</p>

<blockquote><p>
$ alias abc='def '; alias def=echo; alias xyz=potato<br />
$ abc xyz<br />
potato<br />
$ alias abc='def '; alias def='echo xyz'; alias xyz=potato<br />
$ abc<br />
xyz
</p></blockquote>

<p>That's not nice. I don't want to do that. But apparently busybox ash
does that too. Sigh. Ok, I should add the test and do it.
This really, really sucks. (And says the chained input sources WERE probably
the right way to go, vs the in-situ string modification.)</p>

<p>How horrible does:</p>

<blockquote><pre>
$ alias xyz=potato
$ &gt; xyz echo hello
$ cat potato
cat: potato: No such file or directory
$ cat xyz
hello
$ alias abc='&gt; '
$ &gt; xyz thursday
$ cat potato
cat: potato: No such file or directory
$ cat xyz
thursday
<p></blockquote>

<p>Ok, redirectors still eat their following argument without alias expansion
regardless of this "pending more alias expansion" nonsense.</p>

<p>Right, currently I've got a "noalias" variable in pl to indicate when alias
expansion's either disabled or exhausted, and I've got an "aliseen" list
of previous aliases that got expanded already in this stack...</p>

<blockquote><pre>
$ alias xyz='abc '; alias abc=def; alias ghi='echo ';
$ ghi xyz xyz xyz
def def def
$ ghi ghi xyz xyz xyz
echo def def def
$ alias xyz='abc'; alias abc='def '; alias ghi='echo ';
$ ghi ghi xyz xyz xyz
echo def xyz xyz
</pre></blockquote>

<p>Huh. Is it only the TOP level alias that says when we do this
continuation mess?</p>

<blockquote><pre>
$ alias abc=def def='ghi ' ghi=jkl ee='echo '
$ abc abc
bash: jkl: command not found
$ ee abc abc
jkl abc
</pre></blockquote>

<p>Yes. I think. Darn it, it's hard to come up with proper tests for this
weird nested behavior without paper and pen to draw trees with, but I _think_
only the top level one gets checked for continuation. So I don't actually
need a checkpoint, I just need a saved flag to look at when I clear the
aliseen stack. I think.</p>

<p>Still not comfortable I've got my head wrapped entirely around the additional
sharp edge in this legacy nonsense "feature". I would very much like to STOP
working on this part and move on to something else, but it's still not
RIGHT...</p>

<p>Vim autoindent found a new way to screw up. I use two space indents for toybox
and they're all spaces, not mixed tabs and spaces. It tries to insert tabs
at the start of the lines, and since I haven't figured out how to get it
to stop I'm adding ":set paste" to my ":set mouse=" which I of course have
to do manually in every window because it won't read it from the /etc files.
(It USED to do all this stuff just fine before the OS version upgrade. It
grew a bunch of new unwanted "features" that I can't easily disable.)</p>

<p>Sigh. If toybox didn't have a vi in pending already I'd probably divert into
writing one before too much longer. But it does, so I can't. And reverse
engineering the existing one is a rathole I don't want to go down right now.
Oh well.</p>

<p>So here's the problematic alias test:</p>

<blockquote><pre>
$ alias ee='echo ' def='abc xyz ' xyz='abc '
$ ee def xyz
abc xyz abc
</pre></blockquote>

<p>When checking for additional aliases because of trailing space, you don't
start the "additional" until you've consumed the output of the previous alias
substitution. But the way I'm doing it, it's a simple string substitution that
calls back into the original logic, so that "xyz" that gets passed through is
just as validly "next" as the one that gets substituted. My parser doesn't
care that it's the result of a previous alias, it's all the same string
input. I have to ADD A CHECK, and update the offset at which we "resume"
with each recursive substitution.</p>

<p>Ok, punt that.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#21-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 20, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#20-06-2025</link>
   <pubDate>Fri, 20 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Went out to the not-mall (the Univeristy of Minnesota Student Center,
which is open to the public and has a Starbucks in the basement that still
sells Madeleines for $2.50 a bag, which is almost a dollar per
cookie but nine years into trumpflation that's almost reasonable).
I'm actually more productive with something like office space, but as
with externally imposed deadlines it doesn't work to do it myself. Setting
aside a specific chunk of the apartment to be workspace is just the apartment
again. I'm not "out and about".</p>

<p>Grinding through the toysh bugs from the changes I made, the prefix
assignment cascading into redoing function call member lifetime rules,
and some in-passing bug fixes (the "set" command was using an uninitialized
variable which the compiler did NOT warn about; it does all these "may be
used uninitialized but actually isn't" warnings and then MISSES REAL ONES.
Sigh. ASAN didn't catch it either, but then I don't think I have "set" tests
using the long option names yet...)</p>

<p>I got everything passing in the Devuan Chimaera KVM (the old OS release
where ASAN still works) a while back (trick: if you set up httpd on loopback
you can wget the source file from the host to do test builds over there
while only ever editing the master copy on the host), but it still
fails on current devuan because they keep trying to make C more brittle.
Problems with gcc, problems with glibc...</p>

<p>And at the end of all that... I broke "alias" again. HOW?</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#20-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 19, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#19-06-2025</link>
   <pubDate>Thu, 19 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>Spending multiple days reading Murderbot got me into the habit of wanting
to read instead of wanting to program. (As opposed to wanting to watch
youtube instead of wanting to program.)</p>

<p>Programming is still a fun hobby of mine, but it's hard to convince
myself it's _important_ during Böömerdämmerung. Making a nice little
reference Linux system you can audit down to (and through) the bare metal
so future generations don't lose institutional knowledge about how their
systems work seems less important when unguillotined billionaires who
did regulatory capture on the entire government are
trying their hardest to roll back the civil war and cold war simultaneously,
so we have both slavery and a berlin wall behind which every phone is bugged
and every neighbor reports on every other neighbor. Plus the phones
themselves are locked down corporate spyware straight out of Max Headroom
or cyberpunk, the supply chains to make them are spiraling inwards,
and spending all your time online seems like a bad idea. (Although going
outside when EVERY STATE in the lower 48 is supposed to have 100 degree
farenheit weather at least once this week... We're on track for 3
degrees celsius rise from the _existing_ wells without drilling new ones.
The difference between "japan is a peninusula" and
"japan is an island" at the end of the last ice age 12,000 years ago was
about 3 degrees. (The peak was colder but that was millennia earlier.)
"How to survive a wet bulb event" needs to be taught in middle school,
they'll need it.)</p>

<p>I called my father on Father's day, and he's turned 80 now. I thought he
still had a couple years, but I forgot he was almost as much older than my
mother as I am older than Fade. (I was terrified of getting anyone pregnant
until I turned 30: aids, overpopulation, poverty... Looking back on it, that
was fucking stupid, but that's the messaging the Boomers sprayed everyone
younger than them down with. "Don't do what we did, never trust anyone
over 30 and we've all turned 30." These days even AIDS is basically "contagious
diabetes", it's treatable to the point you'll reliably die of old age
and the same treatment works as an effective prophylactic preventative ("PREP").
We can vaccinate for HPV, but the reich wing loons are INCENSED that
the FEAR OF DEATH is being taken out of sex the same way the copyleft
loons were SO MAD AT ME for trying to stop Busybox from being used as
a club to beat kernel sources out of people.</p>

<p>Here's a <a href=https://www.nytimes.com/2025/06/18/health/hiv-fda-lenacapavir.html?unlocked_article_code=1.QU8.klxa.FzV5q9QQliOp>long article</a>
about DOGE cutting funding for the AIDS vaccine.</p>

<p>Did you know that the main guy trying to push sex out of public life
is the same guy behind the SCO lawsuits? All that money he gobbled up
via Canopy Group when Ray Noorda went senile got turned into a big Mormon
anti-sex campaign. It is the SAME ASSHOLES. Me not being on faceboot
for 30 years didn't stop Palantir. They've all come together into a
voltron of self-righteousness in Project 2025 so they can moralize at
everyone, do as I say not as I do. Sunlight is the best disenfectant and
turnabout is fair play: put a toilet-cam under every billionaire.</p>

<p>"Give me a child until the age of 7." Learned helplessness.
The problem is "it is not their choice".
If they can't say no they can't say yes, you are making their
choices for them EXACTLY THE SAME WAY all those pastors are. I want to
hand off to AOC and Greta Tundberg and FOLLOW instead of leading. Scotland
lowered the voting age to sixteen and I'd personally be happy to bump it
down to twelve. They're not going to make dumber decisions than the Boomers
are making right now. Learning from your mistakes starting at 18 doesn't
mean you make less mistakes, you just have less time (and supervision) to
recover from them.</p>

<p>On the one hand, I'm against AI. On the other hand, robot voices reading
reddit articles should be a service REDDIT provides, and there's a bit
of selection in cherry picking which comments to include. Today's
example: <a href=https://youtu.be/JLEevYFeSm4>What's your strange fetish, how'd you find out?</a>
Which I ran in my headphones while loading the dishwasher...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#19-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 17, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#17-06-2025</link>
   <pubDate>Tue, 17 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Google did a thing again last week [removing device trees]. On top of the thing
they did the previous week [yet more layoffs] or maybe because of it? Maybe they
don't have enough people left so they're throwing cargo overboard to
stay afloat? No idea, I'm out of the loop. But I did toybox long before
anybody else used it. I was never doing it FOR Android per se, I want
a nice clean understandable and reproducible base system.
I should do those explanatory videos I kept meaning to do,
except ever since Youtube went sideways that's meant setting up a peertube
instance or something, which I have not had the spoons for.</p>

<p>Jeff is thinking of maybe flying me back to Japan on the 30th. Nothing
confirmed yet. And this time I probably can't take a spare suitcase to fill
up with snacks. (My little suitcase fits as a carry-on, and the little one
ALSO fits inside a bigger one, originally part of a matched set, so if I
just bring a small suitcase full of clothes I can check one bag on the way out,
and one plus carry-on on the way back.) But some orange idiot eliminated the de minimis exemption
so I'd pay a big beautiful tariff and I don't want to deal with the paperwork.</p>

<p>I left off on toysh wrestling with one of those changes that
keeps trying to spread into a tectonic archaeological shift in the design
infrastructure, which once again boils down to object lifetime rules.
(And no a reference counted language wouldn't help here, it's a visibility
question, what occludes what.)</p>

<p>Did you know that if you start a script with "#/bin/bash -c" bash hangs
running it? If you just run "bash -c" from the command line it says "option
requires an argument", but the BINFMT_SCRIPT loader entry path doesn't
seem to have an error check. (The loader can provide exactly one argument:
everything after the first space becomes argv[1], and if there are multiple
spaces then that argument has a space in it). I _think_ bash is endlessly
reloading itself, not sure. Eats cpu, but not a single processor peg, or at
least it doesn't look like one in the xfce cpu graph. Yup, strace says it's
doing an exec() on the script file over and over and over.</p>

<p>I should email Chet. I dowanna email Chet.</p>

<p>Anyway, the tricksy bit I was halfway through changing is that $0 never
seems to get assigned to outside of sh_main(), nor does it participate in $*
and $@. It's not REALLY part of the function-level sh_arg{v,c} that $1 and $2
and so on are, which are affected by "shift", replaced by "set" or "source" or
shell function calls... so I was breaking it out into its own variable,
and that variable doesn't even REALLY belong in sh_fcall(), it belongs
at the top level, as TT.argv0 or some such. Which means all the previous
logic that was doing a lot of "shift-1" and "arg.c-1" and "pos&lt;=arg.c"
now has the -1 and = stripped off in most places, which is just an off
by one error waiting to happen. (It's simplifying, but stripping off
all the special case code because the semantics changes is still an
exercise in de-boning a salmon with pliers. Try not to miss one.)</p>

<p>That's what the test suite is for. I have SO MANY MORE tests to add to it,
but adding tests that don't pass just means drowning in noise, so I
have basically "pending tests" which is.. categorically sad.</p>

<p>Hmmm... I should figure out some way to traverse the $BROKEN annotation
in tests/sh.test (tests bash passes and toysh currently doesn't but should)
so it finds all the ones that DO pass now, so I can untag them in blocks.
Alas <b>VERBOSE=all TEST_HOST=1 BROKEN="echo ];" make test_sh</b> doesn't
RUN the affected tests, because the ; isn't parsed as a control character
but expanded into a literal so the echo eats the whole line and I get
the testing function invocation lines echoed to stdout instead of executed.
Probably need to make a shell function? Besides, at least one test is
hanging and it hasn't got the timeout -i 10" wrapper plumbing standard
in the whole test suite yet, so VERBOSE=all doesn't reliably terminate.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#17-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 16, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#16-06-2025</link>
   <pubDate>Mon, 16 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Fade got Apple TV (we dropped Hulu for it) so she could watch Murderbot with
her friends on Mondays (it comes out something like wednesday but she holds
off until scheduled group watching time), and I sat down and several days
ago I watched the accumulated episides with her so I could participate in
the monday communal activity... and then I went and read all 7 books. And
two short stories. I am now out of murderbot. :(</p>

<p>Ordinarily I go for audiobooks these days because eyestrain tends to be my
liming factor for computing (if the USA had a functional healthcare system
I'd have both cataract surgery and proper ADHD meds, but alas we have
unguillotined billionaires instead), but I tanked the eyestrain to read
the books. Considering re-reading the whole series again, but I should
probably give it a week.</p>

<p>We watched the new episode tonight. It's a bit campy compared to the books
(bordering on "hammy" in places), and of course they made the protagonist
a chiseled handsome white guy. But the actors are VERY good, and the dry
humor of the books would be almost impossible for an american production
company to pull off. (The people who did "Yes Prime Minister" could have.)
The series consisting of one long acerbic snarky first person inner
mologue from a non-human construct, which for example never once describes
food (the humans around it ingest "hot liquids", "crunchy vegetable matter",
"food from a bag") because it's just not interested. It's kind of impressive
the managed a decent screen adaptation at all. (And you can't blame
Sanctuary Moon for being over the top unrealistic, that was the whole point
of the series to Murderbot.)</p>

<p>Anyway, I've done nothing on toybox for days. I just fired up my laptop
to download 8000 back emails, most of which are spam and linux-kernel and
qemu-devel and such, but still. If anybody tried to email me the past
few days, I didn't notice.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#16-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 12, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#12-06-2025</link>
   <pubDate>Thu, 12 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Another random way the religious loons were just OBVIOUSLY wrong if
you think for fifteen seconds: ages recorded in the old testment used a
lunar calendar, and didn't bother to specify units because _everybody_
used "moons". You can look up each night and see the moon, so "this many
moons ago" was easy to agree on with a simple tally. A week is a
quarter moon, the lit part advances from sunset to sunrise each night,
and it's easy to tell when the moon is new, full, or when the line
down the middle is straight, so you have four weeks per month delineated
by new moon, waxing half moon (lit towards sunset), full moon, and waning
half moon (lit towards sunrise).</p>

<p>Even today we divide the year into moonths (like fourths and fifths),
although we adjusted them to line up with the solar calendar rather than the
actual moon and divide evenly (12 instead of 12.4). And once it was no longer
measuring a physical phenomenon it become political: "september",
"october", "november", and "december" are 9th, 10th, 11th, and 12th
months despite the names meaning 7 8 9 and 10 because Julius and Augustus
Caesar inserted months named after themsleves into the middle.</p>

<p>This is why easter keeps moving around: it's a lunar calculation,
predating the astronomical technology to do reliable solar calendar
measurements (365.24 days isn't an even number either, that's why we have
leap years).</p>

<p>All the old biblical ages are "this many moons ago" so if you
divide methusalah's 969 moons by 12.4 he was 78, Noah's 950 makes him 76.6,
Adam's 930 is an even 75 years, and Enoch's "one day he disappeared, because
God took him" at 365 moons means he was 29. When the bible says Noah's Father
Mahalalel lived to be 895 moons and died when Noah was 245 moons,
that means Mahalalel died at 72 when Noah was almost 19.</p>

<p>Despite the above seemingly obvious math, bible "scholars" who believed in
inerrancy tried to insert "and when THIS happened god said people wouldn't
live so long anymore" into the book. So in order for it to be inerrant you
have to change the text. Bravo.</p>

<p>So yeah, people lived into the 70s back in the Bronze Age, and probably
longer. With only slightly better medical technology Plato died at 80,
the roman senator Cato the Elder lived to be 85, and Pliny the Elder's
Natural History says Marcus Perperna lived to be 98 and "the Sicilian
Gorgias lived 108 years". The empire had better nutrition and buildings
with primitive heating (underfloor even) and air conditioning (using the
aqueducts to run swamp coolers), but mostly I expect it's sample size:
they had better literacy (so recorded what happened to a lot more people)
and were more recent (so more records survived). Plus of course the
indicated roman examples were rich people, who could afford the best
care and nutrition and slaves on their own land inside a secure building
surrounded by armed guards.</p>

<p>The Shakers are the go-to example of a sect celibacy did in
because they <a href=https://www.nytimes.com/2024/09/05/magazine/shakers-utopia.html>just about</a> survived to the modern day
by recruiting more people to join, but in general
religions surviving today are the ones that DIDN'T make too many of
their followers drink the kool-aid. And while priests and nuns were celibate,
if you had three kids at 13, 14, and 15 then by the time you were 30 your
youngest child was married so becoming a nun later in life didn't mean you
hadn't reproduced. It was the medieval version of going back to college
for a doctorate, living indoors where the books and lessons were.</p>

<p>Responding to "not enough kids" with "be more uptight about sex" could
easily be another such cultural demographic bottleneck (well, exacerbate
the one we're in), but since the world's population was 2 billion in 1923 and
is 8 billion now, cutting it in half and then in half AGAIN just means
going back to the population we had in the "roaring twenties". Not exactly
the end of humanity as a species. Hopefully it IS the end of capitalism,
and its parent religion the "protestant work ethic".</p>
The modern view of children as some sort of retirement project you have
right before your biological clock runs out, raising them alone without
any input from an "extended family" because you were an only child and
your parents died before you had your kid, isn't how most of history worked.
My grandmother was one ten children: I'm pretty sure they started younger
than 35. I met 4 of my great-grandparents.</p>

<p>Recovering population is trivial when capitalism gets out of the picture.
You don't even have to have lots of kids if you have them earlier. The
above hypothetical 15 year old parents (the age <a href=https://youtube.com/shorts/ihzrNyPWLz8>Dolly Parton's mother</a> had
her first child)
could have four 30 year old grandparents and eight 45 year
old great grandparents (and some number of 60 year old great great grandparents,
and maybe even a couple 75 year old great great great grandparents) available to
babysit. (Yes people lived that long: people's ages in the old testment used
a lunar calendar, methusalah's 969 moons meant he was 78.) If each
marriage had 3 surviving children, that 75 year old could live to see 3^6=729
great-great-great grandchildren. Lots of historical societies raised kids and
THEN went on to do other professional things. (Yeah there's a lot of mysogyny
in Charles Darwin having 10 kids, but there were also a lot of babysitters,
nannies, doula, grandparents... Cleopatra had 4 kids, Queen Victoria had 9,
they managed to accomplish quite a lot regardless and that's without
the aid of modern technology. Us not doing that is a choice capitalism
makes for us: I wanted kids in my 20's but didn't feel I could afford them
while still paying student loan debt and car loans and a mortgage.)</p>

<p>I note that long pork was mainly
(but <a href=https://www.smithsonianmag.com/history/the-gruesome-history-of-eating-corpses-as-medicine-82360284/>not</a>
<a href=https://explorersweb.com/why-rich-europeans-ate-up-all-the-egyptian-mummies/>entirely</a>) a problem among the poor (and
<a href=https://en.wikipedia.org/wiki/Donner_Party>otherwise</a>
<a href=https://www.npr.org/2024/01/10/1223078048/society-of-the-snow-ja-bayona-1972-plane-crash-cannibalism>desperate</a>) because
as always the rich just openly enslave people. These days it's debt slavery:
you spend your life working
for the person who owns your debt, they don't even need chains or guards.
You don't need sex for people to be trafficed, the Triangle Shirtwaist
fire was an entirely chaste capitalist mass murder of workers locked in
a building unable to leave. (And that's ignoring african slavery,
after too many indentured europeans <a href=notes-2013.html#22-02-2013>died of malaria</a> in the new world.)
Religion treats sex as special magic (marriage, circumcision, taboos...),
secular politicans doing it is CREEPY. Stop it.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#12-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 11, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#11-06-2025</link>
   <pubDate>Wed, 11 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>The Google workspace account I had all those years "has been deleted" today,
because I didn't log into it for 6 months after redirecting my DNS MX record
to dreamhost's mail servers. Thanks Google. You made that
decision, not me. The account I created for uploading youtube videos did the
same thing a couple years ago: I literally can't add more videos to that
youtube account, because Google deleted the login. *shrug* Their choice.
(At the time I thought I must have been inactive for a long time, but no,
it was just 6 months.) Presumably if I was out of the country for 6 months
using a different phone, all the youtube watch later bookmarks on my phone
would similarly be deleted when I got back.</p>

<p>I retested the Turtle board building with current toybox and last week's
release kernel and it worked fine for me, booted to a shell prompt and
everything, and I head scratched a bit on "how did I reproduce this issue
last time" until I remembered "oh right, I have a dozen patches
applied to my kernel". It's almost certainly a regression cropping up
in the "init has no stdin/stdout/stderr" codepath that's only triggered without
CONFIG_DEVTMPFS_MOUNT. I HAD that working, but have poked the shell a bit
since then and it isn't regression tested if I'm using my patches...</p>

<p>But I also have to check in the $KCONFIG_ALLCONFIG update I did to
the new scripts/kconfig.c because mkroot doesn't add CONFIG_SH or CONFIG_ROUTE
without it (which is a separate failure, regression when I switched to the new
infrastructure: I can manually work around it by creating a .config with
menuconfig and switching those two pending commands on, but that's quite the
sharp edge for newbies). Which I hadn't checked in yet because I hadn't added
"KCONFIG_CONFIG=.singleconfig_airlock" support for the mkroot airlock build
(and for scripts/single.sh to build "make sed" and such which "make test_sed"
uses). Except the current kconfig spits its new file to stdout and
the Makefile wrapping it is already using that variable to redirect the
output to a file. That's not necessarily right: I need to teach it to READ from
the previous .config to do incremental edits, and basic symmetry says it
should write back to it when it does that. But what's currently there
isn't breaking mkroot, so I can throw in a couple TODOs and punt to next
release.</p>

<p>Still gotta add crypt() to lib/hash.c: now that github's updated this
toolchain regression is visible to Elliott's guys. That might have to go
in this release, but that sort of pulls in all the /etc/passwd stuff
which promotes a half-dozen commands (I did it and checked it in a while
ago, it's just broken and can only be tested in a chroot or mkroot, and
toysh can't run the test suite under mkroot yet but is MUCH CLOSER NOW)...</p>

<p>Speaking of the current mkroot work I need to finish and check in,
the "alias" stuff (which Tim Bird's "$VAR doesn't run a shell function" bug
bumped up to the top of the todo list) gave me a bunch of failing test
cases for prefix assignment mixed with other stuff, and redoing that
plumbing caused several regressions because I moved initializing
the new function context to before resolving the command line's variables,
and now I'm staring at a design issue where what it's currently doing
is clearly not ideal, so should I patch it to get a release out or do
the larger fix?</p>

<p>The problem is I've been copying various sh_fcall fields into each new
function context, which bit me with "shift" not matching the corresponding
"args", and while I CAN just copy shift too, I'm not sure that's the right
answer? It makes attempts to update stuff a nightmare when there's multiple
versions of it and you can't tell how they're related.</p>

<p>Variables are already sparse within function context, because they
get assigned to a bunch, sometimes during variable resolution! $((x=7)) and
${abc:=def} come to mind. Those assignments have to go to the appropriate
local variable level, or the root context when there isn't a local.
And yes, there are WHITEOUTS in this logic:</p>

<blockquote><p>
$ y() { abc=def; echo y=$abc;}<br />
$ x() { local abc; abc=xyz; echo x1=$abc; unset abc; echo x2=$abc; y; echo x3=$abc;}<br />
$ abc=123; x; echo top=$abc<br />
x1=xyz<br />
x2=<br />
y=def<br />
x3=def<br />
top=123<br />
</p></blockquote>

<p>Last time I hit this for something OTHER than variables, I remember making
a function to traverse the fcall stack to find the last context where it was
set and use that version instead of the empty one at the top of stack. (Like
shell variables do, but for a different field.) I THOUGHT that was "lineno",
but the current code seems to be using lineno directly, and now I'm not sure
I checked it in rather than frogging it (the knitting term for unraveling
the yarn back to a mistake and redoing it) and using a different approach?</p>

<p>But $LINENO is kind of a bad example because there are two active "lineno"
values: TT.ff-&gt;lineno is the last line read from the input source,
while TT.ff-&gt;pl-&gt;lineno is the line number this pipeline segment
lived in. The first should only really be used to set the second:</p>

<blockquote><p>
$ bash &lt;&lt; 'EOF'<br />
&gt; for i in $LINENO two three<br />
&gt; do<br />
&gt; &nbsp; echo $LINENO $i<br />
&gt; done; echo and $LINENO<br />
&gt; EOF<br />
3 1<br />
3 two<br />
3 three<br />
and 4<br />
</p></blockquote>

<p>The three instances of $LINENO resolve to three different values, despite
the shell having to read the whole mess in at once before running any of
it, because it remembers what line the statement WAS on when it read it
in, and repeats that even when we loop back to it. Yes, this is another
test I need to add to tests/sh.test.</p>

<p>Anyway, rather than copying ANYTHING in sh_fcall() setup I should probably
have a function that loops back through TT.ff-&gt;prev to find where this was
last set and return that function context pointer

<p>Darn it, the sh_fcall generator function is still call_function(), I
know I renamed that. (Because "sh_function" is a function() definition
and sh_fcall is a call to a function or "source". It's the difference between
a function pointer and a stack pointer.) Looks like that cleanup was in a
branch I didn't check in.</p>

<p>Looking at sherror_msg() I was probably thinking about how I added
TT.ff-&gt;name being checked for via for loop, except it's checking source
&amp;&amp; name and I dunno when name is set when source wouldn't be?
(I mean functions can have names too. I need more lifetime rules comments.)
Other iterative traversals of the function call stack (basically just
searching for ff-&gt;next) include:</p>

<ul>
<li><b>findvar()</b> - searching through sparsely populated local variable
contexts</li>
<li><b>cache_ifs()</b> - doing the same for the "ifs" field (as
is "unsetvar" specifically for ifs).</li>
<li><b>subshell_callback()</b> - iterating through the function call stack to
fclose(source) at every level (so we don't leak filehandles into child
processes).</li>
<li><b>signify()</b> - this is the function that sets a new trap handler,
and it checks if the one we're replacing is currently running (I.E.
replacing a trap handler from within a trap handler). Coulda done
reference counting, and would have if I had generic plumbing
that could handle arbitrary structs, but with llist assuming the first
member is "next" and dlist assuming the first two are "next" and "prev"
(which means singly and doubly linked list traversal functions are
compatible), I'd have to have the reference count be the THIRD long-sized
field and... that's getting brittle.</li>
<li><b>sh_exec()</b> - also doing the close the same as subshell_callback().
It's annoying having it twice but it's "fork needs this and exec needs
this" thing, and it's a simple for loop calling one function that
would probably be worse to factor out into a function.</li>
<li><b>run_lines()</b> - set -x tracing is counting the parent function
levels so it can stick the appropraite number of + on the front.</li>
<li><b>break_main()</b> - searching for the loop we broke out of,
you could </b>while true; do exec 'if true; then break; fi'; done
where the blockstack you want is outside the current fcall context.
(Mostly because exec is weirdly transparent in a way neither "source" nor
function calls are. And yes I need tests for that.)</li>
<li><b>local_main()</b> - find current local variable context to add to
(you can eval inside a function)</li>
<li><b>return_main()</b> - like break_main</li>
</ul>

<p>And of course <b>eval_main</b> is weird: it needs to snapshot lineno but
ALSO let it return to the previous value:</p>

<blockquote><p>
$ bash -c $'eval $\'echo $LINENO\\necho $LINENO\'; echo $LINENO'<br />
1<br />
2<br />
1
</p></blockquote>

<p>Darn it, it's more complicated than that. $0 is inherited from the
parent context. It is NOT overwritten by "source" or "set" or function calls.
You can set it on the bash -c command line, but otherwise it's argv[0]
from main(). And then if you don't provide arguments to "source" it
inherits the parent's context, however:</p>

<blockquote><p>
$ bash -c 'source &lt;(echo set abc def); echo $1' aaa bbb ccc<br />
abc
</p></blockquote>

<p>Assignments to that context persist, so the sparse search approach
still seems right. Just... tricksy, and $0 probably shouldn't be part of
the argv[] array but instead its own entry in GLOBALS(). (You also can't
make $0 local because 0 is not a valid variable name.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#11-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 10, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#10-06-2025</link>
   <pubDate>Tue, 10 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>Spent most of today curled up in a ball due to stress. The Boomers will die.
Deep breaths.</p>

<p>Pelosi and Schumer dying will probably have more long term
positive impact than anything that happens on the other side, which has
been the exact same brand of evil since they were slaveowners arguing
over the 3/5 compromise (back then "our slaves give us more votes", now it's
"land can vote"). Pearl clutching about "they wouldn't ACTUALLY enslave
millions of people after committing genocide against the continent's
indigenous population" flies in the face of even sanitized grade school
history. (Note the indians peeking out in the schoolhouse rock about
how white men fought over the land mysteriously devoid of natives.)</p>

<p>No, the difference is their opposition stopped opposing. Obama was to the
right of Nixon, and the last guy to do anything to even mildly dent the
plutocrats (plantation owner, railroad robber baron, billionarie... all
the same) was Bill Clinton balancing the federal budget back in the 1990s.
(Because money is literally debt: that's how modern money is created, by
"borrowing" it from the government. So
reducing the national debt reduced the money supply the plutocrats have
available to hoard.) Dubyah turned that RIGHT back around as soon as he got in,
leaving Obama with such a mess he
spent his time firefighting and trying xeno's compromise with "the party of
no" repeatedly moving halfway to their position while they didn't move,
until he gave up or converged on their position. And then the first year AOC
was old enough to run (minimum age to be president is 35, maximum age none)
Pelosi and Schumer went all in on making sure that another FDR or another
Teddy Roosevelt could NEVER HAPPEN WHILE THEY DREW BREATH.</p>

<p>So we're waiting for them to stop.</p>

<p>Sigh, I think last time this asshole was in charge I settled on
blogging about technology on even days and politics on odd ones?
Not going back to that, I have no real influence on events and it's just
venting for stress. I don't want to talk Fade's ear off, I try to send
her mostly positive things.</p>

<p>There's actually
&lt;span id=politics&gt; and &lt;span id=programming&gt; tags around each
entry (and sometimes sections of entries) but I never made the rss
generator actually use that. (It was python 2 until python 2 went away,
then the guy who wrote toybox's awk sent me an awk translation which I'm
using and thankful for, but I don't speak awk. Might redo it in lua.
I keep thinking I should go back and
record mp3s of reading all these entries as a sort of terrible podcast but
how do you handle embedded links or bullet point lists? They weren't
really written with being read aloud in mind.)</p>

<p>Always more I COULD be doing, but the oligarchs keep burying my
spoons. Externalities aren't just smashed windows, there's opportunity
costs galore. But at the same time, "ignore it and focus
on work"... Iran was a secular nation until the Ayatollah took over.
Afghanistan had a thriving pop music scene before Russia invaded.
Religious fascism is not guananteed TO blow over, every televangalist
would happily run gas chambers for profit. I am not interested in
making the trains run on time to the concentration camps, sometimes
collapse is better.</p>

<p>It's a constant stream of little things.
Here's a <a href=https://youtu.be/EPzdnW_g8yk>catgirl vtuber kicked
off fansly for "bestiality"</a>, because once again the payment
processors (same ones who took out Tumblr and attacked OnlyFans, going
after everyone now they've got their fascist back in the whiter than white
house). Did you notice how the thumbnail of
<a href=https://youtu.be/aZv6i01De2Q>The Top Ten Treasures of the British
Museum, an In-Depth Museum Tour</a> blurs out the breasts on a multiple
millennia old bronze statue? Termites in the support beams.
<a href=https://www.goodreads.com/quotes/102579-how-did-you-go-bankrupt-two-ways-gradually-then-suddenly>Gradually,
then suddenly.</a></p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#10-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 9, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#09-06-2025</link>
   <pubDate>Mon, 09 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Got poked again about the turtle board. Ooops, kinda slipped my mind.</p>

<p>Alas I can't test it where I am because I didn't bring an SD card holder.
I walked to the U of M student center, which is more or less a shopping
mall, to use my laptop in the starbucks food court in the basement. It's a 7k
step round trip, not quite the walk to the UT tables, and they're only
open to non-students until 8pm (and not at all on sundays) but I'll take it.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#09-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 8, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#08-06-2025</link>
   <pubDate>Sun, 08 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>Stressed again by <a href=https://youtu.be/TlUXiw6Dr6U>France joining</a>
the "government ID is required to use the
internet" crowd. FRANCE. Not because of the flood of nazis and misinformation,
but because their STATED REASON is horny teenagers who can't just fish copies
of playboy/playgirl out of the trash anymore are finding it online. This has
been the status quo for 30 years, nobody is even suggesting they're coerced
into it rather than actively and voluntarily seeking it out, but now it's
suddenly a crisis and we must lock down the internet because the priests who
diddle choir boys <a href=https://youtu.be/XgAoLYfc7-E>en masse</a> (to the point they
make <a href=https://en.wikipedia.org/wiki/Spotlight_(film)>movies about it</a>)
and INSIST circumcision is not child abuse, headquartered in
vatican city where the <a href=https://youtu.be/YJtZSL0hxyE>age of consent is 12</a>, say so.</p>

<p>Stop clutching your pearls and maybe provide parental guidance and healthy
alternatives? No? Too radical? Instead we have "prohibition but you don't
even need equipment, literally everybody has a body, this should end well".</p>

<p>You can argue against the right wing's "every immigrant is a murderer
and rapist" to push back against ICE deporting people (show me a victim,
habeas corpus up evidence of an actual crime having been committed to a real
person by someone specific; that's what habeas corpus MEANS), but if you
argue back against THIS nonsense you're obviously in
favor of the worst possible excesses and ONE OF THEM. It's their go-to
argument in basically any circumstance, Musk even called
the expert who rescued a soccer team from a flooded cave in
thailand a "<a href=https://www.bbc.com/news/world-us-canada-50695593>pedo guy</a>"
out of the blue for refusing Musk's unsolicited dunning-kruger submarine.</p>

<p>Because the pearl-clutching boomercrats unconditinoally kowtow to this argument
with never a hint of challeng or pushback,
they've gone full on Minority Report preventing theoretical future crime,
and a lot of the "crimes" have no actual victim. (A drawing of violence doesn't
make anybody commit it but a drawing of sex will? Outlawing deepfakes of real people already makes
sense under libel laws: that person didn't say/do that. How is nudity or sex any different
than deepfaking them kicking a puppy, why are you passing SPECIAL CASE LAWS?)
But everybody's afraid to push back against
it because if priests are regularly diddling kids (not just catholics but
mormons and baptists and...)
then who WON'T? (Answer: people who aren't constantly demanding celibacy?
For the same reason people who aren't constantly fasting tend not to be
cannibals. Every accusation a confession still applies to these
genital-obsessed loons.)</p>

<p>Of course this moral panic du jour is no more about children than any other right wing "family
values" crusade. It's about tracking and control, de-anonymization and yet
another excuse to backdoor online cryptography, just like the "clipper chip"
the South Park movie mocked 20 years ago. The fascists never stop trying to
bug everyone's phones (behind the iron curtain the stasi were famous for
listening in to every east german phone call, now Google <a href=https://youtu.be/XgtH58FLEkY>installs an app</a>)
and the senile democrats have been basically republicans for <a href=https://www.latimes.com/archives/la-xpm-1994-01-30-op-16861-story.html>decades</a>.
According to boomercrats, an 11 year old can decide to get an abortion without
parental consent, or start puberty blockers, but they can't decide to HAVE a
baby (even via artificial insemination) WITH a parent's consent. PICK ONE YOU
ASSHOLES. (Women are being paid $60k to be a surrogate mother, students
could time implantation for the last 3 months to happen over summer
vacation and have college tuition ready without taking on any debt, but that idea is clearly beyond the pale.)
If you can't say no you can't say yes, and vice versa. The
attacks on kids are because <a href=https://www.psychologytoday.com/us/blog/the-power-rest/201303/give-us-kid-till-shes-7-and-well-have-her-life>the jesuits
said</a> "give me a child until the age of 7".
What they do to kids, they will do to adults. First they came for. Every time.</p>

<p>Back in 2012 Wikipedia <a href=https://www.bbc.com/news/technology-16590585>went dark</a> to protest earlier rounds of censorship laws, so they pivoted
to sex as an excuse to
<a href=https://decriminalizesex.work/advocacy/sesta-fosta/what-is-sesta-fosta/>pass them in 2017</a>,
then tried to pass KOSA under biden because that wasn't enough (it's never
enough), and now project 2025 literally has outlawing "porn" (I.E. any sort of
sex positivity or free expression) as an explicit goal, except nobody can say
what porn IS ("I'll know it when I see it" is a moving target that binds but
does not protect). Showing what somebody's body looks like should not be
shameful, Weird Al's Amish Paradise video had a joke centerfold with a woman showing ankle,
we mock countries with mandatory <a href=https://en.wikipedia.org/wiki/French_ban_on_face_covering>face coverings</a> and were recently
CELEBRATING that iranian lady who stripped down to her (<a href=https://www.bbc.com/news/articles/c9vngeezwvno>very modest</a>) underwear, but our
mandatory crotch coverings (and far more for women) are THE SAME THING.
The people who refused to wear masks during the pandemic are shaming people
for not covering enough skin. You can cut the hypocrisy with a knife.</p>

<p><a href=https://youtu.be/jVP0NjqX-LM>Britain</a> and
<a href=https://youtu.be/a5EAMKHcHZc>the USA</a>
fairly recently had semi-healthy attitudes towards nudity, but the puritan
crusade that passed fosta/sesta and took nudity off <a href=https://www.eff.org/tossedout/tumblr-ban-adult-content>tumblr</a> in 2018 was just the start, and
it's been a fairly <a href=https://www.vice.com/en/article/national-center-on-sexual-exploitation-ncose-twitter-lawsuit/>straight line</a> since then.
Ok, that wasn't the start, just the first big win Pelosi and Schumer allowed
them to keep.
Back in 2006 the asshole behind the SCO trial took the money he'd elder abused
out of Ray Noorda and founded an <a href=https://en.wikipedia.org/wiki/Ralph_Yarro_III#CP80>anti-porn group</a> with it, note all the
"protect children" and "segregate mature content" language.
The mormons (who outlawed caffeine but were fine with polygamy)
have been <a href=https://youtu.be/4nF_7KpnKuU>leading the
charge against porn</a> for decades,
and collecting an enormous <a href=https://youtu.be/UuHh-LDNJzs>war
chest</a> to do it (all tax-free of course: tax the churches already).
They're not the only such religious lobbying prudery trying to dig its way back
to outlawing gay marriage and birth control and eventually take the vote away
from women (they already DID take away access to abortion), but
<a href=http://www.catb.org/~esr/hackerlore/sco-vs-ibm.html>that one</a>
is <a href=http://www.catb.org/~esr/halloween/halloween9.html>personal</a>.</p>

<p>What is and isn't allowed? <a href=https://youtu.be/5nKBulAaENM>Comedians</a>
<a href=https://youtu.be/BtU-ITgF8Zg>working</a>
<a href=https://youtu.be/ULEt_rdneVA>blue</a>
<a href=https://youtu.be/gmATw7ToOJY>is</a>
<a href=https://youtu.be/nP6sn8s-RP8>nothing</a>
<a href=https://youtu.be/Dx_wzMsbyNg>new</a>,
<a href=https://youtu.be/zjJKQ7tEdLQ>even</a>
<a href=https://youtu.be/70d22_haOiU>on</a>
<a href=https://youtu.be/AjFff3Rd2Mc>famously</a>
<a href=https://youtu.be/gAYgKWkSvXs>prudish</a>
<a href=https://youtu.be/ZPojxETaByA>post-2017</a>
<a href=https://youtube.com/shorts/o5_EX4Games>youtube</a>,
<a href=https://youtu.be/NzavY4QlE7Y>known</a>
for policing women's
bodies over the <a href=https://youtu.be/jroJCQelq3w>explicit</a>
<a href=https://youtu.be/lgDzHPniUp8>objections</a>
of <a href=https://youtu.be/e4hA-mNmizU>those</a>
women. (And yes I only linked
to women there for a reason, there are plenty of men doing it from the
<a href=https://youtu.be/R7OxTxAvvLw>tasteful</a> to
<a href=https://en.wikipedia.org/wiki/Andrew_Dice_Clay>profoundly dickish</a>.)
White knighting assholes protecting third parties from being "exploited" over
the explicit objection of those third parties is not the side to be on.
Given half a chance rather a lot of people <a href=https://www.youtube.com/watch?v=UlDSj09aCi0>voluntarily</a>
go into <a href=https://www.lillithlodge.com/>sex work</a> where it's
legal, and yes they <a href=https://www.youtube.com/@jadeblairxox>vlog about it</a>.
Making it legal in australia
didn't suddenly end the country. It's been legal in Nevada for a
century. Dolly Parton <a href=https://en.wikipedia.org/wiki/The_Best_Little_Whorehouse_in_Texas_(film)>made a movie</a> playing a sex worker as the protagonist.
So did Julia Roberts (youtube keeps recommending me Pretty Woman,
the whole movie, "free with ads"). Are we still allowed to discuss
<a href=https://www.chillpolyamory.com/icouldnever>polyamory</a>?</p>

<p>Here is a LOVELY video essay called
<a href=https://youtu.be/oeZwjR4uaFk>Sheltered Children
and Overprotection in the Legend of Korra</a>.
"Protecting" people from reality MAKES THINGS WORSE. (A lesson
just about all sex educators have tried to convey since at least the 1960s.)
Here's a <a href=https://youtu.be/8xe6nLVXEC0>musical number</a>
about adults not knowing what's best for kids, who are people and deserve
a certain amount of autonomy, not a <a href=https://youtu.be/Pya-kt5M7uY>school-to-prison pipeline</a>
where armed guards run them through metal detectors on the way to their active
shooter drills. In Japan kids still <a href=https://youtu.be/IkVvXVDs5aI>walk
to school</a>, here in the USA we don't.
Speaking of countries with a healtheir attitude towards bodies, years
ago Last Week Tonight reviewed the TV show
<a href=https://youtu.be/A51mJjFyG_w>John Dillermand</a>.</p>

<p>Knitting Cult lady (who did "escaping cults" content before this administration,
and wrote a book about it), did a video titled "<a href=https://youtu.be/h7-XcUE5K64>Cults are always trying to control your underwear</a>".
I am annoyed by reich wing assholes attacking the channels people use to
communicate to OTHER PEOPLE, and by for-profit coprorations owned by
billionaires trying to shovel everyone behind walled gardens where
they can be censored.</p>

<p>The point of the lockdowns is to separate sex from normal life. Again,
imagine if the religious loons had stuck with the bible's dietary prohibitions
instead of the sexual weirdness. You should never eat anything but communion
wafers (and then in ABSOLUTE PRIVACY and NEVER DISCUSS IT) until you're
old enough to marry the one person whose cooking you'll eat for the rest
of your life (and who never even got to purchase ingredients before getting
a marriage license so has zero experience buttering toast)...</p>

<p>And yes they tried that in medieval times, having so many "fast days" people
became malnourished, and natural selection cleaned up those sects. As
it did for Shakers and Carolingians and followers of Theia and Jerome
and so on who insisted
on absolute abstinence: they had no kids, they died off, we moved on.
Responding to "not enough kids" with "be more uptight about sex" could
easily repeat that, but since the world's population was 2 billion in the 1920s
and is 8 billion now, going back to the population we had in the "roaring
twenties" is not the end of humanity. Hopefully it IS the end of capitalism.</p>

<p>If I want cooking videos but all I can find is close-up shots of open mouthed
chewing and pie-eating contests (basically modern pornhub)... what's
the point? I don't want brief glances of what they're putting into their mouths
in hopes a quick glimpse will introduce me to the concept of blueberry cobbler.
I want Julia Child spending half an hour explaining each step as she makes one.
(And no, I do not get to eat or even smell the TV picture. I am not going
to catch Salmonella if Julia did it wrong, nor will I gain weight from a
recording of food preparation.)
Even if I don't expect to make 99% of the dishes, and am not currently hungry,
I enjoy the craft of Claire Saffitz reverse engineering recipes or seeing how
far you can take banana bread (carmelized and fried!).
I've recently been doing a slightly
simplified version of the "baking on a budget" guy's apple muffins because
I had some clearance applesauce anyway and quickbreads are easy. (I haven't
got the patience for yeast, although mostly that's bad experiences with yeast
dying in storage before I try to use it and repeatedly having to abort the
recipe; three year old baking powder still works JUST FINE).</p>

<p>Yes they tried that sort of anti-food biblical cultural lockdown in
medieval times, from which "lent" and so on persist. Recently enough that
McDonalds <a href=https://corporate.mcdonalds.com/corpmcd/our-stories/article/filet_o_fish_journey.html>introduced the Filet-O-Fish</a> sandwich for lent.
Sects had so many "fast days" people became malnourished and starved, and
natural selection cleaned up the more extreme sects.</p>

<p>When food is what people couldn't get through normal channels, "trafficed"
people went missing to cannibalism. And yet the guy who played Captain Jack
Sparrow could go on to play
<a href=https://en.wikipedia.org/wiki/Sweeney_Todd:_The_Demon_Barber_of_Fleet_Street>Sweeney Todd</a>,
and Trump can have some sort of <a href=https://www.rollingstone.com/politics/politics-features/donald-trump-hannibal-lecter-timeline-1235070008/>bizarre love affair</a>
with Anthony Hopkins' character Hannibal Lecter (who got a
<a href=https://en.wikipedia.org/wiki/Hannibal_(TV_series)>TV show</a>
where he was somehow the protagonist?) and nobody says they're
increasing the incidence of cannibalism among the populace. (Although
strangely the british <a href=https://youtu.be/wc-QtmuPIGQ>embraced</a>
it a few centuries ago because they were racist imperialist assholes
who didn't see foreigners as people. Oh but eating mummies wasn't eating
PEOPLE, heavens no...)</p>

<p>Stupid categorical absolute prohibitions cause more problems than they
solve: you don't make a pressure cooker safer by sealing the relief valve.
The most famous "prohibition" is what made alcohol lucrative for
criminals (Al Capone, speakeaseys, etc), until legalization took that away.
The newly legalized cannabis
industry is similarly facing <a href=https://www.northbaybusinessjournal.com/article/industrynews/cannabis-marijuana-business-bankruptcy/>mass bankruptcies</a>
since competition immediately eliminated the expected profits by crashing
prices. Prohibiting sexual expression is not an improvement.</p>

<p>A hundred years ago, paternity tests didn't exist, sexually transmitted
diseases were uncurable and often undetectable, birth control barely existed
and abortion was more dangerous than giving birth. NONE of that is
true today. These days marriage is basically a tax shelter with optional
health insurance and estate planning. Even the big 1980's boogeyman AIDS
has become more like diabetes than a death sentence, and PREP is more
effective than condoms. We're actually shutting down aids camps because
there <a href=https://www.mprnews.org/episode/2024/10/31/in-a-sign-of-the-times-minnesota-camp-for-kids-with-hiv-closing>aren't enough infected people</a>
to be in them. That is a SUCCESS, going directly against
<a href=https://en.wikipedia.org/wiki/Ronald_Reagan_and_AIDS>Reagan's
paralyzed</a> "put a sock on a banana, wink wink".</p>

<p>"But what about disease..." the pearl clutching prudes WANT the diseases
to enforce their prohibitions. We eliminated Smallpox back before the
<a href=notes-2020.html#23-07-2020>Boomers screwed up the WHO</a>, and came close with Guinea Worms, Polio, Tuberculosis... (Still could if we guillotined
the billionaires and got back to work.)
Imagine if all sexually transmitted diseases were taken as seriously as
foodborne illnesses, to the point you were almost always safe and could
easily get treatment for the rare exceptions, with no more shame than a case
of food poisoning. Public lice were in massive decline until
<a href=https://www.nursinginpractice.com/clinical/pubic-lice-will-survive-because-fewer-people-wax-experts-warn/>shame</a>
stopped people from shaving. We have an <a href=https://www.npr.org/sections/shots-health-news/2025/03/12/nx-s1-5323229/hpv-vaccine-cancer-rfk>HPV vaccine</a>
the reich wing is trying hard to prevent people from taking (especially if
underage). There's even a preventative <a href=https://www.gilead.com/news/news-details/2025/yeztugo-lenacapavir-is-now-the-first-and-only-fda-approved-hiv-prevention-option-offering-6-months-of-protection>aids vaccine</a>
now, which DOGE of course <a href=https://www.theguardian.com/us-news/2025/may/24/musk-doge-hiv-aids>cut funding for</a>.</p>

<p>Yes the future remains
unevenly distributed, but these are not problems that require biblical
prohibition on mixing milk and meat because scrubbing wooden plates off
with sand in a desert caused bad bacteriological reactions and nobody
understood WHY or could easily detect them. Kinda funny
that no angel ever said "boil your drinking water", isn't it? I mean
WHILE THEY'RE HANDING OUT HEALTH ADVICE specifically about "clean" and
"unclean". Four words that probably would have
done more good than the rest of the book combined...</p>

<p>But one of the core planks of fascism is promising a
"return to an imaginary golden age", and another core plank is scapegoating.
Both are on full display here and we're all SCARED TO POINT IT OUT because
there's an accusation that's so bad it does not require evidence, let alone
proof, and can't be diluted (15 is as bad as 5, drawings of imaginary people
count). And when the right wing loons pull it out to point at each OTHER,
the left cheers them on as if THIS is clearly the worst thing they've ever done.
(Mister "grab 'em by the pussy", who cheated on his wife and paid six
figures of campaign funds to cover it up, might have done it with someone who
only had a learner's permit instead of a full driver's license? That
changes EVERYTHING. He spent his first term putting kids in cages, is currently
ripping them away from cancer treatment to deport them, but apparently
that was all ok as long as he didn't have sex with one. Russia is kidnapping
children en masse to erase their identity and raise them under another
langauge, Israel is starving them to death and blowing limbs off of them
in gaza, but as long as nobody's having SEX with anybody...)</p>

<p>The pendulum will swing back eventually, it always does.
The ice age mammoth hunters left behind a lot of
<a href=https://youtu.be/YTn5KdsxZ0E>venus of willendorf</a>
statues 30,000 years ago. (Probably earlier, it's just hard to find
anything preserved from that far back.) The Comstock Act
was abysmal, until the Boomers had "sex drugs and rock and roll" (explicitly
"free love") when they THEMSELVES were teenagers. Sex is a symptom not cause
here, it is being used for control, and taking control away from kids lets them
take the same control away from adults. People on THIS side of the line aren't
people, now move the line. When they do it to black people, women,
or gay people they get push back, but kids these days go through metal
detectors to their active shooter drills and that's not a crisis to
octagenarians like Pelosi and Schumer because they're don't even remember
was it was like having kids, let alone being one. Censorship
never fixes anything, the <a href=https://youtu.be/_fKnT_pihb4>problems
remain</a>, they just get worse because they're not being discussed or
addressed.</p>

<p>I was a latchkey kid,
and roamed around entirely unsupervised for hours each day, not just on kwaj
or walking to/from school, but mile-long walks around our suburban
subdivision and into the acres of woods between developments. My habit of
long walks today comes from walking and biking around on my own since I was 5.
Yes, when I was 5 I got mugged while I was out trick or treating... by one
of the other kids my age, who hit me over the head with their plastic flashlight
and ran away with my bag of candy. I'm not sure an adult being nearby would
have prevented that. These days trick-or-treating doesn't happen anymore, because
taking candy from strangers is "too dangerous". Children are too precious to
be allowed to exist, and thus nobody is having any.</p>

<p>The best way to ensure nothing bad ever happens to a child is for there to
be no more children. It DEFINITELY ensures they're not having sex, with 100%
confidence. The only way to reduce the chance all the way to zero. Hence
Greta Thunberg's "extinction rebellion". Notice how she started protesting
at age 15, and is now world reknowned at 22? If she'd been prevented from
starting her life's work until 18 far fewer people would care. David Hogg is
a vice chair of the Democratic Party at 25 because he started marching
in high school. He shouldn't have had to go through a school shooting
to be able to get into politics early, but would not have been ALLOWED
otherwise.</p>

<p>Scotland lets you vote at 16, to register to vote at 14, and the age of
criminal liability is 12 (so no juvenile detention below that). I'd be happy
making the voting age same as the criminal liability age, and making GOING TO
VOTE (in even local elections) a mandatory school trip with busses taking
the kids there. Start the habits early and counteract the
<a href=https://www.advisorperspectives.com/articles/2024/09/09/60-million-baby-boomer-votes-sway-election>90% boomer</a> turnout
<a href=https://www.aarp.org/politics-society/government-elections/info-2024/election-analysis-older-voters.html>for fascists</a>.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#08-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 7, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#07-06-2025</link>
   <pubDate>Sat, 07 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Found one wrong reference count to fix, so now ASAN is still failing on
the same test but saying "segmentation fault" without giving any additional
debug info. Yes, this is the old working version under kvm.</p>

<p>Dear vim: don't gratuitously re-indent lines I didn't touch just because I
deleted a comment next to them.</p>

<p>Sigh, bog standard null pointer dereference, attempting to resolve $LINENO
from TT.ff-&gt;pl-&gt;lineno in a context where TT.ff-&gt;pl was NULL.
(I.E. another unsurprising side effect of moving the function context
initialization command line argument expansion. Urgh, why did I do that...
<a href=#22-05-2025>Because</a> I was trying to save a pass in variable
assignment, and needed somewhere to save the assignments into before
determining whether this was prefix assignment or a persistent assignment.
And THAT doesn't work because prefix and persistent assignments go into
to different lists (one creates new local variables in the current
function context, the other overwrites existing variables or defaults
to the global context).</span>

<p>Probably instead of trying to debug this I should just unroll that
part and let it be two passes again.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#07-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 6, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#06-06-2025</link>
   <pubDate>Fri, 06 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Elliott poked me about github's test builds hitting the glibc ASAN regression,
because github updated its ubuntu build environment to one with the bug.
(It's the issue where enabling ASAN turns calls to crypt() into a null pointer
dereference. No idea why. Works fine without ASAN enaled, and the code is
literally just calling a function out of libc.)</p>

<p>Speaking of ASAN, I installed devuan cataclysm in a KVM so I could run the
old ASAN that gave me stack dumps, but even that is just craptacular.
My redo of the run_command() logic screwed up the reference counting somewhere
so it does a use-after-free, and it gives me the line that happens on...
which is in dlist_add_nomalloc() out of lib/llist.c. Generic function doing
linked list manipulation: I want to know who _called_ it, but it doesn't
give me THAT trace. Instead it gives me a stack dump of where it got
freed from by the earlier reference counting code (which I already knew)
and a stack dump of where it got allocated from (which I already knew). Who
is the persistent user that thinks they still have it AFTER the reference
count's gone to zero? Back to sticking in a bunch of printf()s to track down
what's going on because ASAN is a lot less useful than you'd expect.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#06-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[June 3, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#03-06-2025</link>
   <pubDate>Tue, 03 Jun 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I redid the prefix assignment logic and I'm so glad I have so many regression
tests, because debugging it to handle all of them is seriously threading
some needles. I may have to add more, actually.</p>

<p>Moving the function context creation before local variable assignment
screwed up "shift", which may always have been a bug? When you replace
argv[] for a new function or builtin call shift needs to go back to zero,
but a transparent function context that copies its parent arguments
needs to copy its shift value as well, otherwise <b>sh -c 'for i in "" 2 1 1 1;
do echo $? $1; shift $1; done' one two three four five</b> just prints "two"
over and over (the "one" becomes $0 which oddly enough doesn't shift).</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#03-06-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 29, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#29-05-2025</link>
   <pubDate>Thu, 29 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>Politics remains terrible, curling up in a ball way too much.
(Has Trump ordered the tide not to come in yet?)</p>

<p>I dunno if we get an FDR style "I welcome
their hatred" or a fall of Rome scenario followed by "a thousand years of
camping out" before we get plumbing again. Sexual repression seems linked
to the whole "don't even THINK about having kids before you turn 30" turn
society's taken, which seems kinda maybe linked to declining birth rates,
which seems to have an obvious outcome. Which isn't fun to live through,
but doesn't pose nearly the same long-term threat to the species as global
warming does.</p>

<p>I can't fix any of this. The current increasingly rigid structures
will collapse when the society under them does. Between the birth rate,
income inequality, global warming storms leveling cities, crop monocultures
with patented genes, John Deere trashing right to repair, collapsing
supply chains, widespread loss of institutional knowledge, copyrighted laws
you have to pay to see, maybe a carrington event leading to kessler syndrome,
and so on... shouldn't take too long.</p>

<p>Or maybe society will recover to be productive again. I was told long
ago that when you turn 50 the world suddenly swings into inevitable decline.
We pulled out of the great depression, won WWII, McCarthyism failed, the
Comstock Act was mostly invalidated (but not REPEALED, sigh).
AOC is _explicitly_ mirroring FDR with her name,
policies, and even the "Green New Deal". She Welcomes Their
Hatred. And Pelosi spent every last breath dragging her down, but Pelosi
is 85, she CAN'T live that much longer. (Even Strom Thurmond only lived to 100,
condescending self-righteous evil has limits as a preservative.)</p>

<p>The population crash is mainly alarming because it imposes gerontocracy
while it ticks down (the old outnumbering the young). It's not a threat to
the species or anything: 100 years ago the planet had a total population
of 2 billion and there's 8 billion people right now, so the
loss of 3/4 of the population puts us back to the "roaring twenties".
That isn't the end of humanity, no more than
the fall of Rome or the bronze age sea peoples were. We all seem to be HOPING
for a gentle collapse, like northern europe experienced when the romans just
pulled out and left them to it. I'm aware that's a HUGE oversimplification
on many levels, but in terms of my own stress, from a "how do we cope with
this" perspective? Yes there were barbarian raiders but they could castle up
and stab back, there was something you could DO about problems at the local
level, not mad max style roving survivors the way large chunks of the native
american population was reduced to after 200 years of European disease, invasive
species, and assault (starting in 1492). The Boomers will die: if each
generation after will be smaller, less well-trained, and incapable of
maintaining increasingly brittle infrastructure, that does tend to snowball,
but if we get past the lead poisoning and the belief that billionaires
should exist, it's all fixable. The transistor was invented in 1947,
humanity could lose all our tech and reinvent it from scraps and first
principles in a couple centuries if we were just secular instead of religious.
(Capitalism is, sadly, a religion.)</p>

<p>Humanity's been pretty resilient. The reason modern history seems to start suddenly ~10k years ago is the
seas rose significantly at the end of the last ice age, and most people live
near the coast even today (with cars, trains, and airplanes half the population
STILL lives within 200 miles of an ocean). The archaeology before that is
underwater, we've only recently started to notice it. Modern humans made it to
Australia ~50k years ago, why would you think there weren't cities before now?
The tropics are terrible at preserving stuff, the north was scoured by glaciers,
and we weren't seriously looking for "atlantis" or taking multiple cultures'
"great flood" myths seriously. Despite KNOWING that multiple important
land bridges came and went repeatedly since humans reached Australia,
ethnocentric european assholes somehow assumed nobody interesting was
living in the flooded bits. (Everywhere has archaeology if you ask, but
colonizers tend to steamroll the local population. Hawaii has legends about
being colonized from Tahiti somewhere around 1100 AD, with an earlier
wave of colonization from the Marquesas Islands somewhere between 300 and 800
AD (of course the two groups fought), and before THEY got there the Menehune
were already on the island (one theory was they were Homo Floriesciencis but
I am WAY out of the loop on the last few decades of Hawaiian archaeology.)</p>

<p>So people saying global warming can't melt antarctica and flood a bunch
of cities with a _reverse_ ice age today? Yeah, about that. Humanity's survived
each such event, but civilizations and cultures did not. We think our
current tech level is forever, but you can't blacksmith up a USB adapter.
Cell phones are a miracle, with an average lifespan of 3 years and
dependence on massive distributed infrastructure to do anything interesting.</p>

<p>The planet's actually had global warming before,
the <a href=https://en.wikipedia.org/wiki/Paleocene%E2%80%93Eocene_Thermal_Maximum>last time</a> was called the Paleocene/Eocene Thermal Maximum around 56
million years ago, a 5-8 degree celsius global average temperature rise due
increased carbon dioxide levels in the atmopsphere and ocean, with basically
no ice caps. The big problem is it lasted 200,000 years, which is longer than
modern humans have existed as a species. (This was
long enough ago that north and south america didn't connect yet, but south
america had a land bridge to antarctica, so ocean currents were WAY
different than they are now.) We look to be
pretty much headed for that again, and if we can't fix it NOW we seem
unlikely to have more leverage once our supply chains break down,
our population craters, our monoculture food sources go extinct, and
the good places to live stop being friendly.</p>

<p>A whole lot of the current bad is Tetraethyl Lead working its way through.
But Gen X isn't immune, people my age got 15-20 years of exposure. I grew
up in extremely rural florida (upwind of Daytona) downwind of wilderness straight through
to the gulf of mexico, and then spent 5 more years on Kwaj surrounded by a
thousand miles of open ocean, so I got less of a dose than most. But when I
was 10 we moved to New Jersey and I could FEEL myself getting dumber. (And
angrier. And depressed.) The Boomers mostly managed to compensate until
age 30 (which they <a href=https://medium.com/@MKaines/baby-boomers-critics-of-millennials-once-said-ignore-anyone-over-30-9b2f694b8dec>famously saw coming</a>
and yes that IS a quote from a 1968 Playboy interview)
then gradually decompensated until they lost it completely ~15 years ago when
the Tea Party started screaming "clean cup move down". The nigerian spam emails became
ubiquitous because grandpa kept falling for them. Gen X is going to lose it too
(the question is when) but we're not as demographically dominant, and might
hold out a few years longer due to our exposure tailing off in our 20s
instead of our 40s?</p>

<p>Richard Nixon created the EPA in 1970, catalytic
converters were mandated on all new vehicles sold since 1975, atmospheric
lead levels started rapidly declining in 1980 and dropped 90% over the next
~7 years, and leaded gas was finally withdrawn from sale in 1995. So
anybody under the age of 30 NOW didn't even get significant pediatric exposure
affecting early neurological development: put them in charge please.</p>

<p>It's all very complicated and the people who were trying to understand
it got fired by the oligarchs playing musical chairs. Capitalism is the
biggest problem underlying all the other ones, and the collapse of the
US dollar as the global reserve currency can't come fast enough. Fascism
inevitably eats itself (lying about problems instead of fixing them is not a
long term solution), but we don't have time to work through a major collapse
if we're already getting hurricanes in appalachia. Not if we still
want to have airplanes and air conditioning 50 years from now, let
alone internet and smartphones.</p>

<p>I'm finding it really hard to take poking at Linux seriously in that context.
(Even ignoring the rustification of linux, google enshittifying
android, the LLMpocalypse combining the dotcom crash and mortgage crisis
into one big ball of fraudulent debt, china and the USA competing to
see who can crash electronics manufacturing supply chains faster...)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#29-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 28, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#28-05-2025</link>
   <pubDate>Wed, 28 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Using my laptop in the common work area near the front office of the apartment complex,
listening to the secretary on the phone telling
somebody a parking spot has become available for $150/month. So glad I
can get away with not having a car. Back in 2018 I worked out my car was costing
me over $1000/month (lots of inflation since then)
in Texas (oil country where they prioritize cars), so I didn't replace it when
it broke until I actually needed a car again (still haven't).
And that's when I had a house with
two large driveways (mandated by the city due to "parking minimums",
the horseshoe driveway out front was put in when they did the kitchen expansion
because the extra square footage required another parking space, and
that large concrete dam was part of the reason the house flooded when it
had had been there since 1950 without ever flooding before).</p>

<p>I tried to work around the riscv ABI version skew between gcc and binutils
by changing the mcm-buildall invocation to riscv32::--with-arch=rv32imafd
because looking at the patch in the kernel issue that seems to be the
-march you feed on the command line to specify the old one. But the build still
broke exactly the same way, and rather than dig further in that direction
I'm just going to try to update binutils.</p>

<p>Alas the
<a href=https://github.com/richfelker/musl-cross-make/blob/6f3701d08137/patches/binutils-2.33.1/0001-j2.diff>0001-j2.patch</a>
from patches/binutils-2.33.1 doesn't apply, which I bisected to a
<a href=https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=aebcfb76fc16>binutils commit</a>
which says "Enhance the disassembler so that it will reliably determine whether
a reloc applies to the middle of the next insn." but also did a large unrelated
cleanup converting bfd/cpu-sh.c to use macros to initialize the structure array
that patch is patching. Converting it seems reasonably straightforward.</p>

<p>Rich's
<a href=https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=ae440402f54c>0002</a>,
<a href=https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=a501eb446f51>0003</a>
and <a href=https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=7f02673206ea>0004</a>
commits went upstream. That leaves 0005 which is removing a presumably broken
optimization without explaining why it's broken, but I assume it's
still needed?</p>

<p>I also got pointed at Zach Van Rijn's <a href=https://git.zv.io/toolchains/musl-cross-make/-/tree/musl.cc/patches/gcc-14.2.0?ref_type=heads>mcm fork</a>
which has some weird bespoke git viewer that does not seem able to
show files@version so if that's changed since I wrote this my apologies,
maybe try your luck with archive.org? (Tip of tree commit was
6f3701d08137 at the time.) The gnu/dammit git tree has a releases/15.1.0
but no 15.0.0 so I have no clue what counts as "current", but anyway...
Worry about all that later, let's just get gcc 12 working for this release.
And then maybe try to migrate to a Linux From Scratch style build like my
old aboriginal linux scripts used to do, once I'm more familiar with the
patch stack I need to fish out of mcm to avoid regressions (like lack of
j2 support).</p>

<p>I have a note to look at <a href=https://skarnet.org/toolchains/>another
toolchain</a> but the obvious way to address version skew is to upgrade the
binutils to match the gcc. Unfortunately musl-cross-make is a brittle hairball
that makes moving to new versions unreasonably painful. I really need to move to
a Linux From Scratch style toolchain build. I miss the days I could get a solid
week of focus to dedicate to something like that without fascism du jour
draining my energy...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#28-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 27, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#27-05-2025</link>
   <pubDate>Tue, 27 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Dear gcc: when I do:</p>

<blockquote><pre>
static char *abc;
void blah(void) {
  if (0) function(abc, sizeof(abc), abc = xmalloc(0), 0);
}
</pre></blockquote>

<p>Don't go "warning: operation on 'help_data' may be undefined
[-Wsequence-point]" when the CONTROLLING sequence point is the if (0)
so THE FUNCTION NEVER GETS CALLED.</p>

<p>Yes I'm aware that in the 1980s Turbo
C for DOS (when told to use the "pascal" calling syntax and thus
produce .o files that could be linked into pascal programs by putting all
the arguments on the stack in reverse order) would ignore the plainly defined
meaning of "," as a sequence point and instead parse the arguments backwards
including all side effects. This WAS A BUG and the standards body
SHOULD NOT HAVE CODIFIED IT, but fine. It's borked, the same way a = a+(a++);
ignores the CLEARLY DEFINED MEANING OF PARENTHESES because, again, the
C standards body combined "cowardice" with "microsoft". (And got hijacked
by C++ developers who were INCENSED that C wasn't a minefield of inexplicable
sharp edges like C++, and set about "fixing" that.)</p>

<p>But the if (0) is RIGHT THERE. The meaning is UNAMBIGUOUS. The code
is yanked via DEAD CODE ELIMINATION, the function is NEVER CALLED, none
of the side effects EVER HAPPEN.</p>

<p>I'm trying to provide minimal stubs
so the build doesn't break when the function is compiled out, that's
why all three arguments are the same dummy variable. Blah, does sizeof(0)
work without a warning? Ok, I can make the first two a constant 0 then.</p>

<p>Somebody ("userdocs") on the #musl channel on libera.chat pointed me
at <a href=https://lkml.org/lkml/2023/8/9/890>the reason</a> for the
riscv failure, and yes it's gcc updating the default API to a version
not available in the older binutils. (Who needs backwards compatibility?
After all, the acronym stands for "Gnu's Not Usable".) So the question
is whether newer bintuils just doesn't need patches (given that the
j2 patches never went upstream it'd still need those), or whether I
should -march away the ABI update until binutils catches up? (And/or
I migrate off of mcm.)</p>

<p>From the patch at that URL, it looks like changing mcm-buildall.sh to use
riscv32::--with-arch=rv32imafd and riscv64::--with-arch=rv64imafd
might be the easy fix (the "old ABI"), let's see...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#27-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 26, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#26-05-2025</link>
   <pubDate>Mon, 26 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>The reason none of the mkroot builds boot is the initramfs doesn't
contain "sh", because the config doesn't contain CONFIG_SH=y, because
the new kconfig infrastructure I wrote doesn't know how to read
KCONFIG_ALLCONFIG yet and a while back I switched mkroot to feed the
$PENDING list in via that instead of manually editing the .config file.
(Since it seemed less ugly at the design level.)</p>

<p>I forgot. Right, missing infrastructure in the new plumbing, gotta go
implement that...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#26-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 25, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#25-05-2025</link>
   <pubDate>Sun, 25 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Building test binaries for a release to see what broke: new qemu (git
snapshot du jour, probably back off to 10.0.0 for the release unless they
get something newer out soon) is simple enough (or at least it built).</p>

<p>I've been waiting for Rich to do the next musl release and update
musl-cross-make to use it, but the next kernel release is coming out and
I guess I'm going with the old one again. I can at least try the newest
gcc version musl-cross-make has a patches/ directory for: 12.4.0.
Which failed to build both the 32 and 64 bit riscv toolchains
because "Fatal error: -march=rv32imafdc_zicsr_zifencei: unsupported ISA
subset `z'" which... I think it failed building the musl library (a -j32
build on the fast machine I'm borrowing interleaves the output rather a lot)
but that might just be the first thing it tries to build _with_ the new
compiler+binutils? A grep of the musl source directory for the current
git checkout isn't finding an "rv32" (nor was it in 1.2.5, or 1.2.4)
so... Maybe it needs an updated binutils? But 2.33.1 is the newest entry
in the "patches" directory and commit 82d6c2a6832a added a gcc 12.4
directory to Rich's tree so presumably this worked for SOMEBODY or it wouldn't
have gotten merged? I'm confused. My mcm-buildall.sh script is invoking
it with the exact same command line as last time. Do I need to walk
forward through gcc versions from 9.4 or something?</p>

<p>Sigh, I want to move forward to current package versions so I can switch
to git builds and git bisect exactly this sort of thing. And eventually move
to a Linux From Scratch style build that doesn't use musl-cross-make anymore,
because I spend half my time fighting Rich's scripts...</p>

<p>Anyway, skipping that arch for now. Current git snapshot, apply my patch
stack, build all the targets... Looks like they built. Run
mkroot/testroot.sh and... All of them failed. Ok, try one at random (mips)
and I get boot messages, but the kernel fails to launch init. Sigh...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#25-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 24, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#24-05-2025</link>
   <pubDate>Sat, 24 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>It's so exhausting when bash fails to be unixy. For example, you'd think
alias would print "abc=def" lines like env does, but no. It prints
"alias abc='def'" lines, with the single quotes around things that don't need
to be quoted.
<a href=https://pubs.opengroup.org/onlinepubs/9799919799/utilities/alias.html>Posix
says</a> "If no operands are given, all alias definitions shall be written to
standard output." and adding extra crap seems like breakage. The Defective
Annoying SHell doesn't add "alias" at the front, nor does mksh or busybox ash.</p>

<p>The universal quoting would actually be $'def' so you could
stick newlines and escaped backquotes in there, but no. Single quotes can't
contain single quotes, nor do they have an escape syntax, so what happens
if:</p>

<blockquote><p>
$ alias abc=abc\'<br />
$ alias<br />
alias abc='abc'\'''<br />
$ alias abc=$'abc\nalias abc=\'def'<br />
$ alias<br />
alias abc='abc<br />
alias abc='\''def'
</blockquote>

<p>Oh yeah, that's not confusing at ALL.</p>

<p>There IS an "alias -p" option that says "print all defined alisases in
a reusable format", but it's a NOP. The behavior is exactly the same with
and without -p.</p>

<p>Which means if I'm writing tests for alias listing, and I want TEST_HOST
to pass, I'm just WAITING for version skew where they change the quote style
of the output breaking my tests.</p>

<p>A horrible corner case I have NOT implemented yet is that when alias ends
with a space the next input word is _also_ checked as an alias. Which means
I have to quote forward in the alias body to see if the last character
is an unescaped blank, and I dowanna. (Posix says I can just check the
alias string and not care that it ends in "\ " because even when it's escaped
you can CHOOSE to still process the next word as an alias, and it's all
implementation details bubbling to the surface. I'm going to wait for
somebody to complain before trying to do that crap at ALL, because this is
just too stupid.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#24-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 23, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#23-05-2025</link>
   <pubDate>Fri, 23 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Still salty about Chet saying "sounds like an implementation detail":</p>

<blockquote><pre>
$ [[ 1&lt;2 ]] &amp;&amp; echo yes
bash: unexpected token 284 in conditional command
</pre></blockquote>

<p>Yes, your stuff is FULL of implementation details leaking to the surface.
Having unquestioned design decisions lying around since 1974 does not improve
matters. (No, I have no idea what "token 284" is.)</p>

<p>The question I was trying to ask is the difference between [ test ]
and [[ test ]] operators. The double square bracket ones disable some shell
parsing within them, so you can use unescaped ( ) ! &amp;&amp; || instead
of having to go [ \( a == b \ -o  c == d \) -a e == f ] but it does NOT
let you use &lt; and &gt; as unquoted comparison operators instead of
redirectors. Which is why -gt and so on exist, but still. As long as
you're manually disabling parsing ANYWAY...</p>

<p>This comes up because I'm redoing the run_command() parsing logic that's
special casing (( )) and [[ ]] and need to add SO MANY more test cases,
and help "[[" isn't hugely informative about why it exists. (To the point
when I first used busybox it was installing a [[ symlink alongside the [
symlink, both of which were synonyms for test.).</p>

<p>By the way:</p>

<blockquote><pre>
$ ls -l /usr/bin/\[
-rwxr-xr-x 1 root root 68496 Sep 20  2022 '/usr/bin/['
$ dpkg-query -S /usr/bin/\[
coreutils: /usr/bin/[
$ ls usr/bin/\[*
ls: cannot access 'usr/bin/[*': No such file or directory
$ ls /usr/bin/w* | head -n 1
/usr/bin/w
</pre></blockquote>

<p>Bravo, bash.</p>

<p>(Sigh, I should send these to Chet. Dowanna reopen that can of worms
though. Anyway, <b>ls /usr/bin | grep '\['</b> confirmed that debian does
NOT have a [[ symlink installed by default, which I didn't think so because
it can't work right but I like to check these things.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#23-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 22, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#22-05-2025</link>
   <pubDate>Thu, 22 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>So my run_command() plumbing
is ONLY counting leading NAME=VAR prefix assignments, it doesn't let you
interleave redirects or ! operators. So though the alias substitution
logic is skipping those, you can't use them anywhere else yet.</p>

<p>Handling ! and redirects mixed in with prefix assignments is annoying
because of a couple different subtleties. First, my code is deciding whether
or not to strdup() the variable memory of the assignments based on whether or
not they're persistent. An "a=b d=f ghi" that's just local variables for
a single command or function's execution doesn't need its own lifetime
rules, it lasts as long as the command's arguments. (Which are already
transplanted into the sh_fcall so they can outlive the caller, that
was part of the change from recursion to stack based function processing
a few months back.) That's why the function assignments are done in two
passes: the first measured "envlen" to see how many assignments there were,
and the second interated through them knowing that each string until envlen
was an assignment.</p>

<p>But if other crap's mixed in there, I have to parse them again in the
second pass to confirm they're assignments, which is the kind of
"doing the same work twice" thing I've been trying to avoid. Now that
there's always a function context created for each run_command(), I could
move that earlier to give the assignments somewhere to go and thus the FIRST
pass could create them... except I don't know until the end whether or not
they need to be copied.</p>

<p>The second problem is that expand_redir() was handling ! and redirects,
but didn't know about variable assignments. Either I need to remove the
assignments, or teach it to skip them. But ONLY before the first command
word, and expand_redir() doesn't distinguish between commands and arguments.
Which is actually a problem because ! was being handled too late, and "echo !"
was returning 1. Bug, fixing it in this pass, but in my defense:</p>

<blockquote><pre>
$ echo !that
bash: !that: event not found
$ echo this!that
bash: !that: event not found
$ echo !
!
$ echo $?
0
</pre></blockquote>

<p>I didn't know ! by itself was SPECIAL CASED to not be magic in bash.
BE CONSISTENT! Except...</p>

<blockquote><pre>
$ echo ;!;echo $?
bash: !: event not found
$ echo

$ !
$ echo $?
1
$ echo ;! ;echo $?

1
</pre></blockquote>

<p>It needs a trailing space? Really?</p>

<p>Anyway, it turns out the operator version of ! has to come before EVERYTHING
else, and is treated as a literal after redirects or variable assignments:</p>

<blockquote><pre>
$ ! a=b
$ echo $a $?
b 0
$ a=b !
bash: !: command not found
</pre></blockquote>

<p>I keep thinking this stuff is more systematic and less ad-hoc than it
is.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#22-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 21, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#21-05-2025</link>
   <pubDate>Wed, 21 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<p>One downside of going back and editing old blog entries to post, especially when
there's an entire email to manually format as html (the &gt; quote character
needs to be converted to &amp;gt; and the line breaks for it are manual and
my "hit space twice to indent" code examples turn into blockquotes...) is
that you can spend the day doing that and wind up not having any new blog entry
to show for it.</p>

<p>"Performed janitorial tasks".</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#21-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 20, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#20-05-2025</link>
   <pubDate>Tue, 20 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>Not sleeping well. Stressed.</p>

<p>The Golden Showers Dome sounds to me like a new spy sattelite plan where the
satellites all point down at the USA to track dissidents when the torches and
pitchforks come out for the billionaires (because you can leave your phone at
home, so they need a whole new skynet to spy on each individual person).
They have that already, but each starlink satellite isn't streaming a live
feed of each individual citizen... that we know of.</p>

<p>And the news article I didn't click through (the signing ceremony Melania
was at for her anti-bullying crusade) says they outlawed deepfake porn
(not other kinds of impersonation, specifically
singling out porn) so when project 2025 outlaws all "porn" (including skimpy
clothing or suggestive dialogue) you're guilty until proven innocent saying it
was real humans not deepfakes. With Pearl Clutching Pelosi and Senile Schumer
cheering them along, just like SOPA/PIPA, FOSTA/SESTA, and KOSA.</p>

<p>Google recently shipped an app to my phone, <a href=https://www.kaspersky.com/blog/what-are-android-safetycore-and-key-verifier/53171/>installing it without my consent</a>,
on an old and out of support model that hasn't gotten security updates in
3 years, to scan for nudity. In photos taken and stored locally. Why do that?
Because project 2025 has completely outlawing "porn" as an objective,
with Maga defining what is and isn't "porn". The law binds but does not
protect: "I'll know it when I see it." You can't ever say what ISN'T porn,
but they get to declare shoes porn because some people have shoe fetishes.
Women on twitter were lamenting this under the first trump administration.
Security cam footage of murders is commonly shared online, but if you're
found with entirely imagined drawings of the wrong kind of sex your life
is over.</p>

<p>Kind of depressing to be a nudist right now. (Or sex positive, which is a
separate thing.)</p>

<p>We went from Suicide Girls being a cultural force and The Internet is
for Porn winning a tony in 2011 to burquaville under the new Comstock Act in
a dozen years. If you don't cover your mouth, somebody could kiss it! A random
stranger could stick their FINGERS in your mouth! Without asking! And you'd
be to blame because you didn't wear your face covering at all times!
(But somehow this only applies to women, who'd want to stick their fingers in
a man's mouth? <a href=https://youtu.be/BGASvVqzOa0>Dave Allen</a>'s "<a href=https://www.youtube.com/watch?v=OnxNF2Lo-_o>Nose Knickers</a>"
could easily have been reality...)</p>

<p>In skyrim you murder endless hordes of strangers on sight because the game
calls them "bandits" (and can get a perk to decapitate them), but when
you steal their armor they still have underwear because simulated recreational
murder is fine, simulated recreational nudity is not. (Let alone SEX.
Can't even MENTION that.)</p>

<p>Is it any wonder so many people have "gender dysphoria" these days if nudity
is completely verbotten and any HINT of sexual nature below the age of 18
is a felony? If anyone EVER sees the SHAME in your pants mommy and daddy will
go to jail and YOU won't just be an orphan you'll wind up on a special
list of bad people FOREVER, so you must hide it and pretend as hard as you
can that it's not there. But that person over there, what they have under THEIR
clothes is fantastic and magical and you want it SO MUCH... If you could just
swap what you've got for what they've got maybe everything would be all fixed!
And a new religion blossoms, where a voice deep in their heart tells them a
truth nobody else can hear, which they devote their life to and will
die for if necessary.</p>

<p>I'm not saying this is the only reason people wind up hating their bodies
enough to jump through flaming hoops to get drugs and surgery while becoming
a lifetime target for every hate group, but clamping down HARDER seems unlikely
to improve anyone's self-image or self-acceptance. And pondering
<a href=https://www.nbcnews.com/health/kids-health/heres-how-dirt-might-protect-kids-asthma-n421861>where asthma
comes from</a> doesn't mean outlawing inhalers: this society has produced over a
million trans people and they deserve a good life. Deal with it. You can
vaccinate for polio and make everything wheelchair accessable at the same
time.</p>

<p>The current round of repression started with a supreme court decision in
1982 (<a href=https://en.wikipedia.org/wiki/New_York_v._Ferber>yes that recent</a>)
which said 1) the constitution doesn't apply to everybody (because children
aren't people) and 2) sex is
somehow worse than murder. If you murder a kid, once you serve <a href=https://www.reddit.com/r/Dallas/comments/dcrd5t/for_those_of_you_who_think_10_years_for_murder_is/>your time</a> you
don't have to announce it to the neighbors when you move in. Unless they think
you had a sexual motive for doing it, then you're on the list. (If Epstein had
merely killed a bunch of young women, he wouldn't still be news five years
later. We know because mass shooters are forgotten right quick.)</p>

<p>In 1979 the original Superman movie had full frontal nudity when toddler Clark
climbed out of the escape pod and nobody batted an eye. Naked baby pictures
were normal, they were in the <a href=https://www.imdb.com/title/tt0084979/>opening</a> <a href=https://youtu.be/WYUENT6FUiQ>credits</a> of television shows. I showered
together with my younger brother until I was 10 (and with my sister a couple
times when I was really young, which is how I knew
growing up that girls bodies are different). In Shakespeare the nurse notes
that Juliet is "not yet fourteen", but the barrier to her relationship with
Romeo isn't age but the fact his family belongs to a different political faction.
Otherwise they'd have happily gotten married and it wouldn't be a tragedy.
Saying that power imbalance is bad in a realtionship and thus it's wrong for
a teacher to have sex with their student, a boss with their employee, a
soldier with their commanding officer, or a billionaire with ANYBODY,
isn't the same as drawing an arbitrary line and going "on this side
there's nothing, on this side it's 100%". (I'm waiting for the prudes to raise
the age of consent from 18 to 21, like the drinking age. Which is also strange:
kids in europe regularly get alcohol from their parents, and they turn
out fine. Reality is shades of grey, any system drawing bright lines
isn't reality. "Thou shalt not murder, except in self defense, now join
the army, or <a href=https://www.vox.com/21497089/derek-chauvin-george-floyd-trial-police-prosecutions-black-lives-matter>the police</a>.")</p>

<p>We keep EXPORTING victorian prudishness. Japan still has mixed gender
public baths to this day (<a href=https://youtu.be/T0NINJOuaf4>as does
Germany</a>) but the USA has been prostletyzing at them to stop. I remember
growing up on Kwajalein, watching a scene from the 1980
<a href=https://www.imdb.com/title/tt0080274/>shogun</a> series where the
translator explained to the gaijain protagonist that people in japan weren't
ashamed of their bodies. (Which is <a href=http://youtube.com/post/Ugkx-Mdub-Xx8s4Y2Jnd4Gm-b_e9Py1V3zMV>true</a>.)
A century ago (AFTER the Meiji Restoration spent decades copying western
traditions) japanese labor clothing while planting rice or pulling a
rickshaw was <a href=https://meiji.filmarchives.jp/lumiere-works/ML29-1030.html>basically a speedo</a>
(and in india wearing less was <a href=https://en.wikipedia.org/wiki/Kaupinam>considered
holy</a>),
but these days in tokyo adults need to be fully covered at all times (long pants, long
sleeves, don't show shoulder) because america says
so. Kids in japan are treated as people, expected to be <a href=https://medium.com/a-parent-is-born/the-first-errand-the-japanese-tradition-that-will-change-you-parenting-style-2432b7fb02e8>autonomous</a> in a
society that respects them and keeps them safe. Over here we outright
boggle at that (the netflix series "old enough" is americans boggling), except...
I walked to school in the 1980s. I was a latchkey kid.
Charlie Brown and Leave it to Beaver and Lassie could all follow children
whose parents weren't around because children didn't used to be prisoners
under perpetual house arrest going through metal detectors past armed
security to enter school for their active shooter drills. It was normal HERE
until recently, and <a href=https://www.freerangekids.com/>some people</a>
have been fighting to preserve what's been taken away.</p>

<p>Conservatives always use "protecting children" as an excuse to
dig farther into people's lives. The main anti-abortion group was called
"focus on the family". Ever since the supreme court punched a hole in
the constitution in 1982, children not being people provides
a handle by which rights can be stripped away from the rest of us. Random
naked pictures on your laptop? If you can't prove every one of these people
you've never met is over 18, that's a felony! Guilty until proven innocent.
Even made up DRAWINGS of underage nudity (or sex) is verbotten. To protect
entirely imaginary people. You can draw bloody dismemberment and nobody
thinks anyone will get any ideas. Cannibalism's fine too, there's a Tom Petty
<a href=https://www.youtube.com/watch?v=h0JvF9vpqx8>music video</a>
where he eats Alice in Wonderland, and plenty of <a href=https://youtu.be/4XP5NhS0aYE>other</a> <a href=https://www.youtube.com/watch?v=9wgkSKfr4LI>songs</a>
where sexual desire is couched in terms of cannibalism to
get past the censors). But sex is SPECIAL, because
bible, except not as special as the OTHER parts of the bible apparently.

<p>Imagine if the bible's dietary laws were socially enforced the same way. You
imported the Japanese hentai called "Campfire Cooking" where the cartoon
man cooks milk and meat together! You can SAY that watching cartoons eat
doesn't necessarily make you hungry, but we all know better! For SHAME!
Anime is FULL of characters conspicuously eating and screaming OISHII!
It's disgusting, you could get tapeworms and hepatitis and gout and
cholera and obseity and ALL SORTS OF TERRIBLE THINGS COULD HAPPEN...
We tracked down Typhoid Mary, but a similar spreader of STDs? The victims
deserve it, everyone's too shamed to come forward. That's why we still
HAVE STDs but have virtually eliminated foodborne illness despite eating
and drinking far more often than we have sex.</p>

<p>The Boomers are not dying fast enough. And someday "project 2025" will
be shelved next to "Mein Kampf". But for the moment, you can't complain
about the inability to draw pictures of mohammed without the zealots
descending upon you, and we have our own religious third rails here.
Promulgated by a church that diddled choir boys en masse, telling us
we can't use our own judgement because priests can't be trusted.</p>

<p>Even when the problem is real, your solution can be worse. And Pelosi and
Schumer are right in there making it all worse. You've invented an accusation
so horrible that guilt need not be established, that the topic can't be
discussed, and perpetually increasing enforcement mechanisms encroaching upon
our lives are justified because otherwise you're ONE OF THEM. You can never
push back even a little without painting a target on yourself. Encryption
can't be allowed. Privacy can't be allowed. A neighbor babysitting your
kids? Horrors, they could be a PREDATOR, instead pay exorbitant fees for
day care with a waiting list. Children are too precious to exist,
if they play on the corner of your block without a parent standing over
them, CPS will come and take them away and even <a href=https://www.youtube.com/watch?v=mrkLwOxychA>put the parent in jail</a>. (And yet Nick's uncle still raped her
for most of a decade, starting from age 6 until he died of a heart attack.
She didn't feel safe telling anyone, because of the culture of shame. (Well,
and he threatened her if she did, but mostly the shame.) As with the choir
boys, the "solution" allowed the problem to persist.)</p>

<p>Sex is a normal part of life, except for <a href=https://www.youtube.com/watch?v=kDOGMM9IaT0>religious zealots</a>.
It wasn't just possible to read playboy for the articles, it was _common_.
There was a <a href=https://www.youtube.com/watch?v=TvWhzaFSdpw>braile edition</a>,
and yes there was a <a href=https://playgirl.com/>playgirl</a> magazine too.
This mess is recent, and very unsustainable.</p>

<p>I'm not any sort of expert on this. I don't WANT to be any sort of
expert on this. I just want the idiots who clearly know EVEN LESS THAN I
DO about it to back the FUCK OFF. Which they can't, because
<a href=https://www.youtube.com/watch?v=uqpq9tP14PA>to quote the fourth doctor</a>,
"The very powerful and the very stupid have one thing in common. They don't
alter their views to fit the facts, they alter the facts to fit the views.
Which can be uncomfortable when you happen to be one of the facts that needs
altering."</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#20-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 19, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#19-05-2025</link>
   <pubDate>Mon, 19 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Started a news.html entry for a new toybox release. I'm not at a good
stopping point on the kconfig or shell alias stuff, STILL haven't
moved the hash stuff into lib/ and replaced the crypt() function,
need to re-promote the passwd commands, need to merge those xz-embedded
commits Oliver identified way back when...</p>

<p>But the kernel's on an -rc7 (about
to drop a new release), qemu had its 10.0.0 release last month, and I should
really start regression testing everything and do new binaries. The android
guys probably have a new ndk toolchain too. I've poked Rich multiple times
about a new musl release, and in theory musl-cross-make
has gcc 12 patches so I should upgrade that...</p>

<p>As my father (an electrical engineer who among other things helped develop
the Aegis Phased Array Radar system) used to say, "Eventually you have to
shoot the engineers and go into production." Quicksave a checkpoint
before hitting the next dungeon.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#19-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 18, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#18-05-2025</link>
   <pubDate>Sun, 18 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Urgh, where did I leave off on the toysh alias stuff. (Unfocused. No
caffeine.)</p>

<ul>
<li>unalias doesn't work</li>
<li>only alias when interactive</li>
<li>$VAR expansion can't call function (I.E. <a href=http://lists.landley.net/pipermail/toybox-landley.net/2025-February/030697.html>Tim's bug</a>.)</li>
<li>Allow prefix interleaving in run_command().</li>
</ul>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#18-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 17, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#17-05-2025</link>
   <pubDate>Sat, 17 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I did not write down when I started doing the caffeine detox. I think
monday? Anyway, I've been semi-zombie all week because... maybe not
zero caffeine (how much is in green tea or those arnold rimmer half lemonade
cans from Aldi's?) but seriously undercaffeinated by my standards.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#17-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 16, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#16-05-2025</link>
   <pubDate>Fri, 16 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Got a <a href=https://github.com/landley/toybox/pull/549>pull request</a>
from user ppphs on github, whose git commit comes from a qq.com address
(basically china's gmail). In hopes of finding a name to attribute the commit
to, I went to his(?) github account main page where he describes himself as
"try my hard to be more execellent". I can't argue with that. (Especially
after many years of failing to learn japanese.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#16-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 15, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#15-05-2025</link>
   <pubDate>Thu, 15 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>

<p>I asked the Linux Foundation about refspecs.linuxfoundation.org (since
it hasn't got the ELF architecture supplement for sh4, cortex-m, riscv...)
and got back a reply that turned into a thread. Here is a response I did
NOT send them, because it wouldn't help.</p>

<blockquote><p>
&gt;&gt;&gt;&gt; These sites are not being maintained as you noticed. They were formally<br />
&gt;&gt;&gt;&gt; archived into static html ~10 years ago, currently hosted by the OSU Open<br />
&gt;&gt;&gt;&gt; Source Lab.<br />
&gt;&gt;&gt;&gt;<br />
&gt;&gt;&gt;&gt; Jeff Licquia is no longer with the Linux Foundation as of a couple years<br />
&gt;&gt;&gt;&gt; ago, and as a result there is nobody maintaining the archive.<br />
&gt;&gt;&gt;<br />
&gt;&gt;&gt; These are useful resources. Would you be interested in coordinating<br />
&gt;&gt;&gt; maintenance with an external team, or should we just host the pages<br />
&gt;&gt;&gt; somewhere else and try to replace the old sites in the community?<br />
&gt;&gt;<br />
&gt;&gt; Great, thanks for letting us know. I'm circling the right people internally<br />
&gt;&gt; to get you an answer. I'm guessing we'll be interested in the help, but<br />
&gt;&gt; I'll get the right people looped in once I hear back.<br />
&gt;<br /> 
&gt; If you're looking to get a group of companies that want to start working on<br />
&gt; LSB again, @Jory and @Mike from the LF can help with the next steps. Can you<br />
&gt; tell us a bit more about the plan?<br />

<p>I was specifically trying to get the curated set of base reference documentation updated, specifically the ELF (and Dwarf?) specs are missing several modern architecture supplements.</p>

<p>FYI Long ago I was briefly the Linux kernel Documentation/ directory maintainer for you guys (circa 2007) and created kernel.org/doc while working on that. Jonathan Corbet of Linux Weekly News has that maintainer position now, and it's entirely possible refspecs.lwn.net or refspecs.kernel.org are a better place to park this sort of thing. I can poke Konstantin about kernel.org if that makes sense.</p>

<p>While an updated LSB/FHS might be nice, that's a larger scope than I'm currently proposing. (And I'd loop enh at google dot com in on _that_, he's the Android base OS maintainer and we've lamented the lack of proper modern base OS specifications privately for years; at least Posix finally came out with Issue 8 but Posix has always been a subset (no "mount" command, for example) and due to Jorg Schilling not dying soon enough it yanked "tar" (in favor of Solaris "pax" that nobody else uses) and "cpio" (the basis of initramfs and rpm) from the spec, but still documents "sccs".</p>

<p>There's also politics/credibility after the LSB's dust-up with Debian, stemming from defining "rpm" as "the standard" (a decision perceived to be made because Red Hat gave the linux foundation money, at least that's what
the <a href=https://wiki.ubuntu.com/DavidMandala>manager of Ubuntu for ARM</a>
told me at CELF back in 2008). I talked about the LSB's political
problems a bit in <a href=https://landley.net/toybox/roadmap.html#sigh>the toybox
roadmap</a>.</p>

<p>*shrug* Politics. Trying to step around it...</p>

<p>I don't believe lanana.org (the other website I mentioned that's been 404 below the top page since the announcement that the Linux Foundation was taking it over) is part of LSB either. But that one's already mirrored on kernel.org, and updating it is probably mostly just running a grep in the kernel code and chasing down where each gets the numbers:</p>

<blockquote><pre>
$ grep -ho 'MKDEV([^)]*)' -r * | wc -l
416
</pre></blockquote>

<p>(Kay Sievers' idea that major:minor numbers would be dynamically assigned seems to have been allowed to die quietly after Linus very publicly kicked him out.)</p>

<p>THAT probably belongs in the kernel Documentation/ directory, and I should poke Jon about it...</p>
</blockquote>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#15-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 13, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#13-05-2025</link>
   <pubDate>Tue, 13 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>When I switch my bluetooth headphones off and back on, they reset to a
default volume which is just slightly too loud for comfort. They associate
automatically and have a start/stop button that resumes whatever was playing
last, but half the time I have to fish my phone out of my pocket just to
adjust the volume. (And pressing the up/down buttons there is a delta from
its remembered volume, so usually a noticeable jump from the headphones'
default.)</p>

<p>Implementation details leaking to the surface. Part of the reason I break
everything is I'm not always mentally modeling an abstract user interface,
my brain takes things apart to figure out how they implemented it, and I'm
subconsciously thinking in terms of what I think this piece of machinery
is actualy doing. And sometimes, my imagined design differs from theirs in
ways they didn't account for. "Nobody will ever do that. Certainly not
consistently..." (Flashback to learning to drive stick where I initially
tried to prevent the clutch from slipping because I thought plates grinding
against each other would wear them out, hence lurches and stalls until my father explained
that "yes asbestos has been removed in most places but clutch pads are still
made from it and they're DESIGNED to slip, it's bad if they DON'T slip,
the sharp shocks are peeling the asbestos off". My father was also an
engineer. And my mother's father. I come by it honestly on both sides.)</p>
</p>

<p>Most of the time it's helpful though. I started playing skyrim again and
worked out that the R1 trigger button (shouts) has a dirty contact, but possibly
two contact switches? If you pull towards yourself like a trigger it
ignores you, but if you push it SIDEWAYS (the button wraps around the corner
of the controller), it reliably makes contact. So just do that. (I mostly
just use whirlwhind sprint while overloaded and heading back to sell stuff.
Yes I'm early enough in the playthrough I haven't broken down and used the
resto loop to make boots of carrying a million pounds, and if I drag Lydia
along she'll kill steal so I don't get souls from the mudcrabs to level
enchanting with. Also... when I tell Lydia "I need you to do something -&gt;
pick that up" to bypass her encumbrance limit, it seems to be marking
those items stolen now? Just noticed that and haven't quite worked out what's
going on there, maybe one of the updates they sent before I put the thing
permanently in airplane mode when Nintendo announced they were awarding
themselves the right to <a href=https://betanews.com/2025/05/09/nintendo-switch-2-console-kill-switch/>brick your switch</a>
at will.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#13-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 9, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#09-05-2025</link>
   <pubDate>Fri, 09 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I got the basics of alias support in, and the alias parsing is skipping
leading redirects, variable assignments, and whatever "!" is called. That's
the prefix operator that reverses the true/false status of the command's exit
code, so zero becomes 1 and nonzero becomes 0, and yes you can ! ! ! multiple
times in front of a single command, which inverts the _previous_ result:</p>

<blockquote>
$ ! ! ! &gt; file.txt A=B env; echo $?; grep ^A= file.txt<br />
1<br />
A=B<br />
$ ! ! &gt; file.txt A=B env; echo $?; grep ^A= file.txt<br />
0<br />
A=B
</blockquote>

<p>The next test I want to pass is <b>shxpect 'alias prefixes' I$'alias abc=env\n'
E"$P" I$'! &gt; hello a=xyz abc\n' E"$P" I$'grep ^a= hello\n' O$'a=xyz\n'</b>
which means:</p>

<ol>
<li>launch an interactive shell as a child process in an "expect"
style environment where we're in control of its stdin, stdout, and stderr</li>
<li>write "alias abc=env" to the child shell process's stdin</li>
<li>read "$ " from its stderr (shells write prompts to stderr, not stdout)</li>
<li>write "! &gt; hello a=xyz abc" to its stdin</li>
<li>read another prompt fron stderr</li>
<li>write "grep ^a= hello" to its stdin</li>
<li>read "a=xyz" from its stdout</li>
</ol>

<p>The point is to prove that when we do all three prefix types before an
alias, the alias is still expanded properly. (And it's doing the redirect
variant where the redirect operator and the file to redirect to are two
different arguments, to ensure we've got the full parsing complexity in there.
Well, I'm not testing {x}&lt;$blah but it's using skip_redir_prefix()
which should handle that.)</p>

<p>The shell expect plumbing I wrote (function "txpect" in scripts/runtest.sh)
launches a child process and sends it input strings (arguments starting with
I), reads from the child's output (O), reads from its stderr (E), and at the
end can check for a specific exit code ala "X37". Normal "run this test
and show me the output" tests can't really interrogate things like line
continuation. The shxpect function is a wrapper around txpect that
provides the big long sh command line to avoid reading the normal rc files
and put it in interactive mode despite input not being a tty,
sets up $P to be "$ " for normal users and "# " when run as root,
explicitly calls "bash" instead of "dash" for TEST_HOST (because testing
the Defective Annoying Shell is pointless), and so on.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#09-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 8, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#08-05-2025</link>
   <pubDate>Thu, 08 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Finished the first pass implementing alias support, although I haven't gated
it on interactive mode yet so in theory </b>toybox sh -c $'alias abc=def;abc'</b>
should let me test it. In practice, that immediately segfaults (although
<b>make test_sh</b> passes all the way through, so obviously the failure is
in the new ASAN codepath in parse_line().</p>

<p>Of course building with ASAN=1 makes no difference, the output is just
"Segmentation fault" with no other indication that ASAN is linked in.
Adding V=1 to the build confirms that all the ASAN flags are there, but
either this failure is bypassing their debugger or gcc had funky version
skew so ASAN no longer happens at all. Wheee...</p>

<p>And of course the Android NDK never had ASAN work for static linked
binaries, only dynamic.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#08-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 7, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#07-05-2025</link>
   <pubDate>Wed, 07 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Sigh, laptop failed to come out of suspend (the backlight lit up but the
screen remained otherwise black, ctrl-alt-f1 didn't go to text mode,
and closing the lid didn't suspend it), so I had to power cycle it and lose
all my open windows.</p>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#07-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 6, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#06-05-2025</link>
   <pubDate>Tue, 06 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>For the record, here's the big long email I typed up (and then spent
multiple attempts to edit DOWN, each time instead making it larger),
and eventually decided NOT to send to Chet:</p>

<blockquote>
<p>I held off on sending this because I don't think it'll help. Feel free to skip.</p>

<p>I think I know what I need to do, the question was mostly whether it was worth doing. I wanted to understand _why_ alias is like that (what is it _for_), but there doesn't seem to be an answer. Just backwards compatibility with a historical design from 1976.</p>

<p>Still, as long as I've already typed it up...</p>

On 5/1/25 20:26, Chet Ramey wrote:<br />
&gt; On 5/1/25 6:23 PM, Rob Landley wrote:<br />
&gt;&gt; The implementation is different but what they do is the same. Modulo<br />
&gt;&gt; the "wrapping source" thing I mentioned. But I've never seen anybody<br />
&gt;&gt; do that, I'm just going "maybe that's why it exists".<br />
&gt;<br />
&gt; What they do is definitely not the same. You can make them appear to have<br />
&gt; the same effect, but it's not the same.<br />

<p>This is that "how vs why" distinction again. I can work out "how" by asking enough questions and running enough tests, the question was always "why".</p>

&gt;&gt; (I've never seen anybody use "alias" as anything but function<br />
&gt;&gt; definition with a more convenient syntax, and I've been reading shell<br />
&gt;&gt; scripts since 1992.)<br />
&gt;<br /> 
&gt; People who do things other than that are trying to be too clever by half.<br />

<p>Isn't that the reason for alias to exist when we have functions? That and being automatically disabled when the shell isn't interactive, which is just weird.</p>

<p>To be honest, back in ~2019 when I got to the alias part of the bash man page and it said "The rules concerning the definition and use of aliases are somewhat confusing... For almost every purpose, aliases are superseded by shell functions." I punted and just implemented functions, and people have been griping at me ever since. "If you're going to do it, do it right" can lead to a certain amount of procrastination on the doing it part.</p>

<p>And then when I _did_ circle back around to alias support I initially forgot that "help alias" and what the man page says about alias were two different things. (In toybox there's one instance of help text for each command. I try not to have more than one instance of the same thing wherever possible, so the command --help output and "help command" are all sourced from the menuconfig text so there's just the one...)</p>

&gt;&gt; You can alias "if". I just don't know why you'd WANT to.<br />
&gt;<br /> 
&gt; Sure. POSIX doesn't let you, btw.<br />

<p>I first read through what posix had to say about shells in 2006, which is admittedly both a bit hazy and 2 major releases back now anyway. I was waiting for Issue 8 before rereading (and then they didn't have html available, and then didn't have DOWNLOADS available, but now they do and it's on my todo list).</p>

<p>But
<a href=https://wiki.ubuntu.com/DashAsBinSh>https://wiki.ubuntu.com/DashAsBinSh</a>
was SUCH a disaster I've focused on the bash man page and bash help output ever since, and tested what bash did. A close pass through posix to make more tests is on my todo list after finishing the bash man page, but dash cured me of any idea that being a posix compliant shell was in and of itself a good thing. (And as that page says he did it to "speed up the boot scripts", which FAILED so they made upstart to parallelize them with dependencies, the failure of which is why systemd exists, and yet he never admitted his mistake and pointed /bin/sh back at bash. Sigh.)</p>

<p>Speaking of things posix is unlikely to cover, why does bash's "help \(" give help output for (( )) arithmetic expressions instead of (subshells)? Is that intentional? I notice "(" isn't in the two column "help" output list. Nor is ! and there's no "help \!" either.</p>

<p>(I ask because I still don't have infrastructure in toybox to provide help entries for KEYWORDS which aren't shell builtins that otherwise work like commands, ala "help if" and "help {", and running tests. It's on the todo list. And found by asking questions and poking at bash, not by reading the new posix-2024.)</p>

&gt;&gt; Ah, yes that's what I was expecting. And it did it. Which means it's<br />
&gt;&gt; not _just_ special casing prefix assignments, it's also special casing <br />
&gt;&gt; redirects.<br />
&gt;<br />
&gt; Because a simple command consists of words, assignment words, and<br />
&gt; redirections. A redirection is not a word, and is not eligible for<br />
&gt; alias expansion. If you want to consider that "special casing," go for<br />
&gt; it, but don't claim that it's not well-defined.<br />

<p>My question was more "is there anything _else_ I have to specially check for that could go before the command name to exec". The bash man page says:</p>

<blockquote> <p>Simple Commands<p> <blockquote>
<p>A simple command is a sequence of optional variable assignments
followed by blank-separated words and redirections, and terminated
by a control operator. The first word specifies the command to be
executed, and is passed as argument zero. The remaining words are
passed as arguments to the invoked command.</p>
</blockquote></blockquote>

<p>Which uses "words and redirections" interchangeably, so yes you can have redirections before the first "word".</p>

<p>But it doesn't mention the leading ! that can invert the return code:</p>

<blockquote>
$ alias abc=def<br />
$ ! abc<br />
bash: def: command not found
</blockquote>

<p>I have to special case check for all these things, since it happens before my normal command processing, but I'm never sure I'm checking for ALL of them because I don't understand WHY some are allowed and some aren't.</p>

<p>Also, the definition of "interactive" seems a bit arbitrary:</p>

<blockquote>
$ alias abc='echo potato'<br />
$ echo 123$(abc)456<br />
123potato456<br />
$ cat &lt;(abc)<br />
potato<br />
$ cat ../../../../../&lt;(abc)<br />
potato<br />
</blockquote>

<p>I.E. "sh -c blah" isn't interactive, but &lt;(text) is.</p>

&gt;&gt; Yeah yeah, blame posix...<br />
&gt;<br /> 
&gt; No! Don't blame POSIX! This is how Bourne shells work.<br />

<p>So blame Bell Labs circa 1976?</p>

&gt; The first word in<br />
&gt; the command I marked as `command 1' up there is $X. That means the second<br />
&gt; word (`blah') is not eligible for alias expansion. Even though $X doesn't<br />
&gt; expand to anything it's still the first word of a simple command.<br />

<p>Yes. This gets back to what is and isn't special case skipped when working out line continuations so it can do a text replacement on a specific input word. If "!" wasn't mentioned in the nested man page section (at least I think it does, "aliases" refers to "simple commands" which refers to "control operator"... easy to miss stuff) then what _else_ isn't? I have to check everything I can think of, and I'm never sure I've thought of everything. Assignments are skipped (but only valid ones, not "abc.def=ghi", but yes "abc_def=ghi"). Empty variables are _not_ skipped (which differs from functions and commands) because they haven't been resolved yet.</p>

<p>I have a checklist of things to look for. I have no idea if the checklist is complete, because what is and isn't on it doesn't really make sense to me except as implementation details in a specific design from 1976 I didn't look at because I'm writing differently licensed code and don't want to aggro copyright trolls.</p>

<p>I've spent quite a few years poking at corner cases trying to work out tests to understand (or at least comply with) things like:</p>

<blockquote>
$ for i; in a b c; do echo $i; done<br />
bash: syntax error near unexpected token `in'<br />
$ for i<br />
&gt; in a b c<br />
&gt; do echo $i;<br />
&gt; done<br />
a<br />
b<br />
c
</blockquote>

<p>And half the time, there doesn't seem to be a "why" for such differences. I just need tests for corner cases.</p>

&gt; In the command I marked as `command 2', we have a simple command that<br />
&gt; undergoes word expansion. After word expansion, the only word left is<br />
&gt; `func', which is executed. It happens to be a shell function.<br />
&gt; 
&gt; It's pretty fundamental that your shell understands the difference.<br />

<p>Until I tried to implement alias expansion, this "fundamental" distinction
never really came up. I parsed what I needed to handle line continuations
until I had a complete thought, then ran the result.</p>

<p>I remember redirect vs variable expansion order of operations (which alias
seems _entirely_ dependent on) leaking implementation details once before,
some corner case where mixing things like ${A=value} ${B?error} {var}&gt;file
on the same line (I think in preassignment context?) caused side effects to
persist or not based on the order things happened in (not the order they
occurred on the command line)? At the time I punted on that because it only
happened during error recovery and it was sufficiently unlikely anyone else
would ever notice that I felt comfortable waiting for somebody to complain.</p>

<p>Alas, I didn't find the actual test case for that with a brief search. I
need to reread my blog back to about 2019 to collate all the todo items out
of
<a href=https://landley.net/notes-2021.html#06-06-2021>https://landley.net/notes-2021.html#06-06-2021</a>
and friends (multiple hundreds of such entries) and make proper regression test cases for everything. But that's probably _after_ getting the basic functionality in to run the toybox test suite under toysh and build Linux From Scratch under toybox. Real world tests are more important than artificial ones.</p>

<p>I'm aware my parsing has faults. $(( )) doesn't handle case statements, because I didn't make parse_line() recurse, because I want it to work on nommu where I may only have something like 32k of stack space. (And because parse_word() is using a convenient 4k buffer for the quote stack which I'd have to duplicate, yes that means you can't "$("$("$( more than 4096 entries deep in a single block: I'm waiting for somebody to hit it and complain before changing it. The if/else nesting in parse_line() is handled with a linked list.) Which means $( ) processing only counts nested quotes, and thus doesn't understand the unmatched ) in case statements, which I admit is a flaw. (I have a todo item about it.)</p>

&gt;&gt;&gt; You have agency here, Rob: you don't have to do anything you don't<br />
&gt;&gt;&gt; want to.<br />
&gt;&gt;&gt; I'm telling you what other shells -- including bash -- do and what POSIX<br />
&gt;&gt;&gt; says (most of it's unspecified).<br />
&gt;&gt;<br />
&gt;&gt; I can see _what_ it's doing, I'm trying to figure out _why_. And am<br />
&gt;&gt; not sure I'm any closer than when I started, but again I think this is<br />
&gt;&gt; posix and history at fault here...<br />
&gt;<br />
&gt; You have to decide what you want. Do you want a reimplementation of bash,<br />
&gt; or do you want something so that you understand every "why"? You get to<br />
&gt; make that choice. And the latter is still possible, but you have to put<br />
&gt; in the work.<br />

<p>I asked because I'm trying to put in the work.</p>

<p>But there is a certain amount of 80/20 at times. Alias support has been an oft-requested feature over the years, and every time I asked for an example I got ones that work just like functions with a second namespace. I hadn't tackled it yet because I was aware there were corner cases and wanted to do it right. It's just when I looked under that rock for the corner cases, there was a lot of wriggling. Is it worth doing "right", or just doing what every test case I've ever seen wants so far? Twice as big, do it right. Ten times as big, maybe try to find an actual user...</p>

&gt;&gt; Sigh, this is preprocessor macros, isn't it? Except it wants to skip<br />
&gt;&gt; prefix assignments and redirections and who knows what else that isn't <br />
&gt;&gt; detected until the line gets parsed quite a while later.<br />
&gt;
&gt; Oh, ffs. You really should read POSIX, at least<br />
&gt;<br /> 
&gt; https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html#tag_19_10_01<br />

<p>I have. And I mentioned I plan a full re-read.</p>

<p>But I haven't looked back at the tokenizing part in forever because I don't use lex and yacc. My code just breaks input lines down into a linked list of argv[] string arrays, using a context stack for quotes and if/then/fi. The first pass is mostly for line continuation, but creates the broken down argv[] lists because it had to do that work to figure out line continuation. Then the second pass handles each argv[] entry using nested if/else staircases doing strcmp() to actually run them.</p>

<p>In a "parse a list of argv[] until line continuation is satisfied, then run the resulting list" design, what posix has to say about "tokenizing" doesn't directly apply.</p>

<p>The "this is preprocessor macros" above was a "why", not a "how" statement. I think I've figured out WHAT it's doing a couple emails ago. I still do not understand WHY it's like that. What's it FOR?</p>

&gt;&gt; See, the problem is:<br />
&gt;&gt;<br />
&gt;&gt; $ a=b if true; then echo a=$a; fi<br />
&gt;&gt; bash: syntax error near unexpected token `then'<br />
&gt;<br /> 
&gt; How is that a problem?<br />

<p>It's inconsistent behavior. The fact it _doesn't_ work seems fairly arbitrary. I thought about allowing it anyway, but didn't for compatibility. Same way I didn't allow "x() echo hello;" despite "x() if true; then echo hello; fi;" being allowed. Or the way the semicolon after that fi is fine, but this is not:</p>

<blockquote>
$ ;<br />
bash: syntax error near unexpected token `;'
</blockquote>

<p>There's no obvious reason I can spot to accept ":;" but not ";", just "that's what's come down to us through the ages".</p>

<p>Again, they're "why" questions. Half the time the answer is "implementation artifacts from a different design".</p>

&gt; A reserved word can't be recognized as such unless<br />
&gt; it follows an operator or other acceptable token (there is a finite number<br />
&gt; of tokens that can prececde a reserved word).<br />

<p>Parsing logic is always a giant state machine of X goes after Y. I was just surprised by the order of operations:</p>

<blockquote>
$ alias abc='while true; do'<br />
$ abc<br />
&gt;
</blockquote> 

<p>This feature has to perform targeted string substitution BEFORE resolving line continuation, and yet allow:</p>

<blockquote>
$ alias ls='ls -l'<br />
$ LC_ALL=$ABC ls
</blockquote>

<p>to work in the result, and that's either happening in two places or doing the same work twice.</p>

&gt; It cannot ever appear after<br />
&gt; an assignment word; assignment statements cannot precede compound commands.<br />
&gt; So the `if' can't be returned to the parser as the IF token; it's just the<br />
&gt; first word of a simple command.<br />

<p>I'm not tokenizing. I'm string matching. In toysh the core loop is get_next_line() -&gt; parse_line() -&gt; run_lines()</p>

<p>All get_next_line() does is getline() with prompting/editing/history. It returns a string, or NULL for end of input.</p>

<p>Then parse_line() digests each input line to accumulate a list of broken out argv[] (plus some metadata), and returns whether or not it needs another line to complete the current thought (line continuation, which is a continue; in the loop).</p>

<p>Then run_lines() is called when parsing gives the ok to process that accumulated list of parsed argv[]'s, which are still strings. (And then there's a free() before the loop hits the end and restarts.)</p>

<p>Parsing creates a circular doubly linked list of pipeline segments (struct sh_pipeline *pl), each of which has a struct sh_arg { char **v; int c; } member. (Actually it has an array of those, the first is the command and later ones if any are here document bodies fed into this command in order.) So it's literally chopping up the input into a linked list of argv[] with metadata.</p>

<p>The goal of parse_line() is really to satisfy line continuation, because "echo hello; if true" won't run the echo before prompting for the next line, I.E. all line continuations are resolved before executing anything, so it has to happen in two passes. So I wrote two passes. That said, parse_line() had to ask a lot of questions TO resolve line continuation, and I cache the answers in pl-&gt;members so the later code doesn't have to ask them again (the "plus some metadata", above).</p>

<p>Internally parse_line() calls parse_word() which returns the end of the
current word. It has some basic understanding of redirects (although only as
the start of a word, meaning subdir&lt;(echo hello) gets split into two arguments
as if there was a space between them, which came up trying to set up a chroot
once, and is also why I did the ../../&lt;(blah) above because I'm aware mine
does NOT currently get that right). It also has a list of line terminators like
|&amp; because that's fundamental to splitting up the argv[] entries, and the
rest is mostly pushing/popping various types of quotes on a stack so it can
also go "I need another line to complete this thought". (In this context, "if"
is a quote terminated by "then" which is a quote terminated by "fi".) When
it _does_ get another line, the parse_line() logic glues them together with
\n and calls parse_word() from the previous offset into the new string so
it re-parses that argument from the beginning.</p>

<p>The closest all this gets to tokenizing is that each pl entry has an integer
"type" field which is 0 for a regular executable command, 1 for a flow control
statement ("if" and "for" but also "{" and "("), 2 for a flow control gearshift
(like "then" and "do"), and 3 for an end of block statement, because the line
continuation logic already had to figure that out and keeping it constrains
what run_lines() has to check for. (There are a few other types, like function
definitions and case statements, but it's all just saving work parse_line()
already had to do to figure out line continuations.) Each command's arg list
can end with &amp; or &amp;&amp; or | so run_lines() can figure out how to
chain them together and when it needs a subshell (the terminator is actually
arg.v[arg-&gt;c], not _part_ of the arguments per se, but these are raw
arguments before variable and redirect and quote removal so the lack of NULL
teminator for exec() isn't a problem), and there's a pl-&gt;end pointer that
points to the end of the current block (mostly so we can efficiently handle
block redirects, but also useful for break and so if...fi &amp;&amp; if...fi
can skip ahead without having to traverse the list checking types to find it).</p>

<p>There are some rough edges. The fact that $( ) is a quote type matched by parse_word(), as is (( )), but ( _isn't_ but is returned as a separate word (flow control statement!) is basically why handling case statements in $( ) is tricksy and really wants recursion. And yes ((echo);echo) is handled properly, which involves (( being a special quote type (255) so trying to pop a _single_ ) against it goes back and demotes it to normal ( instead of popping it, and yes I've tested this against arbitrarily deep levels of (((((...</p>

<p>But really, toysh just breaks the input up into individual commands, each of which is arg.{v[],c} and a little cached metadata left over from working out line continuation. Then run_lines() and run_command() and expand_redir() and so on figure out what to _do_ with them.</p>

<p>I see what bash is doing:

<blockquote>
$ set -x<br />
$ alias one=two<br />
+ alias one=two<br />
$ one<br />
+ two<br />
bash: two: command not found
</blockquote>

<p>I have to put string substitution plumbing in parse_line(), AND track which entry I should be examining specially with a new state flag. The problem is while parse_word() has to know about redirects to skip them properly, all it returns is a pointer to the end of word. (Which is NULL if we need another line or the null terminator at EOL if there's no more words.)</p>

<p>But the reason things like prefix assignments aren't checked for until run_command() _way_ later in the process is precisely BECAUSE "a=b if" isn't allowed. If parse_line() had to advance past prefix assignments and redirects in order to resolve flow control, it would be doing so. Right now, run_command() is doing that much later in the process. Now there's what basically amounts to a layering violation.</p>

<p>I need to add a redundant check to parse_line() for leading redirects and prefix assignments so I can perform string substitution. Except the EXTRA fun about this is the unterminated quotes where it would have to start re-parsing from the middle of the ALIAS text after asking for an additional line, and of course this insanity:</p>

<blockquote>
$ alias abc='cat &lt;&lt;'<br />
$ abc&lt;hello<br />
hello
</blockquote>

<p>Alias ending in the middle of a OPERATOR means parse_word() has to traverse the context switch internally.</p>

<p>Sigh, I can do it. Quite possibly with a global variable storing state between calls to parse_list() since "the string" is no longer true when it becomes a stack of strings. (Or make it return a struct, which... ew. And expensive, has to do this stuff for every input word.)</p>

<p>I'm just... there's no "why" for this feature, other than historical inertia. I was hoping the _why_ would provide a good reason to do what seems like a lot of work for very little gain that I'm unaware of any actual users for. I have yet to get a real-world example where "alias "x=y" turning into x() { $y "$@"; } in a second function namespace would behave differently. (Which is what my first attempt basically implemented, and then I went "no, but...")</p>

&gt; Since `then' appears after a token that can precede a reserved word, you<br />
&gt; return THEN as a token (or however you represent it). That's a syntax<br />
&gt; error.<br />

<p>I believe at one point I had prefix assignments working before blocks, and backed it out because it's not "supposed" to work. Now I need to put it back in, but _also_ put redirects and ! in there. AND of course:</p>

<blockquote>
$ alias abc='echo hello'<br />
$ &gt; file abc<br />
$ cat file<br />
hello<br />
$ alias abc=cat<br />
$ &lt;&lt;&lt; because abc<br />
because<br />
</blockquote>

<p>Since redirects can eat the following argument. (I _have_ code getting this all right to the best of my knowledge, just... not in THAT part. My code does the parsing work when it needs to use the result, this is parsing it and discarding the result so later code can do it again. Factoring it out it is nontrivial, the two contexts work on different types of data structures, and I can't just _move_ it because it's still needed where it is...)</p>

&gt; "1. [Command Name]<br />
&gt;<br />
&gt; When the TOKEN is exactly a reserved word, the token identifier for that<br />
&gt; reserved word shall result. Otherwise, the token WORD shall be returned.<br />
&gt; Also, if the parser is in any state where only a reserved word could be the<br />
&gt; next correct token, proceed as above."<br />

<p>I'm not tokenizing. I'm parsing as-needed, most of it as late as possible.</p>

&gt;&gt; I have to parse keywords to do line continuations and prompt for more<br />
&gt;&gt; input, but I can't have prefix assignments before a keyword. But alias<br />
&gt;&gt; can, and alias can RESOLVE to a keyword.<br />
&gt;<br /> 
&gt; You have to restart the lexical token scan after you expand an alias at the<br />
&gt; start of a command (you have to rescan starting with the expanded text<br />
&gt; anyway; that's how aliases work).<br />

<p>It's not a "restart" when a variable expands. It's a single pass traversal. I track how much of the input I've consumed. How much is done and how much is still to do.</p>

<p>Admittedly "done" can be multilayer since $A vs "$A" affects IFS line breaking on the expanded text or not, and $A drops out but ""$A is _going_ to produce
at least one argument but could produce more. But the indexes still only move
forward, not back...</p>

<p>Doing this for alias isn't more complicated than doing it for variable expansion. (Having parse_word() rescan from the start of the word after it detected the need for another line of input was a simplifying design decision, I didn't want to keep the quote and flow control stacks to pass back to the next instance. But if there has to be a struct anyway...)</p>

<p>But complicating parse_word() wouldn't share code with expand_redir(), and just seems so unnecessary to do it all AGAIN in a different place for a use case I've never seen anyone _exercise_...</p>

&gt; That doesn't mean you return the result<br />
&gt; to the parser as a word, though it often does.<br />

<p>It becomes an argv[], some of the entries in which may be zero length strings, just like for main(). And argv[argc] may be an operator string which connects it to the next such argv[] via conditional execution or a pipe or some such. But that's still a string.</p>

<p>(Functions I cheat a bit for, but "executing" a function definition chops it
out of the pipeline_list() and moves it to a separate list because a function
has different lifetime rules than the block of script it was declared in.
The pl-&gt;type changes after its first execution, and there's reference
counting. As I said, a bit of a cheat. Mostly so I didn't have to make a copy
of the data structures. I should test I've got a loop redefinining the function
twice with two different function bodies works properly...)</p>

&gt;&gt; It's INVENTING A LAYER, which happens EARLIER than that yet does MORE<br />
&gt;&gt; than that,<br />
&gt;<br />
&gt; This sounds like an implementation artifact.<br />

<p>Yes, but posix assumes an implementation. Which implementation it's an artifact of is the question. Very easy in the other implementation, kind of nuts in this one.</p>

&gt; Since the alias expansion happens at the lexical level, the expanded alias<br />
&gt; determines what the lexical level returns to the parser:<br /?

<p>There's no lex/yacc equivalent in my design.</p>

&gt; "When a TOKEN is subject to alias substitution, the value of the alias<br />
&gt; shall be processed as if it had been read from the input instead of the<br />
&gt; TOKEN, with token recognition (see 2.3 Token Recognition) resuming at the<br />
&gt; start of the alias value."<br />
&gt;<br /> 
&gt; There is a necessary element of rescanning here.<br />

<p>Yeah, I think I can localize it to parse_word, except...</p>

<blockquote>
$ alias abc='def &lt;&lt;'<br />
$ alias def='cat'<br />
$ abc&lt;hello<br />
hello
</blockquote>

<p>Of course it nests. Meaning the pending alias string has to be a linked list with offsets.</p>

<p>Alright, how does:</p>

<blockquote>
$ alias abc=def<br />
$ alias def=abc<br />
$ abc<br />
bash: abc: command not found<br />
$ def<br />
bash: def: command not found
</blockquote>

<p>Ah, that's misleading:</p>

<blockquote>
$ alias echo='abc 1'<br />
$ alias abc='echo 2'<br />
$ echo<br />
2 1
</blockquote>

<p>It expands BACK to the old one before refusing to go further due to recursion detection. Right. (I need to get all the test cases in so I can make sure it's passing them.)</p>

&gt; Chet<br />

<p>Rob</p>
</blockquote>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#06-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 5, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#05-05-2025</link>
   <pubDate>Mon, 05 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Prefix assignments can be += and you can have a redirect before prefix
assignments. And the ! operator can go before (or among) any of that.
Great.</p>

<p>It's not the alias corner cases, it's that in TESTING the alias corner
cases I'm finding corner cases in my existing code I never addressed.
So the changes I need to make aren't contained and keep trying to spread...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#05-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 4, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#04-05-2025</link>
   <pubDate>Sun, 04 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I'm just implementing alias support in toysh before replying to chet again,
because it's a waste of time arguing with him when I'm asking "why" questions
and he's not giving "why" answers. (Mostly a waste of _his_ time, I've already
done the arguing into an email composition window. But sending the result does
not seem like it would be productive, I'm unlikely to learn anything more of
use from the exchange because he's not answering the types of question I'm
asking.)</p>

<p>My first pass alias code (before starting the email thread) which treated
aliases as early function calls had a comment "TODO: lifetime of alias entry
when alias command redoes it using an alias" and I guess THAT'S sorted now.</p>

<p>I think I can get away with just
having one global variable to deal with this crap... nope, I may need
two. Because it recurses. One variable so parse_word() can keep track of
where to restart when resuming alias expansion after asking for additional
input due to unterminated quotes, and one one so recursive alias expansion
can track the alias stack it's popping down through. And alas, parse_word has
to deal with _both_. Urgh, and the stack has to include the resumption
point because:</p>

<blockquote>
$ alias echo='abc 123' abc='echo 456'<br />
$ echo<br />
456 123<br />
</blockquote>

<p>When the aliased "echo" recurses into the alias "abc" parse_word has to
return two completed words, then RESUME the previous alias epansion to
return the third word. And then fail to recurse further because it's already
expanded echo, and thus leave "echo" as the literal string which gets
interpreted as a shell builtin command.</p>

<p>Sigh. On the one hand, "if you're GOING to do it, do it right". On the
other, NOBODY is going to notice this. I've never seen alias used as anything
other than "functions with a slightly more convenient syntax that you can
define in /etc/profile without breaking shell scripts".</p>

<p>Hmmm, actually this may be an arg_list. If the global is a singly linked list
of pointers, then parse_word() has everything it needs to continue (and
even to clean up after itself), and then parse_line() can detect the
recursion. Can you actively attack the recursion? Yes, both redirects
and prefix assignments (which are allowed before the alias to be expanded)
can be quoted, which can be unterminated and require additional input:</p>

<blockquote><p>
$ Y=0; alias abc=$'Y=$((Y+1)) x="' def='abc ghi'<br />
$ abc<br />
&gt; " def<br />
&gt; "<br />
$ echo $Y<br />
2
</p></blockquote>

<p>And that is BROKEN IN BASH. (The bash man page says the same alias won't
expand twice, the increment is only in the abc expansion, it got expanded twice
because the decision about whether or not to expand it again got deferred
until the first alias had finished processing and got popped from the stack.)
So I guess I don't have to care about getting it right myself then.</p>

<p>Bash doesn't document that the ! operator is _also_ allowed
before an alias, along with prefix assignment and redirection. I'm still
salty about him being incredulous about not having recently re-read the
section of posix on tokenizing when my design DOES NOT TOKENIZE. It parses
and manages argv[] string arrays with a light dusting of metadata to cache
previously done parsing work. "That sounds like an implementation detail"
yes, in the bell labs version from 1976 written on and for a 16 bit PDP-11.</p>

<p>Of course NOW the rough edge is that the obvious place to put the list
traversal is in the loop (so when it hits the null terminator at the start
of the loop it pops the list and restarts from the next position), but
&lt;( and (( are only detected at the start of a word (I.E. _before_ the loop),
so an alias ending with a single quote or less than wouldn't combine with the
next character after the alias and would instead produce the separate &lt;
or ( operator, followed by a separate parentheses.</p>

<p>Nobody but me will EVER NOTICE THIS CORNER CASE. GAAAAAH.</p>

<p>Another rough edge: parse_word() has 3 explicit uses of "start" other
than the initial end=start assignment so "end" can advance through the string.
These are all essentially checks whether or not we've really done anything
yet, but when an alias expands to "" (or we otherwise start parsing having
fully consumed alias contents because it was 'alias abc='(x)' or similar
that naturally ended a word where the next alias character to examine
is the null terminator), then we pop and advance without actually having
consumed any bytes of input. I guess if (end==start) while we're popping
the alias list, move start? The caller needs to free this because the
"unmatched quotes = we need more input" case has to restart from the OLD
position.</p>

<p>Ok, maybe the new arg_list is NOT a global, I can do a new
parse_aliased_word() taking a third argument, and make a parse_word() wrapper
compatible with the original calling semantics that passes a null in for the
new argument. Hmmm, early and alias are never used at the same time, make
it parse_aliword() with two arguments and feed in (void *)1 for early,
and have the parse_word() wrapper just have the one string argument and
remove the extra , 0 from the callers using the wrapper. Which yanks enough
extra arrguments to pay for the wrapper, except the if () case to move it
back into a separate variable consumes the space again, but the SEMANTIC
difference is worth it. Less mental load on callers for the simple case.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#04-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[May 2, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#02-05-2025</link>
   <pubDate>Fri, 02 May 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Long <a href=http://lists.landley.net/pipermail/toybox-landley.net/2025-May/030722.html>ongoing thread</a> with Chet the bash maintainer.
I don't really WANT it to be a long thread,
but we're talking past each other and it's impolite to just stop replying.</p>

<p>Especially when he goes "didn't you read posix?" and the answer is
A) yes but a long time ago, B) I don't do lex/yacc style tokenizing so all
the stuff it has to say about tokenizing does not apply to my implementation.</p>

<p>I keep asking "why" questions and he answers "how". I can presumably
determine how myself by running enough tests and then waiting for
people to submit bug reports about what I missed, but I do not understand
WHY aliases still exist when we have functions, other than a slightly more
convenient syntax to declare them.</p>

<p>I've been handling redirection and variable expansion in the same pass,
and this seems to want redirections to be pulled out early but actually
processed later.</p>

<blockquote><p>
$ alias one='echo $BLAH'<br />
$ for BLAH in a b c; do &gt;$BLAH one; done<br />
$ cat a<br />
a
</p></blockquote>

<p>Empty variable expansions can also go before commands being executed, but
they can't here because they're not processed. Yet redirects and conditional
assignments aren't processed in this context either, they're just checked
for and ignored, and I don't get WHY. I can _see_ how.</p>

<p>Why put in extra effort to do the same work _twice_?</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#02-05-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 28, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#28-04-2025</link>
   <pubDate>Mon, 28 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Got another bounce message from the out of control german spam filter:</p>

<blockquote><pre>
&lt;mail@bernhard-voelker.de&gt;: host mx01.ionos.de[217.72.192.67] said:
    550-Requested action not taken: mailbox unavailable 550-Reject due to
    policy restrictions. 550 For explanation visit
    https://postmaster.1und1.de/en/case?c=r1102&amp;i=ip&amp;v=23.83.209.249&amp;r=1Mti2r-1uw0Us2BB9-010Cz6
    (in reply to MAIL FROM command)
</pre></blockquote>

<p>Sigh, I need to poke <a href=https://check.spamhaus.org/>check.spamhaus.org</a>
and really don't want to.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#28-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 26, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#26-04-2025</link>
   <pubDate>Sat, 26 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>My toybox development tree has several half-finished things in it,
and attempting to flush them involves completing them, so I'm looking
at tests/chmod.test to add -f -v -c tests and...</p>

<blockquote><pre>
# macOS doesn't allow +s in /tmp
touch s-supported
chmod +s s-supported 2&gt;/dev/null || SKIP=99 
rm s-supported
chtest +s "drwsr-sr-x\n-rwSr-Sr--\n"
SKIP=0
</pre></blockquote>

<p>Only test chmod +s if chmod +s succeeded? Sigh. Years ago people asked me
how they could help and I said "we need more tests" so I got tests I've
been trying to fix up ever since. Even tests need to be properly designed
to be testing something coherent.</p>

<p>So now I'm going: when they say mac fails is it mac _specifically_ or
are free/net/open/dragonfly BSD also impacted? Should the test be
the usual [ "$(uname)" == Darwin ] or will that introduce test failures
on something _else_ that hasn't been supporting +s all this time? (And honestly,
if they do is that info we want to hear about?)</p>

<p>Design work is usually the hard part. Implementing is easy.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#26-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 25, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#25-04-2025</link>
   <pubDate>Fri, 25 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>The debian-superh maintainer requested the kernel build switch from xz to gz
compression, and when I asked why <a href=https://lists.debian.org/debian-superh/2025/04/msg00006.html>he said</a>
it was because xz ran out of memory on native kernel builds. I typed up
a reply:</p>

<blockquote>
<p>My aboriginal linux sh4 native build setup, which natively compiled linux
from scratch under qemu, had a swap partition on a network block device.
That was the original reason I implemented nbd-client in busybox, and it's
why toybox has nbd-client and nbd-server.</p>
</blockquote>

<p>And then didn't send it because... I'm sure he already knows how to
do that and has chosen not to?</p>

<p>(Ok, the reason I submitted nbd-client <a href=https://lists.busybox.net/pipermail/busybox/2010-September/073311.html>to busybox</a> even though I'd left
busybox maintainership was I was doing native builds on the hexagon comet
boards for qualcomm, and wanted to leave them a procedure that worked with
"generic" tools (like busybox) rather than "my" tools (like toybox).
But I first _did_ it on qemu-system-sh4, because that board only had 64 megs ram
and C++ builds needed 128 megs on 32 bit targets and 256 on 64 bit. The
C builds generally worked fine, Linux started out on a 4 meg system and
Linus first implemented swapping because somebody who only had 2 megs
asked nicely. Even the 2.6 kernel wasn't THAT much of a pig. Yet.)
</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#25-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 24, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#24-04-2025</link>
   <pubDate>Thu, 24 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>Ok, I've got to admire the emotional manipulation in this spam, going
for the "switch from anxiety to relief" emotional manipulation of
dementia-addled geezers.</p>

<p>The subject "FBI HEADQUARTERS IN WASHINGTON, DC" (all caps!)
with a header about ANTI-TERRORIST AND MONEY CRIMES DIVISION and
then mailing address headers like postal mail used to have, and a first
sentence "We have finally completed an investigation with the help of our
Intelligence Monitoring Network system, your E-mail address was among the
email that Won the UK National lottery Award which you did not claim..."</p>

<p>And then going on to explain the scam about how the FBI caught someone
stealing uncollected lottery-you-never-entered winnings, which they
are now ready to transfer to the rightful owner as soon as you sign over your
banking info. You'd think nobody could EVER FALL FOR THAT, but
Altzheimers patients deep into <a href=https://www.ncbi.nlm.nih.gov/books/NBK536961/>confabulation</a>
feeling a sudden flood of relief from having their emotions jerked around
is EXACTLY who could be convinced that they'd entered a lottery they don't
remember entering, and their life savings give them deep pockets to drain
(or if nothing else, a fixed income means there's always _something_ to take).
As with all those weird infomercials for devices to help you put on socks
without bending over, they don't SAY it's aimed at end-of-life care patients
but if you weight the <a href=https://www.census.gov/library/visualizations/interactive/age-sex-pyramid-for-the-united-states.html>age sex pyramid</a>
by the <a href=https://www.empower.com/the-currency/life/average-net-worth-by-age>average
net worth by age</a> it's crystal clear where the motherlode of dumb money is.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#24-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 23, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#23-04-2025</link>
   <pubDate>Wed, 23 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<p>It's ironic that uranium glass is flourescent under ultraviolet light due to
the _chemical_ properties of uranium, so people value the pretty green glow
for reasons unrelated to the radioactivity. Radium watch dials are sort
of adjacent, in that the radium was mixed with a flourescent paint to
energize the paint and make _that_ glow. Between the two of them
this gave us the cultural cliche (a century or so back) that radiation glows,
but by the time you have enough of it do that you have
<a href=https://www.youtube.com/watch?v=e1aUaVNMTfc>bigger problems</a>.</p>

<span id=programming>
<p>Didn't quite get enough sleep last night, so my brain is of course reading
outbox.json as catbox.json.</p>

<p>I vaguely recall trying to convert scripts/mkflags.c to inline bash
shortly before the move out of Austin, and thought I had a script that did
the FLAG_x macros but didn't handle the optstr whiteouts. As long as I've
got help escaping with a ! syntax I thought I might as well do something
similar in lib/args.c, so I tried to dig up the generator for
generated/flags.h so I could yeet mkflags.c the way config2help.c went away.</p>

<p>Except... no, I <a href=https://landley.net/notes-2022.html#17-05-2022>misremembered</a>.
(Which is unsurprising considering I was packing to move while doing that,
and then collapsed into a ball of depression and anxiety with the looming
re-election of the Oldest President Ever against the Unindicted Co-Conspirator
that Pelosi and Schumer made sure would be unimpeded from running again,
focusing instead of blocking "the squad" from any real power. I DID NOT WANT
TO BE RIGHT ABOUT THAT.)</p>

<p>Of course a disgusting thing I could do is stick a function in lib/args.c
to emit flags.h. I could even have a toys/build directory with commands
like "instlist", "kconfig", and "mkflags" that... oh that's disgusting.
Turn all the scripts/*.c files into toybox commands used to build toybox.
I already have scripts/recreate-prereq.sh and scripts/single.sh that...
Oh that way lies madness. I probably should not do that.</p>

<p>But it WOULD mean that there's only one instance of the lib/args.c
pluming parsing the option strings, and that would be what generates the
FLAG macros. And scripts/install.c is already a strange hybrid including
generated/config.h and lib/toyflags.h and generated/newtoys.h after defining
its own NEWTOY and OLDTOY macros. And kconfig is halfway to being a
generic-ish command line utility already...</p>

<p>Telling projects like buildroot that if you want a generic kconfig
replacement you should clone toybox and "make kconfig" seems a bit...
Well, compared to any of the disgusting things gnu pulls on a regular basis
that's... Oh ouch. That's smelling like a local peak in the solution
space. Once again, I do not WANT to be right.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#23-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 22, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#22-04-2025</link>
   <pubDate>Tue, 22 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Implementing chmod -c (going through some very old
<a href=https://github.com/landley/toybox/pull/150>requests</a>)
I used a dirty trick where I replaced stderr with
the read end of a pipe. That way I don't depend on /dev/null being present,
and if I used the WRITE end of the pipe there's the possibility the pipe could
fill up on a chmod -R or similar. The read end isn't writeable and will just
silently discard each write (with an error we don't check for).</p>

<p>It's one of those things where I want to add a comment explaining it, but
also want the code to be simple and obvious and thus don't want to go off on
an unrelated tangent explaining a Linux thing, not a chmod thing...</p>

<p>Hit a fun little gcc bug implementing that TOYFLAG_BIGHELP
<a href="#10-04-2025">idea</a>: if you #include the same file more than once
(such as the NEED_OPTIONS trick I copied for NEED_TRIMHELP in main.c),
the include stack it gives you is from the FIRST place that file was #included,
so it's really hard to tell what it's complaining about when it does the
"suggest parentheses around &amp; and |" warning if you remove the parentheses
around "flags" in the #define NEWTOY for trimhelp. The warning seems to
reach back in time and make an EARLIER #include fail, because it's reporting
the wrong line number for the #include from main.c, because there can be only
one.</p>

<p>I have encountered a problem with toybox's help text format: I want
to put <b>for i in /sys/class/*/*/dev; do echo -n "$(basename $(dirname $i)) "; cat $i; done</b>
as an example shell snippet in mknod's help (to show all the devices currently
available in this kernel) but that has /* and */ in it which are C comment
indicators. The help text is in the C source file, which means it's inside a
big C comment, and the in-band signaling would END the C comment. I have not
implemented an escape syntax to break those up. Kinda not worth it for one
instance? Hmmm...</p>

<p>Dialed in to Tim Bird's linux boot time optimization SIG meeting. Of course
nobody's done anything on compile time elimination of unnecessary printk()
strings. (One of the largest size savings in Matt Mackall's old -tiny tree
back before there was no such person.) Nobody's done anything about
adding a CONFIG_SIMPLE_DMESG where we can get the old simple string ring
buffer back without wasting 5 times as much space on gratuitous metadata as
on the actual logged strings. I mentioned my fdpic for ssh with mmu patch
but nobody was interested. At one point we sauntered past "the fast way to
boot 15 years ago was to abuse the suspend-to-ram and live migration stuff
(kind of like
<a href=https://github.com/checkpoint-restore/criu>ciru</a> for VMs instead
of containers</a>), and several other people on the call chimed in
"oh yeah, we've done that too" but there's no documentation on it and
nothing went upstream, and of course it was dropped and we moved on...</p>

<p>*shrug* The usual. Linux kernel development's toxic enough nobody
really wants to engage with upstream anymore (even BEFORE Linus decided
that what the kernel really needed was a bunch of rust people waging an
inquisition against every heretic who refuses to convert), and the Linux
foundation very effectively drove away the hobbyists who used to fill in
the gaps, leaving a bunch of employees uninterested in working on anything
that isn't THEIR job.</p>

<p>I guess this is what the end of the enlightenment felt like. No longer are
"gentlemen of leisure" self-taught from books and going out into the field
to advance the state of the art, now you need a bunch of certifications and
permissions for tenured university factulty to listen to you.
Sadly, <a href=http://landley.net/writing/#3waves>as predicted</a>, although
computer programming speed-ran that in a few decades. (I refuse to call it "computer
science" when you can't reproduce stuff from first principles in a lab,
your unpublished trade secrets made once and then copied exactly by rote
are computer alchemy. So many of the shared libraries people pull in are
basically a digital form of Ringer's Solution, who cares WHY it works,
just do it...)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#22-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 21, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#21-04-2025</link>
   <pubDate>Mon, 21 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>So <a href=https://github.com/landley/toybox/issues/548>bug report du
jour</a>
about the build breaking because getentropy() isn't found.
I'm already checking for the header's existence. Unfortunately there's no
#ifdef equivalent for function prototypes, so "header exists but doesn't
provide the definitions we need" is hard to spot/fix without a compile
time probe, and I've been trying to move away from those.</p>

<p>This is actually an android/bionic issue, providing the header but
not a function that should be in that header. Which Android already fixed,
but API 28 came out in 2018 and our <a href=https://landley.net/toybox/faq.html#support_horizon>7
year time horizon policy</a> says we probably SHOULD still support the old
stuff for another year or so. For Android specifically I've always let Elliott
handle that, but now somebody hit a thing. (Trying to build for an android
emulator, which maybe I should look more into because it would be nice to
be able to test android stuff on my laptop more thoroughly. A full
AOSP build on this laptop is many hours, and there's no obvious
"make baseline" that gives me a command line version without the gui because
Android generally isn't a server OS.)</p>

<p>That said, there's probably some sort of "#ifdef ANDROID &amp;&amp;
API_LEVEL&lt;28" I could add as a second wrapper around the existing #ifdef.
A quick grep of the NDK-r27 is finding __INTRODUCED_IN(__api_level) and
include/android/api-level.h:#define __ANDROID_API_J_MR1__ 17 and similar.</p>

<p>It would be nice if there was an Android Programmer's Manual. I was SO
spoiled by the Commodore 64 Programmer's Reference Guide in my early teens,
that thing was a masterpiece. Half the reason I got into unix (Rutgers
transitioned its "each costs as much as a car" workstations from SunOS to
Solaris while I was there, and then there was Linux)
was that the OS/2 EMX package, a port of gcc+glibc to OS/2 circa 1992,
had a glibc reference guide (basically the man 3 pages glued together)
that I printed out on clam.rutgers.edu's printer and sewed together with
black thread from mom's sewing kit to make a sort of book out of it.
Back at timesys in 2006 I printed out the tinycc source and the
bash man page in separate 3 ring binders, to read on my daily bus commute.
Yeah, old school, but old school worked for a reason. Survivorship bias:
the stuff that didn't work isn't even remembered, and thus isn't "old school".</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#21-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 20, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#20-04-2025</link>
   <pubDate>Sun, 20 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>There's some tension between commands being self-contained and plumbing
being available in lib/*.c. In addition to the new blake3 stuff I need
to wire up, the sha3sum plumbing is in its own command file, not in the
newer lib/hash.c.</p>

<p>It's a bit like how toys/other/bzcat.c has the bzcat extract plumbing,
but lib/deflate.c has the gzip plumbing. (Because zip/unzip also needs to
use that, but only bzcat and friends use bzip2. Which implies that if
I get around to mksquashfs, it'll only support gzip and not newer algorithms,
but that was already the case because I'm only implementing the compression
side of gzip, the others are decompress only. Deflate is the 80/20 of
compression algorithms: it doesn't produce the smallest result for long
term archiving but it's way better than nothing, churns through data
rapidly, takes very little memory, is trivially parallelizeable if you just
"grab the next 4 megabytes of input and fling it to a child process,
rinse repeat", and works as a streaming algorithm without needing a minimum
input buffer size which is why things like ssh -C use it.</p>

<p>But in this case, now I know that man 5 crypt has different information
than man 3 crypt, I want all the hashing algorithms available to the
new lib/crypt.c. Hmmm, possibly I should rename lib/hash.c to lib/crypt.c
when adding the actual crypt() function...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#20-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 19, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#19-04-2025</link>
   <pubDate>Sat, 19 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Second big protest. Less well-organized than the first. I mentioned I
couldn't figure out when it was supposed to start. (The 515151 website is
like meetup, on tuesday it only wanted to tell me about protests happening
wednesnay, not the supposedly big thing for the weekend. Every event is
equally important, no matter how small, and unless I gave it personal
identifying data it wanted to tell me about things 50 miles away with an
expected attendance of 3 people because that was up next chronologically.)</p>

<p>The day of, Fade found out "when to show up". (Possibly from a coworker?
Dunno, I'd griped at her in passing and she came back with the info later.)
Last time it was noon, this time it was 1pm. Except that was still wrong:
the 1pm thing was for a march far away ENDING at the capital at 2pm.
So we left early (because the green line had melted last time) and got
on fairly lightly attended trains with only one other person having
a sign for the rally (last time there were like 50), and then we showed up
to the capital which had like 5% of the crowd of last time. So that was
disheartening.</p>

<p>We stuck around anyway. Several of the people who did show
up had brought dogs, and the music was good: Dolly Parton's "9 to 5" and
the Artists Formerly Known as Dixie Chicks' "Goodbye Earl" and one where
the chorus was "we have the guillotines". More people did trickle in over
time, and then when the march showed up that tripled the already increased
crowd size, so in the end it was decent turnout. (Still not quite as big
as last time, but that was right after the tariffs went in and they did a
MUCH better job getting the word out, and a lot of the people who'd marched
went straight on home when it ended. And there _are_ a bunch of other protests
happening, this time we got flyers for like 3 different ones each claiming
to be "the next protest", except on different days and for different causes.
Two people were holding a "Legalize nudity" flag but when I asked them they
didn't seem to know what AANR _was_, nor where any of the local clubs were.
They'd started their own group in 2017. Good for them I suppose.
The guy with the hammer and sickle flag over his booth booth trying to hand
pamphlets about marxism _did_ admit that trying to reclaim communism from
Putin using Joseph Stalin's symbol might not be the most effective approach
to convincing people "hey remember FDR's New Deal? Let's do more of that,
maybe add some of that Basic Income Richard Nixon tried to pass in 1970."
I mean DUDE, seriously...)</p>

<p>By the time the marchers showed up, both the marchers and the people
who'd been waiting for them were pretty tired, and even before they showed
up the guy with the microphone kept trying to get the crowd to chant in
unison by including evil bastards' names in the chants (imagine a 1930's
german anti-nazi rally where you try
to get the OPPOSITION to yell "hitler" and "gobbels" repetedly in unison.
Please stop, you're making us uncomfortable.) Right after a "vietnam veteran"
was given the microphone to "read his poetry" (the poems seemed to imply he
was native american, but if the introduction mentioned it I missed it), and
then the same guy went through his uninspiring name-and-shame chants again
the crowd was breaking up and I left. (People drive a hundred miles to hear
AOC and Bernie speak. This one would have gone better if they kept the music
playing and stopped trying to have people speak.)</p>

<p>One the way back I stopped by the place that'd had checkerboard tea
(technically it's "Loire River assam") last time, but they hadn't restocked
since I went back and bought the 8 cans had last week. (I drank all but one of
them since, it's good stuff.) I asked if they were still carrying it or if
tariffs had happened (they took the sticker off the empty shelf where it had
been), and after a couple referrals talked to a guy who said they never knew
when that was coming in. Which is pretty much what the HEB people said back
in the day: it's a brand from Taiwan and apparently shipping stuff from
Taiwain is... irregular.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#19-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 18, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#18-04-2025</link>
   <pubDate>Fri, 18 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I want a "yes" variant that can output controllable repeated data, because
often I need an endless stream of spaces or plus signs or some such, or want a
stream of NUL bytes in a context where I'm not sure /dev/null is mounted.</p>

<p>Alas "yes" is the wrong tool for this because A) it can't output NUL bytes
(no \0 parsing, the shell can't do it because argv[] is NUL terminated C
strings), B) there's no way to tell it NOT to stick a newline between each
output cycle.</p>

<p>The tool that CAN output NUL bytes and write data without a newline is
printf, so had an "add printf -y" todo item, and at a quick glance it looks
straightforward (it's already got an endless loop to consume argv[], just
add an if (FLAG(y)) to reset argv instead of breaking out at the end. Don't
see any obvious memory leaks...)</p>

<p>And look:</p>

<blockquote><pre>
$ printf -y
bash: printf: -y: invalid option
printf: usage: printf [-v var] format [arguments]
</pre></blockquote>

<p>Except...</p>

<blockquote><pre>
$ /usr/bin/printf -y
</pre></blockquote>

<p>Once again, gnu/dammit inconsistently shipping multiple incompatible GPLv3
implementations. Hmmm...</p>

<blockquote><pre>
$ /usr/bin/printf --help
Usage: /usr/bin/printf FORMAT [ARGUMENT]...
...
Full documentation &lt;https://www.gnu.org/software/coreutils/printf&gt;
or available locally via: info '(coreutils) printf invocation'
</pre></blockquote>

<p>AHA! So it's ALREADY not safe to call even the non-bash printf for random
"$VAR" strings. So adding (only parsed before the pattern) isn't a big lift.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#18-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 17, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#17-04-2025</link>
   <pubDate>Thu, 17 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I need a cron job that rebuilds all the mkroot targets using current toybox
git and linux git running the result under current qemu git. It has to
not only do it three times (updating toybox, linux, and qemu between each
run) but bisect when a target fails between the last known good version of
the repo it just updated and the current one, and then probably email me
an infodump with the failure analysis. (Commit X of package Y caused the
mkroot build/test log for these architectures to fail, here's the relevant
log(s).)</p>

<p>There's a question of rebuild granularity: if only one target fails then
qemu doing "./configure --target-list=$ARCH-softmmu" would speed the rebuild
up quite a lot, same for toybox "mkroot/mkroot.sh CROSS=$ARCH: building just
the one arch when bisecting linux kernel issues. But when it's a generic
issue affecting multiple architectures, that would be more work by bisecting
multiple architectures for basically the same issue. In theory, on an average
night it should all just work, and whether I'd set this up on j180 (32-way
x86-64 box in japan) or finally get the orange pi 3b setup (which is an arm64
machine with 8 gigs ram and something like 4x cpu), either way it should kick
off something like midnight and run unattended.</p>

<p>And there's the problem of what to do if I haven't fixed yesterday's issues
yet. The build failing again for basically the same reason isn't useful
to bisect, although marking a package "bad" and bisecting the other two
against the last known good version might make sense. I'd have to manually
clear the "bad" flag. Or it could just try current git once and notice it's
working again and clear it itself, but otherwise NOT bisect?</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#17-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 16, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#16-04-2025</link>
   <pubDate>Wed, 16 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>Ok, I admit I'm impressed by the emotional manipulation in this spam, going
for the "switch from anxiety to relief" emotional manipulation of
dementia-addled geezers. It's pure evil, but I admire the craftsmanship.</p>

<p>The subject "FBI HEADQUARTERS IN WASHINGTON, DC" (all caps!)
with a header about ANTI-TERRORIST AND MONEY CRIMES DIVISION and
then mailing address headers like postal mail used to have, and a first
sentence "We have finally completed an investigation with the help of our
Intelligence Monitoring Network system, your E-mail address was among the
email that Won the UK National lottery Award which you did not claim..."</p>

<p>And then going on to explain the scam, how "the FBI" caught someone
stealing uncollected lottery-you-never-entered winnings, which they
are now ready to transfer to the rightful owner as soon as you sign over your
banking info. You'd think nobody could EVER FALL FOR THAT, but
Altzheimers patients deep into <a href=https://www.ncbi.nlm.nih.gov/books/NBK536961/>confabulation</a>
feeling a sudden flood of relief from having their emotions jerked around
is EXACTLY who could be convinced that they'd entered a lottery they don't
remember entering, and their life savings give them deep pockets to drain,
or if nothing else, a fixed income means there's _something_ to steal.
As with all those weird infomercials for devices to help you put on socks
without bending over, they don't SAY it's aimed at end-of-life care patients
but if you weight the <a href=https://www.census.gov/library/visualizations/interactive/age-sex-pyramid-for-the-united-states.html>age sex pyramid</a>
by the <a href=https://www.empower.com/the-currency/life/average-net-worth-by-age>average
net worth by age</a> it's crystal clear where the motherlode of dumb money is.</p>

<p>It's a pity it's also the motherlode of dumb political power, ever since
the "clean cup move down" tea party initially just intended to shift the
overton window snowballed into something the real grifters could weaponize.
As with the spammers inventing crypto to pyramid scheme younger marks,
they're trying VERY HARD to seem like their ecosystem is bigger than just
addled geezers, but once enough dementia droolers die off what's left is
unlikely to be self-sustaining.</p>

<p>Sadly, we've got another decade of Booming. And even that won't entirely
fix it: the decline of leaded gasoline is fairly recent. Richard Nixon
created the EPA in 1970, which mandated catalytic converters (requiring
unleaded gasoline) on all new US cars sold starting in 1975, which rapidly
<a href=https://www.bts.gov/archive/publications/national_transportation_statistics/2002/table_04_46>reduced US lead emissions</a> into the atmosphere
(173 tons in 1970, 131 tons in 1975, 61 tons in 1980, 19 tons in 1985,
11 tons in 1986, 4 tons in 1987...). Although "amount in the environment" (and
in people's bodies) trails emissions by a few years so people were still being
poisoned by this crap through the early 1990s (although not NEARLY as bad as in
1970). Which means even people born in 1970 got a pretty bad pediatric and
chronic dose.</p>

<p>I was born in very rural florida upwind of orlando, with swamp and
the gulf of mexico upwind of me for hundreds of miles. Then we moved
to Kwajalein in the middle of the pacific ocean (freshest air on
the planet) when I was 5 and stayed there until I was 10, and by the time
I got back to the states emissions had already fallen around 80%. But I
could still tell New Jersey was actively making me dumber, I just didn't
understand why at the time. I did not escape unscathed, and do not expect
to enjoy a productive retirement.</p>

<p>If Gen Z seems way smarter than the Boomers and Gen X it's because
they ARE, due to massive pediatric and chronic lead poisoning.
(No, microplastics don't count. Panic all you like about that, it's not
the same order of magnitude. And the more "micro" it is the faster it does,
in fact, chemically break down. If it can burn, it will oxidize over time.
That's how chemistry works. More surface area means faster activity,
and that's BEFORE nature takes notice of the <a href=https://www.sci.news/biology/ideonella-sakaiensis-bacterium-can-break-down-metabolize-plastic-03693.html>giant
piles of resources</a> we've <a href=https://2050.earth/predictions/the-garbage-patch-is-shrinking-because-of-bacteria-but-do-we-have-to-stop-them>strewn about the place</a>.)</p>

<p>But the Boomers got by far the biggest dose and thus got dumbest fastest
as they went senile, and hopefully Gen X will on average stay lucid a few
years longer than a corresponding Boomer, and thus spend fewer man-years
voting fascist than an equivalent boomer (especially since there's fewer
of us), and then millennials may wind up the age of Trump or Pelosi before
they become fully toxic...</p>

<p>*shrug* I cling to hope where I can find it. The Boomers will die,
and the oldest of them are the worst of them. The younger half don't
even want to be <a href=https://en.wikipedia.org/wiki/Generation_Jones>called
Boomers</a>. (And yes yes I know, hash tag not-all-boomers.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#16-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 15, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#15-04-2025</link>
   <pubDate>Tue, 15 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=health>
<p>Spent today either curled up in a ball from stress, or with
an upset stomach. "Intestinal distress that reads as free-floating anxiety"
is a thing I acquired from one of my bouts of Covid over the pandemic,
and it is one of my least favorite states. It's a bit like how I never USED
to get visual migranes, until that <a href=notes-2013.html#06-04-2013>one bout
with lidocane</a> in 2013 and then suddenly my body had
<a href=notes-2013.html#23-11-2013>learned a new trick</a>. So now that's
a thing that occasionally happens.</p>
</span>

<span id=politics>
<p>It doesn't help that the mastodon server I have an account on has been down
all day. Every time that happens I wonder if mstdn.jp permanently went away
and I didn't hear about it because the announcement was on one of the
japanese-only channels I STILL can't read. And of course the youtube algorithm
has decided I need to see every "I know how we said last week was that
THIS IS THE TIPPING POINT INTO FASCISM? Well what happened THIS
week is DEFINITELY it! Yet again! Somehow! We only have to be right once!"
video copying its strategy from the climate change people. (Yes this is
terrible. You convinced me some years ago we were already totally fscked.
I notice you are saying this from the comfort of a chair in an air conditioned
office that does not appear under immediate seige, and you are not offering any
solutions or suggesting a specific course of action beyond phoning up
Ilhan Omar's voicemail to let the black muslim woman know she should be even
more alarmed than she already is, which I suppose is still an
improvement over calling Ted Cruz's voicemail to let him know he's a bad
person: he knew, he just didn't care as long as it got him money and power.)</p>

<p>The people who organized the protests on the 5th said the next ones would
be on the 19th. They didn't say it at the time, but there were some rumblings
later. Except when I tried to look up any details there were none. At all.
Not even from their official website. Just... maybe wander down to your state
capital (around noon I guess? That's when last time started...) and see if
anybody else shows up. Wear sunscreen and bring a beverage, because there was
EXACTLY one food truck last time that wanted $7 for french fries.</p>

<p>The point of torches and pitchforks was people coming after the physical
safety of their oppressors. France did not remove Louis XIV from office
via changes to tax policy. The american revolution didn't JUST dump tea
into the harbor. (And the rich white slaveowning cowards who did it dressed
up as native americans so the british would double down on the ongoing racist
genocide instead of blaming THEM, how is it a protest if you hide why you're
doing it...) A couple months back South Korea rose up and literally grabbed
the guns out of the hands of their army. <a href=https://www.youtube.com/watch?v=k8KB2mhsDTY>Almost</a>
nobody around here appears ready for even peaceful direct action. I'm honestly
unsure what the "down with this sort of thing then" middle ground is supposed
to accomplish against somebody who cheats on all cylinders to pack the supreme
court and then ignores even them, backed by a senate (the part of american
politics where land DOES vote, that's literally what it's for) which
has abdicated all responsibility, who are using ICE as america's SS to
grab people off the street and we respond with strongly worded letters to the
editor.</p>

<p>The Bernie/AOC rallies drawing
five figures each stop (they got like 8 thousand people in MONTANA, and
I didn't think it even HAD that many) serve an excellent purpose if the
stress they cause Nanci Pelosi and Chuck Schumer hasten those assholes'
deaths by even 5 minutes. (Which is the only way either is leaving office.
I don't really blame the fascist 27% of the population for this: they're
terrible but they've always been there and didn't CHANGE, the anti-abortion
loons were asassinating medical
practitioners <a href=https://en.wikipedia.org/wiki/Anti-abortion_violence>50
years ago</a>). And it's not ENTIRELY the fault of the lead-addled altzheimers
patients fueling all the elder abuse scams (hence why the phone rings off the
hook and my spam filter has gotten hundreds of blindingly obvious theft
attempts each day for 20 years). Both (overlapping) groups are horrible in
the way rabies is horrible; they have no agency and could not have decided
to do or be better. Measles isn't responsible for the rise in measles,
Brain Worm Guy is. I don't BLAME
hurricane Katrina for what happened to New Orleans. What CHANGED is
Pelosi and Schumer dicking around 4 years after the capital was stormed
on January 6, doing nothing whatsoever to impose any consequences on orange
man bad despite the target rich environment. They did to him what he's doing
to the Dictator of Equador, "clearly I have no power over you, I've fallen and I
can't get up".</p>

<p>Pelosi and Schumer (D-Goldman Sachs) focused all their efforts on stopping
people like Bernie and AOC who noted that coming out of the previous Gilded
Age, the choices were fascism or the New Deal, and went "here's a new new deal,
let's have a Roosevelt (Teddy or FDR, take your pick) instead of a Mussolini
this time around please..." And Pelosi and Schumer went "over our dead bodies,
no literally, ask Dianne Feinstein and Ruth Bader Ginsburg".
Pelosi's personal investments have beat the stock market soundly.
Biden sent a strongly worded letter to the editor but not executive orders.
The supreme court ruled the president was not liable for breaking the law as
part of his duties, and Biden did absolutely nothing with that power when
it was HANDED TO HIM. Instead of "be careful what you wish for", Biden,
Pelosi, and Schumer teed it up for the fascists. THAT is what actually
CHANGED. Ronald Reagan was trying to do the exact same things the first
trump administration tried, George Carlin did a
<a href=https://youtu.be/og9DV0Si8bs>whole set about it</a> in 1988.
(Or McCarthyism and the Comstock Act a generation before then.)
What's different this time is the democratic gerontocracy SURRENDERED.</p>

<p>Honestly, orange man bad's strategy has been "double down every time
you lose" ever since he was a local new jersey real estate swindler back before
he bankrupted his first casino. George Plimpton mocked him on the Disney channel
when I was still in grade school (drumpf called himself "The Donald" back in
the 80's and Mousterpiece Theatre referred to Donald Duck as "The Donald"
as a play on that). He got on the Forbes 500 list by pretending to be
his own assistant and lying to the article's author on the phone
(there are literally audio recordings of this online because the journalist
taped his conversations to ensure he quoted accurately), then used his position
ON that list to get bank loans. When his father died he stole all his
siblings' inheritance (by making himself the trustee of the estate and
then draining it despite what the will said). By the time he ran
through that money the soviet union had collapsed and he could
get into the "money laundering for Russia" business. That's why he had
so many bankruptcies, yet kept getting new loans. Up until the Mortgage
Crisis in 2008 the regulators didn't think to scrutinize people who claimed
to have lost ALL their money, because hhow do you get rich by going bankrupt?
So all you had to do to launder money was "borrow" a bunch of dirty money
from an oligarch, send 95% of it back by "buying" stuff from the people you
"borrowed" it from, then declare bankruptcy to make the "debt" go away.
The launderers even got a tax writeoff for their "loss". THAT is why he could
go bankrupt so many times and still have oligarchs lining up to loan him money
through obscure eastern european branches of Deutsche Bank.
(I could sprinkle all this with a bunch of supporting
<a href=https://www.theguardian.com/business/2019/apr/17/deutsche-bank-faces-action-over-20bn-russian-money-laundering-scheme>links</a> but...
none of this is SECRET. They don't even bother DENYING most of it. As with
the "grab 'em by the pussy" tape, it's the mob standard "yeah, waddya gonna do
about it?") That laundering is how he became "Agent Krasnov", a useful idiot
who was easy to steer and surround with
<a href=https://en.wikipedia.org/wiki/Melania_Trump>russian</a>
<a href=https://www.americanbar.org/news/abanews/aba-news-archives/2019/03/manafort-sentenced-to-47-months/>agents</a>
because he didn't CARE what anyone else's real motive was as long as he got
what he wanted out of the immediate transaction. (And that was
before his senility robbed him of object permanence, just like Reagan
before him. The right wing loves confidence, and the one thing more confident
than a confidence trickster is a nouveau riche white male geezer who literally
can't remember ever having been wrong about anything, because of the altzheimers.
The right wing role model is <a href=https://en.wikipedia.org/wiki/Mr._Magoo>Mr.
Magoo</a>.)</p>

<p>The fact he kept running out of money ANYWAY is on him. 90% of the
consequences he's ever faced were self-inflicted, because he was incompetent
BEFORE he went senile. And yes he's already deep into dementia (progressive
supranuclear palsy): the reason his father got diagnosed with altzheimers
at 86 was he could no longer remember his own birthday. That's not the START
of the problem, that's just when his wealth and power and the layer of
protective suck-ups in deep denial could no longer HIDE the fact that
he wasn't functional even as a figurehead with an entourage trying
to carry out his every whim. The white house is the ultimate enabling senior
care facility, which he is well aware of. As they say,
<a href=https://thehill.com/homenews/campaign/4407287-trump-shares-white-house-senior-living-ad-trolling-biden/>every accusation a confession</a>.</p>

<p>Anyway, it's probably just digestive trouble.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#15-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 14, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#14-04-2025</link>
   <pubDate>Mon, 14 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<p>Called the Austin tax lady and got her to file an extension for us.
Fade said one of her coworkers had a recommendation for a local Minneapolis
tax person, but we just didn't get our act together in time.</p>

<span id=programming>
<p>Got the new scripts/kconfig.c writing out a reasonable defconfig that diffed
the same as the old one (except for the header comments), but changing the
build plumbing over raises the question of what should live where. Right
now kconfig/Makefile (which I wrote to drive the ported plumbing) is
handling all the config targets and help text, and this is the one area
where the Makefile ISN'T a trivial wrapper around a scripts/blah.sh giving
you the option to NOT use make. I already have a scripts/genconfig.sh creating
generated/Config.in and generated/Config.probed, and logically I could add
allyesconfig/allnoconfig/defconfig targets to it.
(And the macos/bsd/android defconfigs targets would be autodetected by
genconfig.sh using cc macro checks. I still need to teach all this to
read an existing .config and do the miniconfig thing.</p>

<p>But the new kconfig binary is _also_ writing out generated/help.h which used
to be done by a different special purpose binary (scripts/config2help.c),
and I switched over the scripts/make.sh plumbing that was doing that to build
the new binary and run it (kconfig -h). And
now that kconfig is writing help.h probably scripts/genconfig.sh should just
write out generated/help.h when it runs? Now that there's one binary
(generated/unstripped/kconfig) producing all the various types of output.</p>

<p>Yesterday's comment about menuconfig wanting to use "less" plumbing (and
"watch", and "nano", and...) out of lib/*.c... Right now this new kconfig
isn't pulling in any lib/*.c code. I wrote a new strany(), and am using
the non-x malloc() and strdup() and friends because if kconfig segfaults I
really don't care. (You'd pretty much
have to be running it on a nommu system for that to happen anyway, which
doesn't seem like a common use case. Even though we _did_ get jcore's gcc
self-hosting! (There's an <a href=https://landley.net/bin/toolchains/25-03-2024/sh2eb-linux-muslfdpic-native.sqf>sh2eb-native compiler</a>
which I have run on turtle, although not recently. Yes I distribute the
native compilers as squashfs images because that's what mkroot needs to
do native builds, there's an unsquashfs that extracts
them like an archive if you don't want to mount it.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#14-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 13, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#13-04-2025</link>
   <pubDate>Sun, 13 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I got <a href=https://github.com/landley/toybox/pull/546>poked</a>
about a fix for a bug in the old kconfig binary from the dawn of time,
which was inherited from my tenure at busybox, where I'd copied
it from the 2.6 kernel (replacing the even older snapshot Eric Anderson
had <a href=https://git.busybox.net/busybox/commit/?id=c9f20d9fb93c>copied
via uClibc</a>).</p>

<p>I've mostly turned down similar bug reports in the past because I don't
want to touch the legacy gpl code cordoned off in its own subdirectory,
I want to _replace_ it. And I am now doing so. But turning down this bug
report does mean I need to prioritize getting a replacement menuconfig in
before too much longer. (Probably an endless scroling version rather than
a modal descent into menus sort of thing. Linux may have ten nested menu
levels that would go off the right edge of the screen without resets,
but the total indentation level in toybox isn't that deep. I probably don't
even need to implement scrolling right (at least not quite yet). In theory
that plumbing should be part of less (and would have been part of my vi
implementation if I'd gotten to do one. I should do a "nano" or something...)</p>
</span>

<span id=donotwant>
<p>The recurring rabid spam filters false positiving on landley.net do make my
own manual spam filtering a touch frustrating, because "your email is borked"
is no longer a category I can delete without reading the first line of.
The zillion senior health scams (Deserts that fight diabetes! "Inch boosting
jelly"! One simple trick to restore eyesight!) and uber-generic "your package
is ready for pickup, don't ask what or where" and "we would like to purchase
whatever your product is" I can still read with the D key. (They're back to
saying that "Mr. Bill Gates" and random african banks are trying to give away
money, I guess orange man bad has sufficiently reasserted itself
even among the drooling vegetable crowd. At least the ones that still have
any money.)</p>

<p>But the endless flood of email hijack attempts have a small
sliver I need to glance at the first line of, and it's not the time this takes
that I mind (still a fraction of a second), it's that there's a nonzero chance
I'll miss a real report about spam̈haus̈ du jour̈ categorizing my last name as
sexual innuendo or some such.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#13-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 12, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#12-04-2025</link>
   <pubDate>Sat, 12 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>And it's back. <a href=http://toot.mirbsd.org/@mirabilos>Mirabilos</a>
(the mksh maintainer) <a href=https://mstdn.jp/@landley/114328167082809753>informed me</a>
that some european anti-spam DNS servers(?) don't resolve "landley.net"
which is presumably yet another manifestation of the same issue that was
false positiving ublock.</p>

<p>I made a hammer in 2013. Somebody made a rootkit using
my hammer, which left hammer marks on it (because old gcc was dirty and leaked
crap into the binaries it built). Lazy antivirus writers used the hammer mark as
a sig for the virus. Then further laziness genericized that to blame me,
personally.</p>

<p>(It was something like either gcc 4.2 or binutils 2.17 added the
compile-time $PWD where the compiler got built/installed into the
<a href=https://en.wikipedia.org/wiki/Rpath>library search path</a>,
so even though I made <a href=https://github.com/landley/aboriginal/blob/master/sources/toys/ccwrap.c>a wrapper</a> to make the compiler run from any directory
you extracted the binaries into, it still leaked "/home/landley/someworkdir"
into the resulting ELF files _that_ built. And when some virus writer downloaded
my toolchain, Witchsmeller Pursuivant went "oh look, a unique
string I've never seen before! That must mean virus! Of course I won't google
it or anything," and I got blamed.)</p>

<p>I vaguely recall that ublock inherited this mistake from some german spam
filter house, which I've never been able to talk to because A) ich nicht
sprecht keine deutch (got an F on it in high school, did ok the first year
then remembered NOTHING after summer break, and no it did not "come back"
as the new year progressed), B) they're high
on their own supply so if you're in their spam filter they can't receive email
from you (nicely circular). I dunno if the recent gitlab whitelisting was
at the ublock level or the people ublock got it from.</p>

<p>The sad part is if you host stuff on big services like faceboot or
<a href=https://mastodon.social/@JuliusGoat/114324937200698001>substack</a>
you don't run into this. Nobody's going to block @gmail.com. It's trying to
do the small independent with an rss feed thing that you face a constant
stream of low-level harassment FROM THE PEOPLE WHO ARE NOMINALLY ON YOUR SIDE.
Purity culture strikes again. Big tent? No: cleanse the flock, keep the infidel
out... Sigh.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#12-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 11, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#11-04-2025</link>
   <pubDate>Fri, 11 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=health>
<p>I thought I could work out a good morning laptop schedule where I go to the
apartment front office until they start mopping, then pack up and head to fresh
thyme and use the tables there (with the price of admission being a $2 box of
their hot food area's chicken strips), and thus stay out and away from Everbark Hysteridog,
Loudest of His Line until at least noon. (Fade doesn't THINK he barks
when he's locked in the bedroom with nobody to hear him. It's one of them
"if a tree falls on a florist, does he make a sound" things.) Alas, the mopping happens between
9am and 9:30, and the chicken strips are never
out before 10am and when I was there today they still weren't out at 10:30
when I gave up waiting. (Sitting at a table without having bought something
seems rude: capitalism has eliminated "third places" that you can just go
unless I want to spend $2 each way on the green line to reach a library.
The apartment's front office is something my rent pays for access to, like
the tiny little gym area.)</p>

<p>I thought maybe I could pace around the stadium working on my daily 10k
step goal in between, but my cataracts have gotten bad enough that trying
to watch anything with the sun up, even in shade, is eyestrain city.
(I envy people with access to non-US healthcare. Yes I have health insurance.
No I <a href=https://www.youtube.com/watch?v=e9LJh81n_zA>don't trust it</a>,
it's just a saving throw against poverty when you wind
up in the emergency room, it doesn't help for luxury bones like teeth or
optional surgeries like being able to read for more than 10 minutes at a
time.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#11-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 10, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#10-04-2025</link>
   <pubDate>Thu, 10 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Alright, how DOES .config file loading work? The "Config.in" files define
a tree of data structures, and then .config applies state to them, but
there's dependencies in there. Dependencies are MOSTLY later symbols depending
on earlier symbols (that's how indentation is handled in menuconfig, a
symbol that depends on the symbol before it gets indented), but a symbol can
also depend on later symbols. Symbols are saved in .config from top to bottom,
so loading can set a symbol before setting its dependency, meaning that set
to something disabled by a later dependency either gets discarded or has to be
remembered and handled in a second pass?</p>

<p>Yet despite this, miniconfig constantly fights with guard symbols because
when I enable a symbol that's inside a menu, the menu does not automatically
get enabled. (Menus are implicit dependencies. Well, glancing at linux-6.14's
mm/Kconfig "menuconfig" is both menu and symbol, which is terminated by
"endchoice". Was it always that bad? I'd think I'd remember if it was always
that bad...) Hmmm, no, judging by drivers/net/ethernet/broadcom/Kconfig
(which is the kind of symbol I usually have trouble with), it looks like
there's just a gratuitous config NET_VENDOR_BROADCOM and then all the
symbols under that have an explicit "depends" (and a bunch of "selects")
so what LOOKS like an expanding menu is just dynamic dependency visibility.</p>

<p>Which says what I really want for miniconfig is for symbol enablement to
traverse "depends" backwards and switch those _on_, whatever I need for this
symbol to be enabled. (Which in the case of multiple X | Y | Z dependencies
is non-obvious, but it could handle the simple cases.) Alas, that's not how
kconfig dependencies work in linux, they're one way gates going the other way.
But if you switch a dependency on after switching on an earlier symbol, it
remembers that the symbol WOULD be enabled if not suppressed, and once unblocked
the symbol does enable. Which is uncomfortably magic.</p>

<p>Sigh, making my new code traverse and set simple dependencies would mean MY
menuconfig would be simpler (one pass, no implicit remembering), but incompatible
with what the kernel does. And I don't do
a lot of that kind of guard symbol nonsense anyway, so it doesn't really
help me either. Compatibility probably wins here, unless I can write a tool
that parses the kernel's Config.in tree and produces a usable .config file
so I don't have to use the legacy plumbing for miniconfig in kernel configs
in mkroot. (Except they also generate a bunch of .h files in their tool
instead of having the Makefile call sed, which seems like a layering
violation...)</p>

<p>I think what's happening is the state assignment is being made (the state
read in from .config is remembered), and the dependencies are resolved when
display the data in menuconfig or write it out into a new .config. So the
symbol IS enabled, but doesn't display as such when you examine it.
(Maybe? Except they'd have to be resolved transitively,
"y" depends on "y" depends on "n" so they're all "n". Possibly with recursion
detecting for circular dependencies, although that's pilot error.)</p>

<p>I don't currently have any "selects", and grep says all my depends are just
on A) SYMBOL, B) !SYMBOL, C) SYMBOL || SYMBOL, D) SYMBOL &amp;&amp; !SYMBOL.
(Oddly all the current &amp;&amp; have a ! on the second one.)</p>

<p>Aha! When I went through menuconfig yesterday looking for anything still
needing the help merging, the reason I found nothing was because of my config.
For example "mkfifo.c" conditionally adds -Z to the help text when you enable
a security blanket. And passwd.c has the block of text about sad password
heuristics. (That's why the old config2help.c read the .config file to write
out the help #defines. I mean I knew I'd implemented quite elaborate plumbing
to do all that, I just missed that there were still any users left.)</p>

<p>So id, mkdir, mkfifo, and mknod add -Z for !TOYBOX_LSM_NONE,
PASSWD adds PASSWD_SAD as a trailing paragraph, and WGET_LIBTLS has
inappropriate help text that should NOT go into wget's --help (it's not
phrased right to act as --help output) but
maybe something should? And sort.c chops out -g when !TOYBOX_FLOAT.</p>

<p>Hmmm... I've thought about adding an escape syntax for a while where you
could insert another %(CONFIG_SYMBOL)'s help text into this block of help
text at an arbitrary point. (That makes all the paragraph parsing to
split out "usage:", "-x options", and "description" sections go away, which
was always brittle and magic.) But if show_help() was parsing that at runtime,
then the other help text would need to be compiled in all the time. But
all the config symbols get resolved at compile time, and if the new kconfig.c
is parsing that then it needs to load .config to write generated/help.h which
for 99% of the cases isn't needed. (Under the new code, generated/help.h is
invariant regardless of .config, and it would be very nice ot keep that.)</p>

<p>I could just always document -Z and -g even when it's not there, and punt
on the other two at the moment? (One of which is wrong and the other
of which is conceptually disgusting anyway.)</p>

<p>Hmmm... or I could teach show_help() that it can suppress lines starting
with, I dunno, an exclamation point. And have a show_help_filter() that
takes a config symbol as an extra argument, and have show_help() be a
wrapper that always passes "don't filter" to the filter argument? Either
way the filter would be modifying the displayed text (even when it doesn't
yank the whole line, it should yank the filter character). And the plumbing
doesn't know what symbols go with which data, that would need to be some
sort of TOYFLAG_HELPSYM(CFG_BLAH) macro setting... I dunno, TOYFLAG_BIGHELP?
#define TOYFLAG_HELPSYM(x) (TOYFLAG_BIGHELP*x)</p>

<p>Since show_help() already has a "flags", this is sort of a HELP_EXTRA
flag, ala "blah|(HELP_EXTRA*CFG_WHATSIS)" which would resolve at compile
time. This doesn't scale to having MULTIPLE dependent config symbols affecting
help text, but <b>grep 'TOY(.*USE' toys/*/*.c</b> is only finding the 5
instances of options dropping out, and going through all the unique "depends
on" lines (<b>grep -h depends\ on Config.in generated/Config.* | sort -u</b>)
only spotted the two added paragraphs, neither of which suppressed an
option. There's "room for future expansion" and there's "philosophy of
consistent behavior" fighting here: config symbols that change behavior
are something I'm trying to AVOID these days...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#10-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 9, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#09-04-2025</link>
   <pubDate>Wed, 09 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I wanted to search my old mastodon posts, so I downloaded my archive
and was once again reminded that the file format is TERRIBLE. "human
readable text" doesn't matter quite so much when the entire file is ONE BIG
UNBROKEN LINE, so you can't usefully open it in vi or use grep or similar.
If I uuencode a binary the result is "human readable text", but being true
isn't the same as being useful.</p>

<p>I googled (and then ecosia.org'd because google is useless now) for a
mastodon archive viewer (or a converter to plain text, or just something
to break the json into an indented data tree with one key:value pair per line,
or even just line breaks BETWEEN RECORDS, but unfortunately most of the hits
are for things like "<a href=https://www.raymondcamden.com/2024/07/21/an-online-mastodon-archive-viewer>online viewers</a>", meaning you upload your data to
a random website that breaks it down for you on their servers after
selling it to advertisers and training AI on it. No: I have a data file
I want to convert it into a useful format locally on my machine.</p>

<p>Last time I applied sed to get "ugly but greppable" (basically just
inserting line breaks between records, which WAS NONTRIVIAL),
and this time I'd like an actual tool. The main downside is I need to
import a json parser, which is not a thing I want to do in C for a
quick-and-dirty tool (I'd spend longer learning/debugging the library API
than writing new code), and there's not a lot of bash ones either, so...</p>

<p>The main recommendation seems to be <a href=https://github.com/zero-mstd/mav-z>a project</a>
which is <a href=https://github.com/slashyn/mastodon-archive-viewer-modified>a fork</a>
of <a href=https://github.com/aionyzq/mastodon-archive-viewer>a fork</a>,
and alas that oldest project (last touched 7 years ago) is still python++
rather than python (sigh), but a quick glance doesn't look like spyware
and when I ran it I did get a self-contained html file... in reverse order
(oldest first, not what I'm used to for this data) with no
links back to the actual tweet on mstdn.jp (the links are IN THE JSON,
the converter just discarded them), which is generally what I'm trying to
look up. (I want to link to an old mastodon post the way I link to old blog
entries, "previously on"...) So I took a whack at modifying it,
and... I forgot how persnickety python 3 is, and how many utterly pointless
gratuitious changes it made. (The dictionary "status" has no member "status.id"
you have to call status.get("id") because... reasons?)</p>

<p>But I still got it to work faster than writing my own from scratch. (I was
HOPING for a python 2 tool that was a decent example of how to use the
json library out of python's standard library, but no...)</p>

<p>I should probably have used this as an excuse to
<a href=https://stackoverflow.com/questions/42139363/how-to-parse-json-in-lua>play</a>
with <a href=https://stackoverflow.com/questions/41931970/deserialization-in-lua/41945465#41945465>lua</a>
some more. (Apparently json is _almost_ valid lua, the trick is avoiding
"bobby tables" problems when you import a malicious dataset that tries to
escape and execute arbitrary code. Of course there's no standard lua library,
but there are
<a href=https://github.com/rxi/json.lua/blob/master/json.lua>third party</a>
ones.) But I just wanted to get it done, and converting the json
into data structures I could traverse still meant learning the format
of mastodon data structures and assembling output, which the above python one
already did _almost_ tolerably...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#09-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 8, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#08-04-2025</link>
   <pubDate>Tue, 08 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I was doing a "gethelp()" function to read the indented help text block
after a "help" keyword, but you tell the block is over by reading a line
that is NOT part of the block, meaning it needs to either return that line
or unget it, and it was already returning the help text it read, so it
probably makes more sense to do it in the main while getline() loop as a
state machine state. So not a function, then.</p>

<p>The usual design balancing act: how much is this a quick and dirty tool to
do the job in front of it, and how much is it scaffolding to tackle a larger
problem in future? But infrastructure in search of a user is a bad thing,
let's just write something now and worry about writing something else later.
New code is easy to come up with.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#08-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 7, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#07-04-2025</link>
   <pubDate>Mon, 07 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Fade's spring break ended, and I headed out the same time she did this
morning to go down to the shared office space near the apartment's front
desk rather than suffer the Cling Of The Dog (and his superhero identity:
Hysteridog Everbark). I did not bring my laptop
charger, which puts a timer on this work session...</p>

<p>Working on a scripts/kconfig.c, which should probably eat
scripts/config2help.c because these days I've mostly eliminated help text that
straddles multiple config symbols. (Busybox did a ton of micromanaging, but
toybox commands should have defined behavior. You can enable or disable a
command, but not options WITHIN a command.)</p>

<p>Yes busybox calls its commands "applets" because Java was popular in 1998.
I made the decision NOT to do that with toybox back in 2006. (Is a cleanup
that isn't widely adopted really a cleanup, or a bespoke divergence from
expetations? Eh, muddle on...)</p>

<p>Anyway, there are a bunch of simplifying design assumptions I could make,
it's a question of how much compatibility I want with the kernel's kconfig.
For example, blocks of related lines are indented, and I could REQUIRE that
so instead of special casing mainmenu, source, comment, config, menu, choice,
endmenu, and endchoice keywords (and whatever else upstream's grown that
I'm not currently using but decide I want to support later), the parsing logic
could just go "hey, unindented keyword right at the left edge: end the previous
context block".</p>

<p>The sad part being that kconfig's "help" DOES care about indentation level,
although it doesn't actually require the help text to be indented FARTHER than
the help keyword (toys/pending/klogd.c has the help text block at the same
level as the help keyword, meaning how does it tell when the block ends
and thus a line starting with "default" or some such would NOT be a keyword)...
It's SO CLOSE to having a reasonable design idea there, and then... doesn't.
(Of course you can have empty lines in help text and the help continues,
so it's never ENTIRELY straightforward. It's not "the next block of lines
indented at least this far in", and of course you can mix tabs and spaces
arbitrarily to achieve this "indentation level". Don't ask what happens if your
first line is indented with 4 spaces and the second with 1 tab, how you trim
the leading space there? Or what if you have one of those allowed blank lines
as your first line of help text, does it defer counting the leading spaces or
set it to zero? Dunno! Haven't checked yet!)</p>

<p>The kernel's kconfig wasn't really designed, it just sort of accumulated.
I <a href=notes-2018.html#05-09-2018>gave up on</a> the kernel's version when
it become turing complete in 2018, by adding the ability to call "rm -rf ~"
to evaluate symbol dependencies.
<a href=https://github.com/torvalds/linux/commit/9ced3bddec08>Yes really!</a>.
I am not implementing that, it is a BAD IDEA.</p>

<p>The kernel has module symbols, and visibility, and "select", and a whole
bunch of stuff I'm just not using. Twenty years ago I'd have had ambitions of
replacing the kernel's verion, but A) I've been juggling too many balls forever,
B) I suspect Linux is more than halfway through its useful lifetime as a
development project (rust and LLM code? Linus isn't even retired yet!),
C) their kconfig is WAY down the Microsoft Word route of having giant
expensive corner case features that matter deeply to like 3 users, and they've
tied it to kbuild when it should JUST MAKE A ".config" FILE FROM Config.in
FILES! It doesn't have a well-defined scope anymore. Dude.</p>

<p>MAYBE the new one could be useful to busybox and buildroot? Except busybox is a
"mature" project that's not exactly moribund, but not looking to make major
changes. And I've lost touch with buildroot development. (uClibc is long dead.
I very vaguely
recall yocto doing something disgusting here, but don't want to get that on me.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#07-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 6, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#06-04-2025</link>
   <pubDate>Sun, 06 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Thunderbird has turned into a CPU-eating loop (as sometimes happens, it's
a terribly coded legacy program), which I need to kill and restart to make
it stop (and thus NOT halve my laptop's battery life). Except I have various
open thunderbird windows scattered over my 8 desktops, partially composed
replies and emails being used as a TODO post-it note and so on, and it would
be a certain amount of work to clean that up.</p>

<p>So I "killall -STOP thunderbird", which is fine until I switch to that desktop
and it renders as a big empty rectangle with whatever background info was
in there before not being overdrawn, and this is queueing up an X11 event that's
not getting serviced in a way that X11 is eventually going to be unhappy
about (they don't exactly timeout, but they aren't discarded either) and
I need to "killall -CONT thunderbird" and then stop it again to clear the
event if I want to feel comfortable about my desktop stability.</p>

<p>Could be worse: firefox has some sort of horrible timer sending itself
events, and if you -STOP that for any length of time (because it should
not be eating CPU when it has nothing to do!) the entire desktop
FREEZES for a while when you -CONT it and it does blocking processing
of the accumulated backlog. Does this mean I could ignore thunderbird for
4 hours while it's stopped? No idea. I usually just kill firefox and
tell it to reload tabs on restart. It's a pity vivaldi isn't in debian's
repo. Yeah, I can add the external repo. And the one for signal. I just
don't feel comfortable adding third party package repos, bypassing
what little peer review the community provides. I stayed with chrome
as long as I did because the <a href=https://www.google.com/googlebooks/chrome/>original design</a>
of each tab being its own process meant I could kill cpu-eating tabs from the
command line. And when that stopped working I could "pkill -f renderer"
and still reload the individual tabs without losing track. I learned back
on _netscape_ that when I bookmark something I never look at it again.
I remember how in the OS/2 web browser I'd drag windows to the bottom right
corner so just the tip was showing in my desktop and would accumulate
dozens of them down there, tabbed browsing was a MUCH nicer way to accumulate
a todo heap.</p>

<p>It's not just "finish reading this", it's "I have some project
in mind" where this tab represents
something I want to follow up on when I have sufficient brain. Where "sufficient
brain" means "this is a heavy lift, I need to be fully rested and at my
strongest with a large block of uninterrupted time to do this justice",
so of course I clear out all the low hanging fruit but the heavy lifts
accumulate, and when I DO sit down to tackle them I do one or two at a time
barely making a dent in the backlog...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#06-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 5, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#05-04-2025</link>
   <pubDate>Sat, 05 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>Went down to the big "down with this sort of thing then" protest at the state
capital. (Which oddly enough is in St. Paul, not Minneapolis. It's a
Dallas/Ft Worth sort of thing: other end of the green line.)
I keep expecting for it to be obvious what to DO when I get there,
but "you're already doing it" is the correct answer. Stood around for 2
hours not really being able to hear the speakers, got mildly sunburned, walked
several stops along the green line towards home (13k steps for the day) and
found out that "Sun Market" sells my checkerboard tea! (Cheaper than HEB had
it!) There was exactly one taco truck at the protest, which was charging $2 for
a soda (brought my own can) and $7 for a basket of fries (decided against).
I suppose I admire their hustle. Found a lady making "hands off" buttons where
you write what you want it to say before they button it,
and I wrote "the penguins".</p>

<p>I wonder if there's a recording of the speakers online somewhere? Not really
the point though. Some lady's protest song got removed from spotify,
and judging by how she sang it there's no WAY it would have gotten as many
listens if they HADN'T removed it. Spotify would totally have removed Bob Dylan
but she was no bob dylan, although she pointed out up front that trying to play
an acoustic guitar in minnesota cold took "in tune" off the table and the
audience was appreciative. The current Bob Dylan, at least
from a singing through the nose perspective, is probably
<a href=https://www.youtube.com/watch?v=e9LJh81n_zA>Jesse Welles</a>
who pointed out that a CEO is an employee not an owner so Luigi
could have aimed higher. (Despite all the hand wringing about said CEO
they didn't even cancel the meeting he was going to, and replaced him with
another from central casting within the week. It would be nice if there was
a non-death way to effect political change, but the nameless faceless
CEO's JOB was to deny medical care to people who would then die, in bulk, every
day. Not a lot of sympathy in evidence in the public record so far. Merely
guillotining the billionaires would have due process of law with forensic
accountants producing an auditable public record. Guillotines are apparently
the compromise position now. And asking for the death penalty is saying "he
shouldn't have killed him, that's why we're going to kill him". Way to
reclaim the moral high ground there.)</p>

<p>But the protest wasn't about that. It wasn't really about any one specific
bad thing, due to the <a href=https://en.wikipedia.org/wiki/Gish_gallop>Gish
Gallop</a> nature of Project 2025.
Lots of other speakers had their own "littany of awful". (Something
about argentinians owning mines that poison wildlife?) And they had one of
the people behind the target boycott, which I was unaware had been organized.
(Sort of a tik-tok thing that caught on, because DUDE.)</p>

<p>I set out doing the medium-paranoia "phone in airplane mode, mask and
headphones to very mildly annoy facial recognition, wear solid colors,
leave the building from a different entrance than usual, do not leave
fingerprints anywhere, bring a straw to drink with mask on" sort of thing,
which the turnout rendered probably moot even before I got on the train.</p>

<p>The green line was WOEFULLY unprepared for a large progressive protest trying
to reach a common venue via public transit. I got on near the start of the line
(well, not long after it splits off from the blue line anyway) and every train
that went by was FULL, wall-to-wall standing people. They'd already BEEN leaving
people behind on previous stops. The train triver of the first one even made a
cut-throat motion at the full platform of people carrying signs. I managed to
squeeze on to a later train by applying tokyo rush hour standards
(sort of jenga-ing myself flat against a door with both arms
raised as it closed, then working my way towards an overlooked gap against a
wall I could stand in). We then stopped at a dozen platforms full of people with
signs, without being able to let anyone else on and nobody getting off.</p>

<p>I took pictures when I arrived but the crowd doubled in size after that
as people trickled in, and I'm still reluctant to post anything that might
show faces. I posted <a href=https://mstdn.jp/@landley/114287408048312369>one</a> that didn't
show anyone's face. (No, my phone does not sync photos to "the cloud".
I beat that crap out of it when I first got it and recheck every few months
to undo Google's <a href=https://mastodon.social/@jzb/114258880850981210>backsliding</a>.
It got its last security update in 2022, yet they're still sending code to
halve the battery life and shame people for having bodies. <a href=https://cloudisland.nz/@rmi/114219847307106213>Bad form</a>.)</p>

<p>As several signs said, "even the introverts are here", and it was EXHAUSTING.
Hit Aldi's but had to put everything back because they refused to take dollar
coins (the green line gives dollar coins as change but the cashier said their
nightly cash deposit thing can't handle them). Got home, slept a lot, woke up
badly dehydrated and chugged a can of Arnold Rimmer, slept some more. That
pretty much ate the day.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#05-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 4, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#04-04-2025</link>
   <pubDate>Fri, 04 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>When I switched from gmail to dreamhost I didn't bother to set up new spam
filtering, I just "read with the d key" when downloading. There's only about
500 spam emails a day, and back on gmaili I had to look at them all in the
"spam" folder to fish out false positives ANYWAY so I might as well just do it
myself in the first pass. It doesn't take long if you stay on top of it,
and I can breeze through most of them deleting multiple messages per second
when the subject is chinese characters, "rate enquiry", "shipping agents",
"chinese phone parts", unexpected (fake) docusign, the whole gamut of
"change your email password" through "new message notification" attempts
to hijack the email account itself (I download and delete messages off
the server each transaction so no, my mailbox is NOT almost full and if
it was the email download in progress would be the fix for that. What _is_ ipfs
dot io, anyway? An entire genre of scam links go there.) I only bother to read
even the start of like 5% of the messages, meaning I can usually delete them
faster than pop3 can download them.</p>
</span>

<span id=politics>
<p>Oddly enough, this blatant obviousness is intentional on the spammers' part
because they're running elder abuse scams: they WANT to select for senile
idiots who are easily duped. They don't want to waste their time on the phone
with somebody who might have second throughts. (Or any thoughts.)
They want a good mark, gullible money that's dumb enough to
respond to a proposal people with working brains would not entertain.
(Sadly, after all the surgery and blood pressure lowering medication,
Stu had deteriorated into that category by the time Fuzzy moved out.
His bank account was constantly drained dry by things he kept
signing up for on his phone, and his brother Mitch (who was not _that_ much
better, cognitively speaking) wouldn't let Fuzzy help because HE needed
to be the one in control. There's a reason she's back in New York now.)</p>

<p>Which is why it's interesting that the "you won
a lottery you didn't enter!" genre, where someone wants to give
you a giant pile of unsolicited money, has switched from claiming
it's somebody like Mackenzie Bezos or Warren Buffett or "The World Bank"
giving away money ("State lottery" without naming a state, etc), to crediting
"President Donald J. Trump" for the random largess. Last month they were
crediting Musk and Doge for wanting to hand out six figure checks to random
email addresses, but even the senile vegetables have gotten over _that_ one.</p>

<p>If you're still a loyal maggot today, they have a bridge to sell you.
Because you've self-identified as someone who will spend $99 for
<a href=https://www.huffpost.com/entry/stephen-colbert-trump-nft-collection_n_639c0c6ae4b03e2cc4fed2b9>AI-generated NFTs</a>.</p>

<p>(There's a reason "The Boomers will die" is my calming mantra.
50 years breathing tetraethyl lead, stacked with senility, stacked
with a lifetime of self-referential navel-gazing entitlement as the
main characters of every story which the universe revolved around.
The fever breaking doesn't mean the patient is healthy again, but it's
a necessary prerequisite. They've provided the criticial mass of cannon
fodder since they first started going senile back in the "tea party,
nigerian prince" days. "Never trust anyone over 30" was THEIR motto,
back when their brains still worked.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#04-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 3, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#03-04-2025</link>
   <pubDate>Thu, 03 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=health>
<p>I thought I'd escaped the usual "catching something" from the international
flight (11 hours in a pressurized can with hundreds of other people breathing
recycled air, kind of inevitable), but no it just had a bit of an incubation
period. This one's a cough. All the coughing.</p>
</span>

<span id=politics>
<p>I got my quarterly poke from the money concierge asking if there's anything
I want to do with my retirement account. Not specifically because Dementia Man
is about to implode the economy so billionaires can scoop up every asset
everywhere at fire sale rates, but just because it's a new quarter so courtesy
call.</p>

<p>I haven't replied because I don't know what to say. I worked hard to get it
all into an S&amp;P 500 index fund, and would have
been better off putting it in the 5% savings account. Or a sock drawer.
Oh well, "the best laid plans of mice and men are generally equal". Going
by how the previous great depression turned out, I'm 99% sure it's got a
whole lot more "down" to go and a very long time to spend there (the 1% is
"octogenarian has sudden stroke and his cult does not survive their god's
demise"), but selling the dip instead of riding it out is timing the market
and I'm not good at that. If anything is left of social security I won't be
able to claim it for 20 years, and he should be (long?) dead by then.
Whether the US dollar will still exist is an open question...</p>

<p>I don't LIKE caring about money. I want to have just enough money to not
have to care about money, which according to
<a href=http://www.youtube.com/watch?v=u6XAPnuFjJc>Daniel Pink</a> is actually the
common case of economic motivations. Alas, the rich can't exist without the
poor or there's nothing to spend the money ON (Bill Gates does not hire
Warren Buffet to wash his car, "you can't get good help these days"),
so billionaires have carefully
engineered "the precariat", and the bottom 99% have so far inexplicably failed
to notice that each billionaire has a neck and applied the obvious historical
solutions yet. No, Luigi doesn't count: a CEO is an employee not an owner,
he could have aimed higher. Capitalism is a religion that makes kings using
numbers and bankers instead of sin and knights. As with all religions, it only
works when a critical mass of people buy into it and the believers actively
ostracize those who don't. People with food and shelter can opt out of
the rat race, so guess what all the inflation's focused on as the billionaires
tighten their grip? Eggs were the cheap protein. It's strategic and focused.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#03-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 2, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#02-04-2025</link>
   <pubDate>Wed, 02 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Google doubled Jeff's cloud bill by making the AI stuff no longer opt out,
so now not only are they leaking our proprietary data to third parties
(Hey Google: what is coresemi working on that they haven't publicized yet) but
charging us double for the privilege. So we looked at "NextCloud" plugins
that let us do the "two editors, one <strike>cup</strike> document" remote collaboration thing,
and we need to set up our own imap server, we need to set up a stable
rackmounted machine with a static IP (we're prototyping it on something with a
DHCP IP), and downloading all our old data OUT of google's cloud is the
real headache. (We can do it manually one file at a time, as an "export"
with multiple data type options that work differently... for example
opendocument loses alpha-channel in background graphics but exporting as
powerpoint doesn't. No big "give us a tarball of all our data" option, nor
any way to get one big list we can go down and tick things off. So it's
eating engineer time to avoid being charged more than a tokyo engineer makes.)</p>

<p>We've got a month to get everyting out before the next bill comes due.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#02-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[April 1, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#01-04-2025</link>
   <pubDate>Tue, 01 Apr 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Spent several days basically curled up into a ball when I got back. Trying
to get some work done now.</p>

<p>So <b>bash -c $'BANANA="ls -l"\nalias banana=\'$BANANA\'\nbanana'</b>
says "line 3: banana: command not found" but when I type the three lines
at an interactive command prompt I get a directory listing. I am reaching
the point where matching bash's behavior exactly is starting to seem
like a bad idea.</p>

<p>I keep poking at "alias" support hoping it makes sense, and coming to some
disturbing conclusions that I do NOT want to implement. (Did... did
he put alias support in the interactive command editing layer? That
CAN'T be right.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#01-04-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 28, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#28-03-2025</link>
   <pubDate>Fri, 28 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>Fade's father is visiting. He's a devout christian (worked for a church his
entire career, remember how Fade's parents raised her in a mission in Ecuador?),
and I'm finding it VERY HARD not to needle him about The Recidivist.</p>

<p>I've actually studied a lot of bible stuff, read the entire Torah
(The old testament: director's cut) in my comparitive religions class at
community college, follow Bart Ehrman's podcast, read
"<a href=https://archive.org/details/kensguidetobible00kens>Ken's Guide to the Bible</a>" when it first came out, etc. But studying Norse
mythology isn't the same as believing in Thor, and Fade got a doctorate
in classics without worshipping Athena. It's more "I could sing
<a href=https://www.youtube.com/watch?v=pvhYqeGp_Do>The Vatican Rag</a>
from memory when I was 7" and following "so where DID the
names of Santa's Reindeer come from" until I'm telling people about Haddon
Sundblom's coca-cola commercials and watching rankin-bass stop
motion making-of specials and trying to explain why the guy who voiced
"Tony the Tiger" didn't get credited for singing "You're a mean one Mr.
Grinch"... Just because I wouldn't be surprised if a dude named Nicholas
actually did live in Turkey 1700-ish years back (and possibly even donated a
dowry to three daughters whose father was otherwise forcing them into
prostitution) doesn't mean a talking snowman and flying raindeer living at
the north pole (who weren't findable when people actually went there)
inexorably follows from that. "But if you don't belive you won't get any
presents" isn't an argument. Reality does not care what you believe,
that's what makes it reality.</p>

<p>Personally knowing someone who organizes their life around The Ten
Commandments is like meeting someone who devoutly follows the Ferengi Rules
of Acquisition. I mean... yeah, that's a thing you can do. You realize
that none of the first 4 commandments in the king james bible have anything
to do with morality, right? No other gods, no graven images, keep the sabbath
holy, don't take the lord's name in vain: none of that is morality, it's
all just monotheism clearing its turf. And then "honour thy
deadbeat dad despite whatever alcoholic beatings or groping may have been
involved" is once again pretty iffy. It doesn't get to "thou shall not
kill" until number SIX. Don't steal is eight. In between is "adultery" (so
nobody should ever get married, to avoid violating an archaic ceremony),
and bearing false witness against thy neighbor... why the
qualifier? It's ok to lie to people who live far enough away? Or siblings?
And not coveting thy neighbor's manservant gets us into
the whole "slavery" thing. The word "manservant" is a euphemism: the bible in
greek is FULL of slavery, just like the ancient greek world was. How
is the timeless word of an omnipotent omniscient being "a product
of its time" again? Egypt has over 5000 years of _recorded_ history and
your magic book chronicles events from 2000 years ago, why wait over a
hundred generations of civilization to go "oh right, time to start
saving people!" (Saving them from... you? All this "original sin" stuff,
inherited badness exactly like India's caste system.) Omnipotent, omniscient,
omnibenevolent: <a href=https://www.smbc-comics.com/comic/2011-06-30>pick two</a>.
And why is your god _hiding_? "God told you" but can't tell me? What does he
need YOU for exactly, when he's omnipotent, omniscient, and omnipresent?
To "spread the word"? Why? Your book has angels showing up all over the place
to perform miracles, they didn't USED to be hiding, but only back in
mythological "a friend of a friend told me" times. Today the world's
covered with cameras and not a single miracle gets recorded. Funny that.
(Mysterious ways is not an excuse, it's you seeing faces in clouds.)</p>

<p>Even if you retrench to "well the garden of Eden and Noah's arc and such didn't REALLY
happen, but these parables are a better source of morality than aesop's
fables"... No they're not. Seriously, this book is not a source of morality.
Four words that could have saved millions of lives: "boil your drinking
water", are found nowhere amongst the pages and pages of "bats aren't kosher,
but this one species of locust explicitly is for some reason". If you're
ignoring the parts about mixing fabrics then you're _already_ acknowleding
a source of morality OTHER than the book that supercedes what the book
literally says. Deuteronomy 17:5 says anyone worshiping other gods (or
the sun, or the moon) should be stoned to death. Leviticus 24:16 says
"anyone who blasphemes the name of the LORD is to be put to death.
The entire assembly must stone them. Whether foreigner or native-born,
when they blaspheme the Name they are to be put to death." Not a lot of
grey area there. The stoning
scene in <a href=https://www.youtube.com/watch?v=FQ5YU_spBw0>life
of brian</a> is LITERALLY what the bible tells people to do.
The fact we don't is because we all admit the bible is wrong, and cherry pick
a subset of what it says based on our own moral judgement.</p>

<p>Of course there's the "God changed his mind, replacing the old eternal
infallible law with a new and different eternal infallible law" argument.
As demonstrated by Jesus' speech in Matthew 10:34-36 "Do not think that I have come to bring peace to the
earth; I have not come to bring peace, but a sword. For I have come to set
a man against his father, and a daughter against her mother, and a
daughter-in-law against her mother-in-law; and one’s foes will be
members of one’s own household." The dude who smote the fig tree and
in Matthew 15 told a "woman of Canaan" asking for help that he only
helped israelites until she compared herself to a dog to get past his
racism. Is the real reason all the old testament laws stopped being the timeless
and infallible word of god because god changed his mind and his eternal
laws stopped being laws? Or did people just pick and choose what they wanted
to follow? The NEW stuff has Jesus <a href=https://en.wikipedia.org/wiki/Cleansing_of_the_Temple>driving the moneylenders</a>
out of the temple is in all four gospels yet the evangelicals have
"prosperity gospels" and televangelists are big business. Render unto caesar
that which is caesar's and they stan billionaires who pay zero taxes.
Yeah yeah, "the devil can quote scripture" I.E.
the words in your book are utterly useless for determining right from wrong,
and you _explicitly_ acknowledge that. The words are just tools, what REALLY
matters is who is saying them. The televangelists begging for money are
the right sort of people, as is the "grab 'em by the pussy" guy.</p>

<p>The fact the guy the new testament's about got tortured to death
and his followers huffed the largest batch of copium in history about it
with the ultimate "no, he MEANT to do that, it was all part of the great
plan" is just... So God can just forgive sin, but in this case he couldn't,
not without coming down to earth and having himself ritually humiliated and
tortured to death over a period of multiple days. This is your religion's
CENTRAL THESIS. If he'd been killed by the electric chair you'd all be
wearing little electric chairs around your neck. And this makes SENSE to you.</p>

<p>But the weird belief thing by itself is on the level of
"Huh, you're a monarchist. You think King Charles is somehow a special sort
of person. In 2024. Still. Really." and I wouldn't really mind what makes
him happy if it was just like a fanatical sports team fandom or he'd spent
decades following the Grateful Dead around the country to see every show.
But christianity is a wholly owned subsidiary of the republican party these
days, which aggressively legislates their beliefs, and THAT I have a problem
with. These people <a href=https://www.bbc.com/news/articles/c20g1zvgj4do>literally worship</a> trump.</p>

<p>Anyway, Fade's father is visiting, who was openly thrilled about the
anti-abortion stuff trump did last time (after every single one of his supreme
court appointees perjured themselves in their confirmation hearings), and I am
being as diplomatic as I can manage.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#28-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 27, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#27-03-2025</link>
   <pubDate>Thu, 27 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Onna plane back to Minneapolis. I look forward to seeing Fade again,
not so much being back among the magats.</p>

<p>Plane is packed, middle seat, no chance to program.</p>

<p>International dateline, I got 48 hours of the 27th. Wheee. (So much
jetlag.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#27-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 24, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#24-03-2025</link>
   <pubDate>Mon, 24 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Bash is just sad at times.</p>

<blockquote><p>
$ alias banana='$BANANA'; BANANA='ls -l'; banana<br />
bash: banana: command not found<br />
$ banana<br />
total 1<br />
drwxr-xr-x 4 landley landley 4096 Mar 22 00:33 bms-c<br />
$
</p></blockquote>

<p>The answer to "what order does alias perform operations in" is basically
Munsch's "the scream".</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#24-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 19, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#19-03-2025</link>
   <pubDate>Wed, 19 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I've been deterred from just creating a new gitlab account because when I
go to the issue link the top bar has "log in" and "free trial" buttons:
all accounts are either paid for or time out. It is NOT a free web hosting
service with any interest in open source projects, it is proudly a paid
proprietary web hosting service only.</p>

<p>I remember when I was researching
github alternatives (back when they were taking my web login away) I looked
at gitlab as one of the options and rejected it, but the options I _didn't_
choose all bleed together. I mostly remember gitlab as "that place you pull
qemu from these days" and there were some other historical projects that
migrated to it when other servers went down, I think? They're not sourceforge,
not kernel.org, not gnu/savannah... remember when "google code" was relevant?
Those were the days...</p>

<p>Alas if I _do_ have a historical gitlab account grandfathered in before
<a href=https://forum.gitlab.com/t/why-force-users-to-start-free-trial-and-why-sign-up-multiple-times/103525/11>this venture late stage capitalism nonsense</a>,
I don't seem to have my notes about it on the machine I brought with me to
tokyo. Sigh, last visit the looming personal server administration issues
were migrating my email from gmail to dreamhost, and figure out what to do
about losing my github web login. Always something...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#19-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 18, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#18-03-2025</link>
   <pubDate>Tue, 18 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=health>
<p>Felt largely ok, went out, ate lunch with people (very slowly), crashed HARD,
had to go home. Whee.</p>

<p>(It's like my blood pressure is really low, and digestion lowering it
further means I just collapse.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#18-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 17, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#17-03-2025</link>
   <pubDate>Mon, 17 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<p>Managing to stay upright for over an hour at a time. Yay.</p>

<span id=programming>
<p>Sigh, nobody's upvoted the gitlab issue. Multiple people have
now reported it to me, and even
<a href=https://mstdn.jp/@landley/114169242776698138>retweeted my mastodon
posts about it</a>, but despite <a href=http://lists.landley.net/pipermail/toybox-landley.net/2025-March/030699.html>posting it to the toybox list</a>
nobody's engaged with gitlab.</p>

<p>I may have to make a new gitlab account (whether I already have one
or not). Also, if their "virus" detection is literally "a document
containing the string landley.net" (which it <a href=https://mstdn.social/@charles25565/114168243724663172>seems to be</a>),
there's a number of
wikipedia pages <a href=https://en.wikipedia.org/wiki/Qualcomm_Hexagon>linking</a> to my site
(especially to the computer history mirror), and links from lwn.net and so on,
that you'd think would trigger.
Mastodon's syndicated several URLs with that string in it. A bunch of linux
kernel archive sites...</p>

<p>But I'm not trying to engage with this while still loopy from saturday's
gastric attack.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#17-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 16, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#16-03-2025</link>
   <pubDate>Sun, 16 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=health>
<p>Spent the day in bed. Running a fever, for some reason. Starting to suspect
this was an allergic reaction or something rather than food poisoning.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#16-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 15, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#15-03-2025</link>
   <pubDate>Sat, 15 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=health>
<p>Food poisoning is never fun, but japan's "bathroom and shower are in
separate rooms, and even small solid chunks can't go down the shower
drain" adds an extra layer of fun to the proceedings.
On the bright side, I did not aspirate anything! Which is pretty much
what I was focused on. <a href=https://mstdn.jp/@landley/114169301524964005>For 8 hours</a>.

<p>(I think the turning point was being able to keep water down around sunrise.
It was an unpleasant night.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#15-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 14, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#14-03-2025</link>
   <pubDate>Fri, 14 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>It's good to know that
<a href=https://www.theverge.com/news/628369/solar-wind-beat-coal-us-ember-report>renewables have passed coal in the US</a>
so despite the Recidivist's thrashing, market forces are strongly arrayed
against fossil fuels. And the actuarial tables against fossil
politicians. (Not that both won't cheat on all cylinders, the question
is who provides groveling compliance and who at least slow walks it until
the octagenarian's dead.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#14-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 13, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#13-03-2025</link>
   <pubDate>Thu, 13 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Someone was kind enough to
<a href=https://woof.tech/@techokami/114152390409374583>open a gitlab
issue</a>. It's most likely the
same nonsense I <a href=notes-2024.html##24-04-2024>argued with dreamhost</a> about
a few months back. If I have a gitlab account the login info isn't on
the machine I have with me in tokyo, so hopefully other people can
upvote the issue...</p>

<p>(I remember looking around for places to flee github to when they
took away my web login, and gitlab somehow managed to be <a href=https://mstdn.jp/users/landley/statuses/111422455113586907>MORE corporate</a>
than microsoft.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#13-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 12, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#12-03-2025</link>
   <pubDate>Wed, 12 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Got an email that ublock is <a href=https://urlhaus.abuse.ch/browse.php?search=landley>blocking landley.net</a>.
I do not have the spoons to deal with this right now.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#12-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 10, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#10-03-2025</link>
   <pubDate>Mon, 10 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I got a couple of <a href=https://github.com/landley/toybox/pull/544>bug</a>
<a href=https://github.com/landley/toybox/pull/545>reports</a> about
selinux support in tar, which collectively imply that Elliott never tested
archive creation, only extraction. I do not have a machine with
selinux in it, I ran fedora in a VM to test this stuff way back when.</p>

<p>Anyway, I think they're both fixed now, but I pestered the reporter to
give me a pair of <a href=https://github.com/user-attachments/files/19157390/gnu.zip>test</a> <a href=https://github.com/user-attachments/files/19157391/toybox.zip>files</a>
(which are actually .tar files despite the .zip extension, because Microsoft
Github allows you to upload files with a .tar extension but will not allow
you to upload files with a .zip extension, no the actual format or contents
of the files don't matter, thanks Microsoft Github).</p>

<p>The file produced by red hat and the file produced by toybox have some
differences, but after looking through them (diff -u &lt;(hd gnu.tar)
&lt;(hd toybox.tar) | less) I'm sort of leaning towards NOT regression
testing xattr creation, because A) I still don't personally care about
this feature I don't use, B) ew.</p>

<p>The first change is that that the header's filename (which is basically
a comment) says "./PaxHeaders/a" and "./PaxHeaders/b" for the two entries in
the gnu one, and "././@PaxHeaders" for both in toybox. It seems to be accepting
it anyway, because the important thing is that the header is type 'x', not the
name. An x record applies to the next header entry after this one, so the name
in the x record isn't used and doesn't matter. My code is creating those comment-like
names via <b>sprintf(tmp.name, "././@%s", type=='x' ? "PaxHeaders" : "LongLink");</b>
which goes into a fixed length buffer padded with NUL bytes so the shorter
name doesn't actually save any space. I got that from somewhere, and it looks
like gnu maybe has version skew? Making the output binary identical is
silly when what they produce changes each version upgrade.</p>

<p>The next change is that various internal header length counters are
different, because the payload is different. Seems like an effect, not a
cause.</p>

<p>The next hunk of diff is that gnu's header has "ustar\000\0" (I.E.
ustar, a null byte, two ascii zeroes, and a null byte), and mine has "ustar  "
(with two trailing spaces) and
"root" with null terminators. My ustar has two trailing spaces of padding
(to match what was there at the time!) and I'm using the name instead of
the UID by default. Which is WHAT IT WAS DOING, and while there's a
--numeric-owner flag to tell it to use numbers, there isn't any sort of
--non-numeric-owner flag to tell it to use names: it's the default behavior.
If it STOPS being the default behavior, we lose that capability. So either
gnu broke and lost a capability, or Red Hat is being nuts with aliases or
something? Plus, the fields are at fixed offsets, so their 00 starting two
bytes earlier than it should is funky (and why TWO zeroes?), their actual
"uname" field seems to be entirely NULL. And then they populated the gname
field, which it looks like mine didn't (dunno why, but it's an x record so
who cares: none of this gets used?) The actual "I can't parse their output,
they can't parse my output" bug reports got fixed, this is differences that
haven't resulted in actual problems... Concerning, but I dunno what's going
on here.</p>

<p>And then the next difference is that an x record is basically a string
with a bunch of "%d keyword=value\n" records concatenated together, where
the %d is length in bytes of the record... Except of course it's not the
length of the string, it's the length of the LINE including the newline, the
number itself, and the space between the number and the string. (Sigh.
You have to print it, work out how many digits that number is, and then
work out if adding that increases the length of the number by one ala 9-&gt;10
and this is VERY GNU. They did not have to do this. It's entirely
self-inflicted.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#10-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 9, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#09-03-2025</link>
   <pubDate>Sun, 09 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<blockquote><p>
$ alias ls='ls -l'<br />
$ ls<br />
sh: ls -l: No such file or directory
</p></blockquote>

<p>I was TRYING to confirm that alias isn't recursive, but... Sigh.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#09-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 8, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#08-03-2025</link>
   <pubDate>Sat, 08 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Busy in Tokyo with other things (Jeff's stuff), haven't been using my
laptop and thus haven't been blogging. Tokyo remains very nice. Being
on the other side of the planet from Putin's pet tangerine is also very
nice.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#08-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 5, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#05-03-2025</link>
   <pubDate>Wed, 05 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Trying to glue the cleaned up blake3 implementation into toybox, which
would be easy to do if there weren't two codepaths. The library codepath
has magic string names for each hash type corresponding with some enum out
of a header, but openssl doesn't seem to have blake3 yet? I cd'd over to the
boringssl source, listed the top level contents, noticed a "rust" directory, and
noped right out of there.</p>

<p>If the rust devs want to write new implementations, fine. The go, swift,
zig, and oberon people are not trying to contaminate every existing project
with internal language domain crossings too mark their territory. Nor do they
insist that they are "owed" all those other projects. If you want to create a
replacement for the linux kernel, do that. If you want to implement a new
drop-in libssl replacement in a different language, do that. But DON'T BREAK
THE EXISTING ONE YOU FUCKING ASSHOLES. But no, the current existing codebase
must BECOME riddled with rust, not be replaced by it and outcompeted in the
marketplace of ideas. And of course it doesn't remove C (because they can't,
they're not actually load bearing), it just adds more layers of complexity.</p>

<p>Do a new implementation in a new language if
you want, but STOP CONTAMINATING C PROJECTS. One project written in
two languages with binary domain transitions at runtime is a BAD THING.
Lua is designed to be extended with C, rust is a parasite that infects C.</p>

<p>This is why I refuse to have a rust toolchain in any of the systems I build.
Any package that can't build without specks of rust weakening its
infrastructure is broken, and I stay at the last version until I find a
dropbear or bearssl or similar package that ISN'T CRAZY.</p>

<p>I have plenty of practice avoiding systemd, and abandoning KDE when it got
toxic, and avoiding windows and facebook in the first place. "Not being part
of that ecosystem" is fine with me. I am willing to be convinced, but
not coerced.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#05-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 4, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#04-03-2025</link>
   <pubDate>Tue, 04 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<p>I have a very nice room in a "monthly mansion", through the 27th.
They emailed me about a resident meet-and-greet (sakura bloom viewing,
it's basically Japan's pumpkin spice) on the 28th.</p>

<p>I'd love to live in Tokyo, and planned to do so while Fade was getting
her doctorate, but now she's graduated and has a job in minneapolis. (And
her response to the election was that she grew up in Ecquador where the
government collapsing was a regular occurrence. I am less sanguine,
but staying with her. Happy to spend some time on the other side of
the planet, though.)</p>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#04-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 3, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#03-03-2025</link>
   <pubDate>Mon, 03 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>(It's really still the same day, but international dateline.)</p>

<p>I'm trying to debug the "wget http://10.0.2.2/blah.tgz | tar xv" bug,
which is like 3 different bugs. I should have this codepath in the test
suite, but autodetecting compression types from nonseekable input isn't
something the host version does, so it would be a toyonly test anyway.
(It works fine if I pipe to tar xvz, but it TRIES to autodetect...)</p>

<p>Got another request for "nologin". Still don't see the point, but it's
in debian's default install and in busybox, so...</p>
</span>

<p>I'm trying to get together some of the info I'll need for the paperwork
at the airport, which includes the address of the place I'm staying.
Instead of Google Maps (which turned into pure advertising) I've been using
the "Organic Maps" app, which is an open source Android app using the Open
Street Map data. Like Gmail, Google Maps started life as a web version of a
30 year old open source project. (Microsoft's approach with Encrata was
to try to put Wikipedia out of business. Google's approach is to embrace
and extend open source projects. They were net contributing back until about
2019, but stuff like "Google Amp" is about interposing their services so
nobody uses the original, and the AI summary stuff is even more of that...
Google Maps has sattelite view and street view, which the open street map
data doesn't, but highlighting advertised businesses three zoom levels
before where they'd otherwise show up, and refusing to show me local black
owned businesses even when I zoom all the way in? That wasn't cool.</p>

<p>Let's just handwave, for the moment, the difficulty of open source projects
surviving in Google's proprietary Play Store. (I trust Debian's repositories
to have good code. The play store, noticeably less so.)</p>

<p>Anyway, the hiccup I hit is that the app works offline, so does not
dynamically download map data. Instead when you zoom in enough it prompts
you to "download tokyo prefecture (120 mb)", which is a thing I should have
done before getting on the plane. (No wonder searching for tokyo street
addresses didn't provide any hits, I'd only downloaded minnesota...)</p>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#03-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 2, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#02-03-2025</link>
   <pubDate>Sun, 02 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>The plane's completely full (I know because the checkin kiosk did this "bid
to be bumped" pop-up thing, $500 was the max of the anchoring options and
they didn't bite when I hit it), but I have an aisle seat so managed to
do a little work on my laptop. (I have elbow room on one side, anyway.)</p>

<p>But it's in bursts, and after fixing a thing and queueing up three more
things I need to do (in a "before I can fix THAT bug I hit THIS bug,
oh yeah I remember that issue I haven't fixed yet..." way), I took a break
to try to watch one of the in-flight movies on the seatback screen.</p>
</span>

<span id=entertainment>
<p>I had high hopes for "Deadpool and Wolverine", but no. I had to pause at 12
minutes in. And then again about once a minute since. Through him being rejected
by the avengers, through failing as a used car salesman, through the painful
burthday party here he's broken up with Vanessa for some reason? Even through
the TVA which is where you'd THINK the movie would perk up but it's still just
sort of... It's not quite embarassment squick, but it's emotionally hard to
watch in a way I don't remember previous deadpool movies being. They
were cathartic and funny. There was tragedy and drama but it not a lot of
"waiting for the other shoe to drop" for more than like 30 seconds at a
time.</p>

<p>Maybe it's just been a long time and I'm not remembering. Maybe I got spoiled
by too many clips online. But it's paused at just under 23 minutes in and
other than the credits sequence (which was great), this movie has been
clearing its throat and waiting to start.</p>

<p>The concept of "anchor being" is... sigh. A billion galaxies all depending
on one dude they've never met? The fabric of reality breaking down because
Jesus died? I'm not buying the physics. They could have at least come
up with some more convincing horseshit about "it's an echo of Thanos doing
that snap, one guy killing half his universe resonated across parallel
realities that are currently either living or dying based on the fate of an
individual because snap." Give me a fscking FIG LEAF here. (How did this
universe survive long enough for the TVA to be founded?) Yes I expect
fourth wall breaks (which in-universe are treated as Wade being mental because
head full of tumors, but here they're... not?), but I've been completely pulled
out of this movie a half dozen times and we're not CLOSE to half an hour in.
"I am aware of voyeuristic extradimensional entities who mimic my reality
for their entertainment" is not the same as
"I'm going to grab the microphone and pull it into frame because this is not
real even to its own characters". I can't make the airplane playback go 2x to
speed through it more tolerably. I'm glad I didn't see this in theatres because
I might have walked out.</p>

<p>Darn it, I was hoping to like this one. (Unlike Moana 2 which I'm just not
bothering with. At least Aladdin II was forwards looking not backwards
looking. That was trying to be the PILOT for a TV series, rather than
"we cancelled the TV series and frankensteined the corpses of a dozen
episodes into a single theatrical release. This time the "sucky direct to
video plot" is recycled leftovers made from something that already explicitly
failied and will not be happening. They're showing it to us because they already
paid for it, not because they LIKED it. They explicitly DIDN'T like it enough
to finish the series, but hey, sit through it in theatres! Kids are too dumb
to know better! That's... Ouch. No. Do not sully the memory of the original
like that. Yes I have the option to watch that on this plane. Or "Mufasa" which FUCK no, a
PREQUEL to the LIVE ACTION REMAKE??? Which WASN'T LIVE ACTION BECAUSE CGI
ANIMALS WITH NO EXPRESSIONS OR BODY LANGUAGE AND... AAAAAAAHHHHHHH!!!!!!)</p>

<p>Ooh goddess, Paradox's villain rant at 25 minutes is... Couldn't they at
least get whatsisname, the Butler from Clue and Sweet Transsexual From
Transylvania to do it? He went full muppet in Muppet Treasure Island,
he could pull this off. The random empty suit they have here is failing to
ham it up OR be convincing. It's neither serious nor camp, it's just sad.</p>

<p>At 26 minutes it's trying to provide motivation, and just isn't. He literally
established that "everyone I care about is in this room" around 10 minutes ago,
but they won't transplant the contents of THAT ROOM. Why? No reason! Ryan
Reynolds actually emoted a little bit (maybe 10 seconds), but the guy in the
suit is just nothing. He's neither Darth Vader nor a punchclock villain,
his motivation is READING A SCRIPT.</p>

<p>Possily "kill your family to join post-endgame marvel alongside Quantumania
and The Eternals" is not a coherent pitch for a villain to even make.
It keeps showing clips of The Avengers from 2012, but they already did Endgame,
that's over. And Deadpool already asked to join The Avengers like 5 minutes
ago, this is supposed to take place AFTER that. The first
movie did nonlinear storyteling, but you could piece it back together
pretty easy. Deadpool 1 asked "why did this happen" and then backed
up to show you. Why does he want to join The Avengers here
instead of the X-Men? Yeah yeah meta Disney but it makes no sense IN UNIVERSE.
The emotional stakes are BACKWARDS, Disney thinks it's hot shit and that
the audience cares more about behind-the-scenes making-of drama than the
story ON THE SCREEN. This movie is failing to tell a coherent story.</p>

<p>I remember how, to me at least, far and away the weakest part of the Dr. Who
50th anniversary special was the meeting with The Curator. Because it was all
nods and winks that made no sense in-universe.
If they'd established "this was one of the leisure hive clones of the 4th
Doctor who survived that episode
and will eventually decay into The Watcher and merge back into The Doctor
when the 4th doctor regenerates between Logopolis and Castrovalva (as we
saw on screen, thus ANSWERING a question instead of asking one), and in the meantime
the clone gets a couple hundred years of scurrying around behind the scenes
pulling strings to balance the fallout from the Logopolis entropy wave
destablilizing the universe, which was why the Key to Time had to be
assembled to save most of the universe from that particular disaster, and
as long as he was cleaning THAT up he took a quick swipe at the time war
on his way out... they could easily have made a fantastic story out of that.
Tom Baker's elderly character getting increasingly pale and frail as his time
runs out, adding "the watcher" makeup and racing against the clock to finish
his tasks until the current Doctor drops him off near where Tegan's Aunt
Vanessa's car broke down at the end. But "all these nods
and winks mean NOTHING in-universe" was self-indulgent nonsense that I found
painful to watch. It served no story purpose. The story needs to emerge from
the motivations of the characters. If that's not what's driving the plot then
there are no emotional stakes and I have no investment in what's going on.</p>

<p>Seriously, this is freshman level writing 101.</p>

<p>And half the point of the Loki
series was apparently that the "sacred timeline" read like a cult to
everybody outside the TVA, so now there are other timelines the TVA allows
to exist (they no longer prune everything)... but one of them is still scared?
How does that work? I'm sorry, what did the Loki series accomplish exactly?
"We no longer prune" THEN THERE ISN'T ONE SACRED TIMELINE. Especially
since going forward past Endgame even Disney's audience doesn't know what
"the" timeline is, it's branching all over the place. That
whole Doctor Strange and The Olson Twins' Mommy movie, Spiderman Across
The Universe's Live Action Remake with Toby and Andrew, and didn't that
forgettable "Ms. Marvel having a three-way" movie involve Monica Rambeau
winding up exiled to X-Cheers where Blue Beastle is played by Frasier?
(I remember Monica's name because I used to read the comics, I remember her
getting her silver costume from a mardi gras rack: Binary was off with the
Starjammers and Inflation Fetish Lass wasn't a thing yet.)
Which of all those timelines is the "sacred" one, exactly?
Didn't most of them fork off a common base, and then interact with lots of
OTHER timelines? "We visited this other timeline, came back to ours, you
pruned the other one so it never existed but we were there for quite
a while breathing its air and interacting with people so why are we still
here now if part of our personal past no longer exists..."</p>

<p>They're not being consistent even _within_ the Tennesee Valley Authority.
The timeline was sacred because that actor they hyped up to replace T'Challa
(who then got fired for domestic violence) pruned all but one
timeline, because he invented a flawed time machine that forked the universe
to death and was going to smear everything into a lifeless fog otherwise,
or some such? And then there were two seasons of plot where Loki won the
Game of Thrones so yggdrasil could grow out of his ass and now there can be
lots of timelines going in parallel without spaghettification... but one of them is still sacred?
(I didn't see the series, I don't have Google+ and I'm not planning to buy
Google Glass to watch it, but I saw a bunch of clips on youtube because
Loki's actor remains engaging and Tall Round is adorable as OB. I should
not have to be up to speed on the minutia of TV series to follow THEATRICAL
offerings, but from what little I know everying this movie is saying is nonsense
even WITHIN the context of what they'd already established about the TVA.)</p>

<p>And hang on, the movie showed Ryan travelilng to Earth 616 to talk to Happy
Hogan about joining the 2018 Avengers (long before the TVA showed up, outside
of the opening credits which was a flash-foward). It SAID "Earth 616".
How did he cross timelines to do that? Cable's time machine was "forward
and backwards" not sideways. (The TVA guy said Deadpool made a mess of HIS
timeline. The single timeline Deadpool is from, number ten thousand something.
Cable's thingy was not interdimensional travel. As with the Tardis, it can't
navigate SIDEWAYS. There's no coordinate settings for other universes, it
doesn't inherently know how to go that way, it only accidentally ever winds up
in pre-existing alternate univeses like Inferno or E-space or the new Cybermen's
universe due to external factors dragging it off course, and you then have to
VERY CAREFULY BACK OUT through the hole you came in to get home.) And wouldn't
going to work for The Avengers in another universe have involved leaving his
family behind to do it? Since that wasn't his universe? I'M CONFUSED.</p>

<p>28:30: did they ever establish that transplanting a Logan would work? If so,
why couldn't the TVA just do that? (I WANT TO LIKE THIS MOVIE. PLEASE STOP
FAILING AT STORYTELLING! I WOULD VERY MUCH LIKE IMMERSION while confined
to an uncomfortable chair for twelve and a half hours.)</p>

<p>Sigh. It picked up a bit once Huge Ackman got a chance to act, but
I made it a little past the 50 minute mark and just stopped. The evil
bald lady from Star Trek The Motionless Picture starting a cult is
just not my problem. I do not care. I cannot BRING myself to care.
Not after Human Torch America broke his neck falling, but was then resurrected so she
could kill him again, because she's so dumb Deadpool could trivially manipulate
her into killing a random stranger he just met who had tried to be kind
to them. For no in-universe reason. What do any of these people EAT? How
are they protected from this giant all-devouring smoke monster from "Lost"
when they have a large visible base in a fixed location on the surface?
Deadpool viscerally murdered like a hundred TVA agents, and then comes
back to have a civil conversation with their boss. Instead of killing him
(which you'd think a disintegrator stick that looks like that COULD DO)
they put him a prison that Loki ALREADY ESCAPED FROM back in that TV
series that explicitly took place before this movie. They still put people in
there, with a giant death monster that CAN kill them, but won't RELIABLY do so,
and otherwise leave them unguarded. Why?</p>

<p>This is just random unconnected things happening on screen, I'm out.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#02-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[March 1, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#01-03-2025</link>
   <pubDate>Sat, 01 Mar 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Preparing for my flight to Tokyo tomorrow morning: full backup of my laptop
less than a week ago is probably good enough. I did a git fetch on repositories
I might want to poke at on the flight, and linux-kernel had stuff but
busybox hasn't been updated since February 9th and musl since February 12th.
I've been feeling really guilty about not going faster on toybox, but DUDE...</p>

<p>As with last trip, I'm stress cooking. Trying to leave Fade with All The
Food Boxes for work lunches and dinners while I'm away.</p>

<p>I had to go to Target to get more jeans. I feel guilty about spending any
money there until their DEI cowardice/appeasement gets undone (or never if it
doesn't, still not on Faceboot, still not using Windows), but at the moment
I can't think of a better place to buy clothing in Minneapolis. (Well I dunno
what's around.) I bought everything else I usually get at Target
at Cub instead, which is more expensive and has worse selection, but
is not the subject of an active boycott I'm aware of. (They may be terrible,
but if so they were QUIETLY terrible. They did not publicly preemptively
appease a would-be dictator as a show of performative fealty.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#01-03-2025</guid>
  </item>
  <item>
   <title><![CDATA[February 28, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#28-02-2025</link>
   <pubDate>Fri, 28 Feb 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>The FSF remains surprisingly incompetent:</p>

<blockquote><p>
$ tar xvf gdb-6.12.xz<br />
$ cd gdb-6.12<br />
$ tar xvf ../gmp-6.2.1.tar.xz<br />
$ mv gmp-* gmp<br />
$ tar xvf ../mpfr-4.2.0.tar.xz<br />
$ mv mpfr-* mpfr<br />
$ ./configure --target=sh2eb-elf<br />
$ make<br />
...<br />
target-float.c:1160:10: fatal error: mpfr.h: No such file or directory<br />
 1160 | #include &lt;mpfr.h&gt;
</p></blockquote>

<p>It's RIGHT THERE. Configure passed, you built 8 gazillion subdirectories,
and then suddenly you can't find YOUR OWN COMPONENT THAT'S IN THE TREE.
("Autoconf is useless" is still to the tune of "every sperm is sacred".)</p>

<pre><p>
$ make clean; make | wc -l<br />
2565
</p></pre>

<p>It made it 2500 lines into the build before going "boing", most of those
one file being compiled per line. Sigh...
(I'm ONE GUY and I try to test all the mkroot targets before each release.
They can't test all their build targets. Oh well...)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#28-02-2025</guid>
  </item>
  <item>
   <title><![CDATA[February 27, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#27-02-2025</link>
   <pubDate>Thu, 27 Feb 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I have been pointed at a small simple public domain
<a href=https://github.com/michaelforney/BLAKE3-tiny>blake3 implementation</a>,
which seems a good thing to glue into toybox.</p>

<p>It means I'm skipping blake2. And there's no agreed-upon /etc/shadow
"$1$salt$hash" indicator for either hash. (In part because there's no
standards authority for that!)</p>

<p>Ah, wait. "man 5 crypt". $6$ is sha512, $5$ is sha256, $sha1$ is sha1.
Nothing for blake2 or blake3 (was there a blake1?), or sha3. I tried to
look at "yescrypt" but it's an intentionally obfuscated magic implementation
that SMELLS like a scam. I suppose I could ask Michael Kerrisk? (I know
he handed the man pages project off, but the new guy DOES NOT HAVE A
WEBSITE.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#27-02-2025</guid>
  </item>
  <item>
   <title><![CDATA[February 26, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#26-02-2025</link>
   <pubDate>Wed, 26 Feb 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I want to replace TOYBOX_LIBCRYPTO and TOYBOX_LIBZ (and WGET_LIBTLS) with
a single global switch that says always use internal implementations even when
there's an external library with a potentially faster version of stuff.
Then the default behavior (when the config symbol is disabled) would be
to __has_include() the relevant header and use it if it's there, but
use the internal one (or disable the functionality) if it's not. It can
check for LIBCRYPTO and fall bback to checking for LIBTLS (because if both
are installed it would pull hash functions from libcrypto already so
might as well use it for everything).</p>

<p>The problem is, what to call the new switch. TOYBOX_NOLIBS? TOYBOX_INTERNAL?
Hmmm... Until I implement my own https "internal" isn't right bcause the
switch would disable https support. NOLIBS isn't the est name, but it's
sort of what's going on here? TOYBOX_NO_EXTERNAL? TOYBOX_NODEPS?</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#26-02-2025</guid>
  </item>
  <item>
   <title><![CDATA[February 25, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#25-02-2025</link>
   <pubDate>Tue, 25 Feb 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Woo, I edited past the blockage and may actually have 2024 up and be on to
a 2025 public blog file soon! (Before the end of February even!)</p>

<p>[Spoilers: nope.] [Futher spoilers: I'm editing this on April 8th.
There was more politics and ball-curling before the anger/spite caught up.]</p>

<p>I often make bullet point todo lists while working, it's a good way to
organize my thoughts, but they tend to <a href=https://landley.net/toybox/release.txt>look like this</a>
which is not the same as a blog entry. And I usually edit such lists a bunch
of times as I go along. And there's the temptation to do a bullet point
list in a blog entry, and sometimes that becomes my active "keep track of
current work" list because it's the one that's up to date, and I should
really know better by now because it never ends well. Editing should be
"is this coherent, does it render well, did I finish my thoughts, look
up the URLs I meant to link to". Simple, quick to do stuff. Not "completely
rewrite this for hours to explain what it means".</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#25-02-2025</guid>
  </item>
  <item>
   <title><![CDATA[February 24, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#24-02-2025</link>
   <pubDate>Mon, 24 Feb 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>The second bug making mkroot/testroot.sh hang doing "<b>toybox timeout -i 10
bash -c ./run-qemu.sh -drive format=raw,file='$TEST'/init.$BASHPID &lt;
/dev/null 2&gt;&amp;1</b>" was that for recursive command calls, toy_exec()
wasn't clearing the old command's signal handlers, so potentially calling an
inappropriate function and segfaulting if it received a signal after the fork.
This one was ANNOYING to track down, so many printf()s to dredge through
to the failure point. Also, it had 4 interacting processes (timeout
forked toysh which backgrounded a shell script using the ampersand,
and that shell script called toybox's dirname command. In a defconfig build
all four of those were toybox processes forked from the parent toybox process,
and ASAN positively lost its MARBLES at that. Me, I just started each printf()
with the current pid number, ala dprintf(2, "%d message", getpid());
so I could keep the output straight. Seriously, you can debug just about
anything with printf()s.</p>

<p>The November 28 blog entry is being really annoying to edit and post, because
I did my normal todo bullet point notes-to-self as just a blog entry
while working on the shell function call stack redesign, and it does
NOT translate to HTML easily. And alas Google Chrome has been absolutely
terrible about &lt;pre&gt; tags forever, because if you don't explicitly set
the font size the default font size for the monospaced font ISN'T the size of
the previous font, it's 1. I.E. the smallest possible size of tiny unreadable
font, yes it's an obvious bug, no they haven't fixed it in... 6 years I think?
Because every page should have a stylesheet and if it doesn't that's
just silly, even though stylesheets regularly
<a href=https://mstdn.jp/@landley/114054094876681573>make
stuff worse</a>. I note that &lt;pre&gt; tags without gratuitous micromanagement
render just fine on firefox, and I made puppy eyes at the Vivaldi guys
first time I tried using that.<p>

<p>Look: I don't know if you prefer a white or black
background for your text, why would I be making these decisions for you?
Here is some test, with paragraph breaks, links to other pages, and the
occasional bold and bulletpoint list. If your browser can't render that,
it is a CRAPPY BROWSER that's less capable than Mosaic was 30 years ago
back BEFORE netscape hired its developers away with silicon valley VC money.
(VC money: turning open source internet infrastructure into exploitative
gatekeeping spyware since William Shockley moved all the way accross the
country from Bell Labs because he was such an asshole nobody wanted to have
anything to do with him. Capitalism is a bad thing.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#24-02-2025</guid>
  </item>
  <item>
   <title><![CDATA[February 23, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#23-02-2025</link>
   <pubDate>Sun, 23 Feb 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>The tiny desk thing remains better than nothing. If nothing else, it prevents
the laptop from overheating when it's directly on a blanket. It's ungainly
and trying to get up from under it I have already spilled a lemonade (clipped
it with a wooden leg) and caused a surprising amount of laundry. Still,
soldiering on...</p>

<p>Suspend and resume fixed two finger scrolling in xfce. I have no idea what's
going on what that. (After a suspend and resume it attached the touchpad
hardware to a different driver? What, race condition or uninitialized
variable or something in the driver? Who knows. If linux-kernel wasn't
so intensely self-fellating these days I might try to track it down, but...)</p>

<p>I was curious if Tim Bird's<a href=https://www.spinics.net/lists/linux-embedded/msg04412.html>boot
log scraper</a> would run on mkroot (I.E. under toysh: spoiler yeah but
the UI is apocolyptically bad and does a complaint-reboot cycle adding
command line options and kernel boot arguments multiple times until
eventually mollified, at which point I had a large text file I wasn't
entirely clear about what to do with).</p>

<p>To get images to run this script on (and confirm that toysh _can_ run
the script, and maye use it as a test load to fix any missing features it
needed), I did a mkroot build all (mkroot/mkroot.sh CROSS=allnonstop
LINUX=~/linux/linux) in a newly cloned toybox directory, which was also
a chance to regression test the current linux-git against my ongoing
patch stack. Everything built fine but of course mkroot/testroot.sh
initially failed for all targets because I hadn't switched the
"timeout bash -c blah" to "timeout /bin/bash -c blah" because toysh has a bash
alias so it recursed into toysh, which fails to run the relevant command
line for some reason. I should track that down and fix it.</p>

<p>The first bug is that once upon a very long time ago, getval() (or whichever
equivalent I was using early in toysh's development) returned the whole
name=value string, and the current behavior just returns the value, so adding
6 to skip SHLVL= is wrong because the function I called to fetch the
data already did that for me. (This only happens in the fork/exec path, and
I've mostly been testing the nommu subshell path, so I hadn't spotted it.)</p>

<p>But there's a second bug, and ASAN totally craps the bed on it:
<b>$ ASAN=1 make clean toybox &amp;&amp; ./toybox timeout -i 10 bash -c
"root/i686/run-qemu.sh -drive format=raw,file=root/build/test/init.sqf
&lt; /dev/null 2&gt;&amp;1"</b> goes:</p>
<blockquote><p>
AddressSanitizer:DEADLYSIGNAL<br />
=================================================================<br />
==20711==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x7f2c7659de7e bp 0x5e24a6a36a05aade sp 0x5e24a6a36a05aade T0)<br />
==20711==The signal is caused by a READ memory access.<br />
==20711==Hint: this fault was caused by a dereference of a high value address (see register values below).  Disassemble the provided pc to learn which register was used.<br />
AddressSanitizer:DEADLYSIGNAL<br />
AddressSanitizer: nested bug in the same thread, aborting.<br />
AddressSanitizer:DEADLYSIGNAL<br />
[Repeat twice more with different numbers]<br />
AddressSanitizer: nested bug in the same thread, aborting.
</p></blockquote>

<p>There are no threads. Toybox is not a threaded program. It forks and
backgrounds processes, but they are NOT THREADS.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#23-02-2025</guid>
  </item>
  <item>
   <title><![CDATA[February 22, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#22-02-2025</link>
   <pubDate>Sat, 22 Feb 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=health>
<p>I've been variants of under the weather for over a month (the stress
isn't helping), and haven't even gone
out to the apartment's front office since... new year's? Nor have I done
a lot of sitting at the kitchen <strike>table</strike> counter-island-thing,
because it's not very confortable
(tall thin chair, doesn't really work for me), nor the desk in the bedroom
(less uncomfortable, but still kind of terrible and I find the room
claustrophobic.)</p>

<p>I currently have whatever cold Fade spent saturday through tuesday home sick
with. (Monday was Not My President's Day and Tuesday was a snow day, so she
got a 4 day weekend to be sick without having to use PTO for it. Wasn't HAPPY
about going back to work on wednesday, but was capable thereof.) This is a
different sickness from the one she had a couple weeks before that where she
only managed to work 2 days out of 9, the rest being basically bedridden.
Winter in Minnesota! And a public schoolteacher taking light rail to a bus to
a half-dozen rooms full of small children each day tends to pick up ALL
the colds. (Her employer warned her this would happen her first year, until
her immune system ramps up to cope with an endless stream of small children.)
At least it's warmed up enough it's not quite so BRUTALLY dry in here...
merely painfully dry. Anyway, I been sick.</p>

<p>Fade had a tiny little wooden desk thing (it's a shelf on two folding legs)
that she tried to use for her laptop on the bed, but the dog didn't like it
(it dampened his cling). I've fished it out from under the bed and am trying
it on the couch. It's... better than nothing?</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#22-02-2025</guid>
  </item>
  <item>
   <title><![CDATA[February 21, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#21-02-2025</link>
   <pubDate>Fri, 21 Feb 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I am tired and sick and grumpy. Fairly certain these are related.</p>

<p>Dreamhost wants money. They do this every 2 years, and given how often I
lose/cancel debit cards they probably wouldn't keep a payment method on file
if I DID give them one, so I tend to mail them a check. And every time I
have to look up how to do that again, and they do NOT make it easy to find
because it's not how they want stuff to go. I have been unable to find
instructions on their website this time, and google is utterly useless
now (I expect the AI feature would HAPPILY suggest a way to do that if
I ever did a search that didn't end -ai these days, but I would NEVER
send money to its suggestion), and Dreamhost's web page has a chatbot that
tries to answer my question, fails, asks if I want a human, and then
says humans are available monday through friday starting at 9am. Oh well,
try again during normal business hours I guess...</p>

<p>Either LInux or Xfce randomly broke two finger scrolling. Digging into it,
the problem is xfce's control panel is seeing two mouse sources: an
ALPS GlidePoint touchpad (which has a two finger scrolling option in the
touchpad tab, which is enabled), and an ALPS mouse, which does not have a
touchpad tab. If I disable the "mouse" entry, the pointer freezes. If I
disable the GlidePoint entry, there's no difference.</p>

<p>I'm not entirely sure when this broke, but it worked until recently.
I didn't do anything obvious to break it. Thunderbird's UI is terrible enough
as it is (I can't figure out how to get XFCE to give me the little move up/down
by one line arrows at the end of scrollbars back, I had that before the forced
version "upgrade" from Devuan Bronchitis to Devuan Diptheria but it no longer
seems to be availiable because removing stuff is considered progress.</p>

<p>I note that hexchat still has the up/down arrows on its slider bars,
because it's not using xfce's default window manager toolkit preferences.
Which in this case is a good thing because I want ALL my apps to behave
like hexchat is behaving. I wouldn't miss two finger scrolling if I had the
darn up/down buttons back. (Clicking in the empty space int he slider
above/below the grab thingy jumps by more than a full screen, meaning
it misses entries. Open source development
<a href=notes-2010.html#13-08-2010>cannot do</a>
user interface design.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#21-02-2025</guid>
  </item>
  <item>
   <title><![CDATA[February 20, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#20-02-2025</link>
   <pubDate>Thu, 20 Feb 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Ken Burk had backups my the 2015 ELC talks, and sent me copies of my
<a href=/talks/elc-2015-shrink-c.mp4>shrinking C code</a>
(<a href=/toybox/cleanup.html>outline</a>) and
<a href=/talks/elc-2015-toybox.mp4>toybox status update</a>
(<a href=/talks/celf-2015.txt>outline</a>) talks!</p>

<p>Thank you! (I poked Tim Bird in case he wants to get any of the others
back online...)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#20-02-2025</guid>
  </item>
  <item>
   <title><![CDATA[February 19, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#19-02-2025</link>
   <pubDate>Wed, 19 Feb 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Over on the gnu/coreutils gnu/mailman gnu/list somebody claimed the linux
kernel's mineral rights for Richard Stallman, and while trying to write
a <a href=https://lists.gnu.org/archive/html/coreutils/2025-02/msg00011.html>civil
reply</a> I cut and pasted this out as too inflammatory for that list:</p>

<blockquote><p>
<p>You realize that Stallman's entire rationale for sticking gnu/ on stuff was to claim credit for the larger system, because it's not like Coherent shipped the first full Unix clone 3 years before Stallman announced the FSF, BSD Net-1 shipped a year before Hurd (after starting work in either 1976 or 1974 depending whether you credit Bill Joy or Bob Fabry), and of course Linus developed his own kernel under Andrew Tanenbaum's Minix and announced it on comp.os.minix).</p>

<p>No, clearly nobody ever thought of cloning Unix except Stallman, and therefore it was his gnu/idea. Because
<a href=https://web.archive.org/web/19980126185426/http://www.gnu.org/gnu/linux-and-gnu.html>his attempts</a>
to get people to stop calling it "Linux" at all failed back in 1998.
(And when I read that page back in 1998, sadly I tried to
<a href=https://web.archive.org/web/20050308143436/http://www.kerneltraffic.org/kernel-traffic/kt20020805_178.html#1>explain marketing</a> to RMS,
which did not go well.)</p>

<p>Interestingly, Stallman himself said in the above ("his attempts") link that
the first Hurd based system shipped in 1996, but Linux not only came out in
1991 (0.0.1 booted and ran) it already had its own mailing list
(here's a few selected interesting posts from
<a href=https://www.landley.net/history/mirror/linux/1991.html>1991</a>
and <a href=https://www.landley.net/history/mirror/linux/1992.html>1992</a>),
having migrated off comp.os.minix when professor Tanenbaum got back from
summer recess and objected to the off-topic project culminating in the
famous <a href=https://www.oreilly.com/openbook/opensources/book/appa.html>Tanenbaum-Torvalds debate</a>.
(There's no similar Stallman/Torvalds debate because Stallman didn't matter.)</p>

<p>Tanenbaum declared Linux as off-topic on his list because while it used
Minix's filesystem format and compiled under minix, Tabenbaum did not claim
ownership of Linux. He acknowledged it was a separate project, needing a
separate discussion list. Meanwhile Stallman, who never submitted a patch
to Linux or even put out a Linux distro, seamlessly transitioned from
railing against Linux (insisting the Hurd would replace it) to retroactively
trying to claim credit for Linux, and politically "embrace and extend" it
ever since. He's also been keen to recapture errant forks such as glibc
from Ulrich Drepper (see "And now for some not so nice things" at the
end of <a href=https://web.archive.org/web/20030113121417/http://sources.redhat.com/ml/libc-announce/2001/msg00000.html>this release announcement</a>),
or recapturing gcc from egcs with that "steering committee" business...</p>

<p>And now you're sticking GNU/ explicitly onto the _kernel_. I'm sure
Alpine Linux (based on busybox) or Android (no GPL in userspace)
would be happy to receive such a "correction".</p>
</p></blockquote>

<p>Along the way I stumbled upon <a href=https://oliverkwebb.github.io/articles/gnulist/>Oliver's page</a> on this stuff, which is quite good (and I
could probably add a dozen things to). I feel REALLY BAD about not being
able to properly harness his enthusiasm. It's a me problem, and I know it.
It seems like the kind of thing that could easily spin into the toybox
version of Alpine Linux if I'd played my cards right, but I just don't have
the skillset and have been curled into a ball at the prospect of "what the
Boomers are going to break next" since moving out of Texas because politics
and climate change had made staying untenable.</p>

<p>And then on my SECOND attempt at writing a civil on-topic reply,
I cut THIS out and pasted it here, again as too inflammatory.</p>
</span>

<blockquote><p>
<p>The kernel Linus started on comp.os.minix using the minix filesystem and compiling it under minix, which got its own mailing list in 1991 after the "Tanenbaum-Torvalds debate", 5 years before the first Hurd-based system shipped?</p>

<p>Systems built under LLVM (as Android's been doing since 2015) using another libc (like musl or bionic or bsd) can be built and run without a single line of gnu/code in them. Alpine Linux uses busybox, Chimera Linux uses uses BSD userspace, etc.</p>

<p>This is often done to avoid GPLv3 (and in Android's case even GPLv2, hence the lack of busybox). Or for performance. Or <a href=http://lists.landley.net/pipermail/toybox-landley.net/2020-July/011898.html>various</a> other
<a href=https://oliverkwebb.github.io/articles/gnulist/>reasons</a>.</p>

<p>Are you claiming Stallman invented the idea of cloning Unix? Because Coherent
shipped the first full Unix clone in 1980, and BSD development started in
either 1974 (under Bob Fabry) or 1976 (under Bill Joy) depending how you want
to count it. Andrew Tanenbaum responded to AT&amp;T's 1983 licensing policy
change (enabled by the Apple vs Franklin decision) by starting work on Minix
even before Stallman announced he was gonna gnu, and he finished it and sent
it to his book publisher to stick on a floppy in the back of a textbook in
1986, having written his own kernel, compiler, and userspace in 3 years.</p>

<p>(There were lots of others, even Dos 2.0 was all about adding Unix features to a CP/M clone and I actually _used_ Vax "Eunice" as a child. The concept of "subdirectories" came from Unix. Stallman was not on the Posix committee, and while wikipedia's been edited to include his claim to have named the Portable Operating System unix project "POS-IX", you'll note the "citation needed". Similarly, when I drove to Boston to interview him for computer history research in 2001 he told me (in person, to my face) that he gave the BSD guys the idea of shipping their own operating system, which Kirk McKusick actually laughed at when I relayed it to him at Ohio LinuxFest in 2013. Stallman tends to retroactively insert himself into stuff.)</p>

<p>And now you're saying "GNU/Linux kernel". Really.
<a href=https://www.youtube.com/watch?v=PaKIZ7gJlRU>This was 10 years ago</a>.
Stallman didn't write GPLv2, Eben Moglen did. Linux used libc5 first.
The driving force behind gcc development (making it better than pcc or
minix's compiler or any of the MANY others available at the time) was
Sun's VP of Marketing Ed Zander unbundling" the compiler from the base
OS during the SunOS-&gt;Solaris migration (which was about AT&amp;T
shaking down vendors with IP claims and forcing them to switch from BSD
to System V codebases, as explained in Red Hat co-founder Robert Young's
book "Under the Radar") and selling the compiler and command line tools
like "tar" as add-ons you had to pay extra for.) That had NOTHING to
do with Stallman, he was hoping Project Jupiter would ship as a PDP-10
successor so he could keep maintaining MIT's ITS, he only retrenched to
Unix when his previous project FAILED.</p>
</blockquote>

<p>Sigh, there's a <a href=https://landley.net/notes-2010.html#19-07-2010>2010
rant</a> on this already. (Which was itself a sequel to the earlier
history posting that links to at the start...)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#19-02-2025</guid>
  </item>
  <item>
   <title><![CDATA[February 8, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#08-02-2025</link>
   <pubDate>Sat, 08 Feb 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I keep thinking shell trap handling works differently than it actually does.
Interactive shell editing is NOT interrupted by trap handlers:</p>

<blockquote><p>
$ trap 'echo hello' USR1<br />
$ (sleep 1; kill -s USR1 $$)&amp;<br />
[1] 5531<br />
$ so now what<br />
hello<br />
bash: so: command not found<br />
[1]+  Done ( sleep 1; kill -s USR1 $$ )
</p></blockquote>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#08-02-2025</guid>
  </item>
  <item>
   <title><![CDATA[February 7, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#07-02-2025</link>
   <pubDate>Fri, 07 Feb 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=politics>
<p>Curled up in a ball for another week. I was functional-ish while caring
for Fade, but now she's back at work and the Circular Firing Squad is of course
causing yet more collateral damage. (The Boomers will die, and thus stop
voting for every nigerian prince email and scam phone call. The crazy 27%
is just a tie breaker, without the Boomers they go back to being a shouty
minority. A <a href=https://mstdn.jp/@landley/113959903731769417>78 year old
man</a> with Progressive Supranuclear Palsy
<a href=https://www.ssa.gov/oact/STATS/table4c6.html>will die</a>
(and xi is 71, and putin is 72). A cult of personality is not transferrable.
Florida is already uninsurable and will be uninhabitable soon. The EU as a
whole generated <a href=https://youtu.be/Wjf7SA2LCzw>more electricity</a>
from solar than from coal last year. Oligarchs only die of natural causes
when they DON'T stir the pot. The rubble can be rebuilt around
basic income, subsidized food and housing (instead of subsidized fossil fuels
and suburbs), a proper right to privacy, and
a policy of guillotining anyone who retains control of a billion dollars
longer than 30 days. Dave Barry predicted Boomerdamarung back in 1996.
The Boomers will die.)</p>

<p>I've spent so much time wearing headphones (listening to distractions)
that I've developed an ear infection and had to stop wearing them for a bit.
Quite possibly just a zit I picked at too much, but still. Alas, earbuds
still cover it and I want it to heal, so...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#07-02-2025</guid>
  </item>
  <item>
   <title><![CDATA[February 4, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#04-02-2025</link>
   <pubDate>Tue, 04 Feb 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>If kexec needs to work from a single processor kernel (because I can't
figure out how to get the second processor back into the power-on state,
and I don't want to edit the turtle board startup code to handle two cases
which each get half as much testing), then I need to be able to power
cycle the Turtle board to get it to reload that UP kernel from which
I can kexec the new kernel I want to test. That way, I can set up a remote
test environment where I can boot a newly built kernel without sneakernet.</p>

<p>I know USB hardware can do this: I've read the specs and gone through low
level programming registers for various hardware. The host can cut power
to a device and restore power to a device. But it looks like Linux
can't, because it did not occur to the Linux kernel clique that intentionally
power cycling a USB device from software is a thing anyone would ever want to
do.</p>

<p>It looks like there potentially
<a href=https://www.kernel.org/doc/Documentation/usb/power-management.txt>used
to be support</a> but it was "improved" away. (Or at least attempts to
write 0 and such to the control thingies under sysfs all say
"illegal write: invalid argument" from sudo /bin/bash's echo, but they
accept "auto" which is the default value and apparently the ONLY value so
why does the knob exist...)
And the <a href=https://www.baeldung.com/linux/control-usb-power-supply>various</a>
<a href=https://askubuntu.com/questions/1338682/is-it-possible-to-disable-usb-port-with-known-physical-location>suggestions</a>
<a href=https://www.reddit.com/r/linuxquestions/comments/1dq4ha3/how_to_turn_off_power_to_a_usb_port/>online</a>
about how to set the autosuspend timeout to 1 millisecond or unbind
drivers from the device are both A) useless (the LEDs on the board stay on,
it is clearly still getting power) and B) persistent (it doesn't work as a
serial device anymore despite unplugging and replugging it, I think I need
to reboot my laptop to get that back). They've replaced manual "do this"
switches with automatic transmission nonsense that does the wrong thing
in 5 different ways, all behind a black box.</p>

<p>All this is DESPITE the USB fan I was plugging into the thing when
programming at the UT geology building's picnic tables (in the dead of summer
when it was still 90 degrees at 2am) breaking a couple years back because
Linux would power it down after 30 seconds despite being a dumb device like
a USB book light. So the device I did NOT want to power down would power down,
and the device I _do_ want to power down can't be powered down. The 6.x
kernel! Knows better than you do, and will not let you gainsay its
decisions.</p>

<p>I'm trying to get a "cursor up, press enter" style compile-and-test
out of my turtle board, like I have with qemu. If I have to stop and fiddle
with hardware then the friction of testing on turtle is way higher than testing
in the emulator so I won't do it as often. (I know me.)</p>

<p>This is why I want kexec, so the kernel that loads from the sdcard doesn't
have to be the kernel I'm testing. It's best to have a known good kernel
boot first anyway, so I have easy recovery if I send it something that
didn't work: if I was replacing the boot kernel on the sdcard and I gave it
a bad one, I'm back to popping the card out and sneakernetting it back to
the host to do recovery, and that's a pain. Being able to power cycle the board
if I gave it a kernel that hangs is also generally good for test cycling:
I need USB to be able to switch the board off and back on.</p>

<p>The rest of the stuff seems like a solved problem, if a bit awkward.
The USB connection provides a serial console through which I can easily
transfer files to the remote board via uuencode/uudecode and similar,
so they wind up in initramfs without having to go to flash at all, avoiding
wear and tear on the finite planned obsolescence technology capitalism moved
us to (storage that wears out with use so you have to buy more). Power cycling
the board means the Association of Computing Machinery serial port
(/dev/ttyACM0) goes away and comes back, so I have to re-bind microcom
or similar to it, but that all seems scriptable. (With sleeps and/or spinning.)</p>

<p>If it plugged into a wall outlet I could buy any number of "smart outlet"
variants with bluetooth or serial connections for doing exactly
this. But the problem is this USB connection also provides the serial
port I want to talk to the device through. The problem is modern Linux
kernels are _less_ capable than $15 crap from digikey.</p> 

<p>Sigh. I'm going to wind up buying an outlet-powered USB hub just so I
can power cycle THAT with a software controllable wall outlet, aren't I?
Because the Linux kernel clique is too focused on rusting the kernel to
pieces rather than actually letting people control the hardware.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#04-02-2025</guid>
  </item>
  <item>
   <title><![CDATA[February 3, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#03-02-2025</link>
   <pubDate>Mon, 03 Feb 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>One problem is kexec.c didn't redo the crt0.c setup from the bootloader,
so when it enters the new kernel the inherited stack pointer is pointing into
unclaimed memory and the registers aren't in a known state. That's probably
part of the problem.</p>

<p>I still need to do my hello world kernel spinning writing to the serial
port, because I need to stick printf() into stuff to debug things. When
I can move the printf() I can see incremental progress. Without that
it's just throwing darts at a bullseye and hoping to get lucky.</p>

<p>By the way: <b>sh2eb-linux-muslfdpic-cc --static -s kexec3.c &amp;&amp;
toybox uuencode kexec &lt; a.out | xclip -sel c</b> and then in the
turtle board run uudecode with no arguments and paste the clipboard into the
terminal. Easy way to fling a binary onto the board via serial console. Of
course this would be more convenient if running the binary DIDN'T brick the
board and require me to power cycle it each time, but for NORMAL
compile-and-test cycles on an embedded board, that's an old trick and
part of the reason uuencode/uudecode is in toybox.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#03-02-2025</guid>
  </item>
  <item>
   <title><![CDATA[February 2, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#02-02-2025</link>
   <pubDate>Sun, 02 Feb 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>The kexec I wrote for turtle doesn't work yet.</p>

<p>The first problem is putting CPU1 back into the state the kernel expects
isn't really possible with this hardware. At power on, CPU1 starts in a
perpetual memory read stall with the Vector Base Register set to 0, and you
have CPU0 poke a register to unblock it, at which point it runs a reset
interrupt loading PC from vbr[0] and SP from vbr[1]. The turtle SOC maps a
small SRAM at physical address 0 (ouch) so Linux SMP bringup just has to
write two pointers to the zero page and poke the unblock register.</p>

<p>Note that this stall unblock register is NOT in
<a href=https://github.com/j-core/jcore-soc/blob/master/targets/boards/turtle_1v1/board.h>board.h</a>,
it's memory mapped off in la-la land. It's mentioned in
<a href=https://github.com/j-core/jcore-soc/blob/master/targets/boards/turtle_1v1/board.dts#L31>the bootloader
device tree</a>
but it's not a properly documented hardware block. So that's nice.</p>

<p>The problem is, when SMP Linux is already up I can run code on CPU1
(using the same taskset+SCHED_RR trick I use to take over CPU0), and I can
lobotomize the interrupt controller (typecast DEVICE_AIC0_ADDR from board.h
to (unsigned *), then aic[0] = 0 to stop the Programmable Interval Timer,
and aic[3] = 0 to mask IRQs, although in this case I'd probably want to use
DEVICE_AIC1_ADDR to write to CPU1's interrupt controller instead). And I
THINK I can even put CPU1 back into the stall state (write a 0 into the
control register). But I can't call a reset interrupt from assembly, it's not
a normal raiseable interrupt.</p>

<p>What I need is for CPU1 to go into the read stall WHILE trying to run the
reset interrupt. It should block trying to read the PC from memory location
0. Otherwise, when it unblocks it's going to read the next instruction
from wherever PC points to and try to execute it, and when I hand off to
the new kernel no area of memory is guaranteed not to get rewritten (not
even that zero page), so whatever PC points to is unprotected. (The most
precise control would be to have CPU1 do the stall poke, but then it would
try to advance to the next instruction when unblocked. I might be able to do
Branch Delay Slot shenanigans to have that advance go anyway, although in
that case (possibly ANY case due to CPU pipelining?) it would read and decode
the next instruction from the old memory contents before hanging trying to
do a read from more memory at some point down the line. (It's a 5 stage
pipeline, instruction read is always at LEAST one clock ahead of execution.)</p>

<p>In theory there's a design element to fix this! Jeff thought about it,
and if you write 7 (bottom 3 bits set) to that PIT control register in AIC,
it should reboot that processor. Unfortunately, the contractor who implemented
it didn't hook that reset line UP to anything. (It raises a reset line that's
not plugged in. Great. Well we never tested this in FPGA, that was an ASIC
feature. Different SOC layout.)</p>

<p>I can change the vmlinux bringup code to take control of CPU1 via an IPI
(have the reset vector go to an infinite loop and then the IPI jumps us
to the real entry point), but changing the kernel's bringup for kexec is
a bit dodgy.</p>

<p>So I punted on all that and built a non-SMP kernel, and just wrote
a very simple KEXEC that doesn't mess with CPU1 at all. That way you can
have a simple stage 2 bootloader (UP linux) that hands off to an SMP kernel,
and CPU1 is in the state it's been programmed to bring up. Just load the
kernel into memory, SCHED_RR ourselves, disable AIC0, do the ELF relocation,
and jump to the entry point. The downside is you can't kexec from the REAL
kernel (yet anyway), and to do automated boot tests you'd need to be able
to power the USB port down and back up to forcibly reset the board
(there's likely a /sys/bus/usb thingy I can poke at, the fact /dev/ttyACM0
goes away and comes back each time this happens is awkward but a script can
work around it).</p>

<p>And it hangs. No further output from the board. Which is always the most
annoying kind of thing to try to debug.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#02-02-2025</guid>
  </item>
  <item>
   <title><![CDATA[February 1, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#01-02-2025</link>
   <pubDate>Sat, 01 Feb 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<p>I got older again. Happens every year. Odometer ticking over...</p>

<p>I considered baking myself a cake, but wasn't up for it. I looked up an
orange bread recipe. (Well, three of them and averaged them out.) Might
try to make that, but it calls for two oranges and Fresh Thyme wants half
a kidney per orange right now. (It has a "free for kids" bowl of tiny oranges
and bananas in front of the sushi display, but that would be cheating.)</p>

<p>Back when I first moved to Austin in 1996 I found a SUPERB
orange bread recipe on yahoo, and had a printout magneted to the fridge for
a while but lost the piece of paper (thinking I could always print it out
again) and could never track down the URL again. It was a simple quick bread:
orange juice, flour, baking something (I can never keep powder
and soda straight), possibly a bit of salt, MAYBE another dry ingredient?
And the second time I made it I added a shot of lemon juice (which was
a suggestion, along with poppy seeds which I didn't because I don't socially
know any vampires who aren't allergic to citrus). I recall being impressed
there wasn't any liquid other than the orange juice (no eggs, milk,
water...) and the instructions were very explicit about stirring JUST enough
to moisten the ingredients and NO MORE. (I think it suggested folding it over
like meringue, in fact. I had to look up what that meant.) But alas my attempts
to recreate it since without ratios or cooking instructions resulted in an
inedible brick, twice.</p>

<p>Or I could just go to target and get a box of spice cake and a tub of
cream cheese frosting, which always seems way fancier than it is. But Fade
is usually more enthusiastic about cake than I am and she's still sick.</p>

<p>Fade got me a second humidifier for the living room (bringing the apartment's
total to FIVE running at once). It is RELENTLESSLY dry here when the heat's
on, and I've found that when I get sufficiently dehydrated A) I stop being
thirsty, B) all my joints ache, C) my skin becomes very easily nicked and
abraded (my knuckles look like I've been in a fight because of getting oven
mitts and such out of the kitchen drawers). Being able to feel 15 years
younger by downing two cans of Arnold Rimmer's half-lemon tea (reasonably
priced at Aldi's, although the "lite" version is still 80 calories of sugar
per can) is... disturbing. Better than NOT being able to do that, I suppose.</p>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#01-02-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 31, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#31-01-2025</link>
   <pubDate>Fri, 31 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>The new ELC call for papers came out, and I find I have nothing I want
to say to the community. I'm happy to learn go, zig, oberon... I would LOVE
more excuses to do lua. But the last version of the kernel I can patch rust
out of is the last version I run. (And python 3 goes in the GPLv3 bucket:
you can pay me to do it, but never for free.)</p>

<p>Fade was out sick wednesday and thursday (teaching tuesday trashed her voice
to full laryngitis), and is in today so she doesn't fall TOO far behind
then has the weekend to recover. I still haven't fully recovered from whatever
this is either (cough cough), but am doing my best to be a dutiful wife
for the breadwinner of the house.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#31-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 30, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#30-01-2025</link>
   <pubDate>Thu, 30 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Had a long call with Jeff walking through the turtle VHDL code, and I
think I understand the pieces needed to implement kexec now. Or at least
we tracked down the answer to all the questions I knew to ask. (Half the output
of this should be BETTER DOCUMENTATION.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#30-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 28, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#28-01-2025</link>
   <pubDate>Tue, 28 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Fade took monday off, but has now gone back to work. Where was I...</p>

<p>So I was adding sh_fcall layers from the signal handler, but that meant
two consecutive references to TT.ff might not refer to the same structure
instance, and about halfway through triaging all the call_function()
instances to make sure we were consistently using the returned pointer
rather than fiddling with TT.ff to initialize the new object, hit the
one in run_command() and traced through the use of the "prefix" variable
and just went "this is not sustainable" and changed to having a separate
linked list of pending signals which the handler appends to (registered
to be called with all signals blocked until it returns so two handlers
don't interfere with each other) and then run_lines() processes under
sigprocmask(sigemptyset()) as the other half of the locking.</p>

<p>This of course meant I didn't NEED all the changes to make sure sh_fcall
initializers were using the returned value instaead of the global list
pointer, and backing them out was where I transplanted the cleanup work
I was doing to run_command() over to the _previous_ checkpoint (in the
toybox/toybox directory, as apposed to its extension in toybox/clean3).</p>

<p>Which means the "TT.signal" value I added and nobody uses can go away
again because that was my first stab before going "no, I can leave THAT
signal blocked until the loop handles it but I can't leave all the OTHER
signals blocked, so this needs to be a list of signals seen, meaning I can't
trust atomic assignment but have to make sure signals are disabled in
both places the list is modified".</p>

<p>This is fundamentally the same problemthat adding to TT.ff had, but
that list also has a bunch of USERS that could be inconvenienced by the list
changing out from under them, and the new list has no existing users who
aren't being, sigh: essentially thread-safe, about it. (I can DO threaded
programming. OS/2 was heavily threaded, SMP in the kernel is "threaded but
slightly worse", and realtime programming on bare hardware is often the
same general mindset. I just don't WANT to when I don't HAVE to, it's like
introducing nuclear isotopes into an engineering project: containment is key,
if it spreads all over the place it will not end well, and it's so much
easier to just not go there in the first place. This still ISN'T threading,
meaning all libc internal locking nonsense isn't necessary. Signal handling
already has its own rules about what is and isn't safe to call from signal
context. So does vfork() child context, just generally not as explicitly
documented. :)</p>.
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#28-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 25, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#25-01-2025</link>
   <pubDate>Sat, 25 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Current status: doing "<b>diff -pu file1.c file2.c | nl | less</b>" to work
out the line ranges so I can do (as it turned out) <b>diff -pu ./toys/*/sh.c
../toybox/toys/*/sh.c | sed '3,28d;132,$d' | patch -p1</b>" and yes the
./ on the first argument was so patch -p1 had the appropriate number of
directory levels to eat. (I _could_ have added enough to match the other
one, but it tries both and takes either one that works.)</p>

<p>Because it's easier than manually editing the patches, that's why.</p>

<p>What happened was I was in the middle of a largeish structural change
to a file, encountered a hunk of code I really needed to clean up to reason
through how it worked (another way to say it is that reasoning through how
it worked suggested multiple simplifications, mostly leftover scar tissue
from before the most recent round of changes) and then I wanted to check in
just that part because the change was getting huge and it's good to have
checkpoints. So I diverged into trying to split up a large change, which
is itself a lot of work.</p>

<p>*shrug* The usual.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#25-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 24, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#24-01-2025</link>
   <pubDate>Fri, 24 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<p>Fade has my cold, which says it's a cold and not just "four humidifiers are
not enough" dryness from the building's heating trying to keep up with
the loss of the polar vortex. (The northernmost layer of jetstream used to
contain the freezing air up north. Now it's gone intermittent which lets
bursts of arctic cold leak out. It apparently first collapsed
<a href=https://en.wikipedia.org/wiki/Polar_vortex>in 2014</a>
and has been unstable ever since. Yes, this is because global warming.)</p>

<p>It's a pet peeve of mine: people keep saying "we're having a polar vortex"
and no, the problem is we're NOT having one. That's why the cold that should
be UP THERE is instead DOWN HERE. It's about the same as trying to cool
yourself on a hot day by leaving your refrigerator open: you get a cool breeze
but all the food goes bad. Any snow/ice added down _here_ will
be gone by june, meanwhile the permafrost isn't and the glaciers aren't
reforming after another summer of melt. THAT'S how blizzards in texas are
a sign of global warming.</p>

<p>I wonder if Florida will submerge fast enough to drown the invasive
pythons? Probably not. Most snakes can swim.</p>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#24-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 23, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#23-01-2025</link>
   <pubDate>Thu, 23 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Trying to do kexec for j-core (turtle boards), because it
<a href=https://www.spinics.net/lists/linux-sh/msg66327.html>came up recently</a>
and I think the guys in japan could use it too. It basically lets us
use Linux as a stage 2 bootloader, so you can just power cycle a turtle
and feed it a kernel+initramfs+cmdline (and maybe dtb) so test cycles
don't involve sneakernet but could be done entirely remotely/automatically.
Heck, you could feed it a tarball over serial console, or have the builtin
ethernet wget something from a web server. You have linux running
arbitrary initramfs as your secondary bootloader.</p>

<p>Since this is a nommu board, I can theoretically do all this from
userspace, although it's a bit awkward. Jeff pointed me at the existing
bootloader code that loads an ELF image: basically just a series of flash load
commands that grab the header, confirm it looks like the right kind of ELF,
iterates through the program header segments
loading each PT_LOAD entry into memory at its p_vaddr, copying p_filesz
many bytes from storage and zeroing from the end of that to p_memsz.
(Presumably bss has a zero filesz?) If I pass a vmlinux pointer in RAM
the result is just an ELF32_Ehdr typecast at the start, a for loop over
Elf32_Phdr array, </p>

<ol>
<li>Verify the ELF header looks good</li>
<li>Make sure the code is running on CPU 0</li>
<li>Halt CPU 1</li>
<li>Stop the PIT and AIC (timer and interrupt controller)</li>
<li>Load the ELF segments and zero bss.</li>
<li>jump to entry point</li>
</ol>

<p>The ELF header check and relocation are easy enough to port from the
bootloader code, the big change is swapping out the flash_load() calls with
memmove() calls, although I simplified it a bit.</p>

<p>The relevant guts of taskset for putting ourselves on CPU0 is just
<b>long x = 1; sched_setaffinity(getpid(), sizeof(x), &x); usleep(100);</b></p>

<p>The header check is making sure it's the right kind of ELF and e_phnum (the
program header count) isn't more than 4 segments (presumably code, data,
rodata, bss).</p>

<p>The relocation iterates through the program header segments
loading each PT_LOAD entry into memory at its p_vaddr, copying p_filesz
many bytes from storage and zeroing from the end of that to p_memsz.
(Presumably bss has a zero filesz.) If I pass a vmlinux pointer in RAM
the result is just an ELF32_Ehdr typecast at the start, a for loop over
Elf32_Phdr array checking p_type==PT_LOAD and calling memmove() and
memset(), and then a void (*e_entry)(void) function pointer call.</p>

<p>I've got the header check first, the taskset, and then the relocation
code at the end, followed by the jump to the entry point. Turtle vmlinux
is conventional ELF so it's all absolute addresses, meaning I don't even
have to calculate relative to the start of physical memory or anything, just
copy and jump where it says in the file.</p>

<p>But between the taskset and the relocation is the quiescing of the old
kernel, and that's a pain. Trying to read through device tree code and
kernel's arch/sh/kernel/cpu/sh2/smp-j2.c is NOT FUN. The C code is looking
up cpu-release-addr out of the device tree, but arch/sh/boot/dts/j2_mimas_v2.dts
hasn't got that field... Ah, because the device tree it's actually USING is
the one out of the
<a href=https://github.com/j-core/jcore-soc/blob/master/targets/boards/turtle_1v1/board.dts>boot ROM</a>,
and that DOES have it (in cpu@1) which says we're writing 0x8000 to
address 0xabcd0640. But that's to ENABLE the second processor, what do I
do to DISABLE it?</p>

<p>(I could also have my kexec command fork(), taskset the child to the
second processor, renice() itself to hard realtime priority,
spin in a for (;;) loop for a quarter second, and then
call the assembly HLT instruction. Giving CPU0 time to switch off the
timer and interrupt controller. But that involves inline assembly,
asynchronous timeouts... smells a bit janky.)</p>

<p>In THEORY, stopping CPU1, stopping the interrupt controller, and stopping
the timer is three pokes.

<p>I really hope there isn't a race where an interrupt can happen the clock
AFTER we write to the AIC to disable interrupts, so we wind up in the kernel
and it can't get back OUT again, stuck in some kernel thread or something.
I don't THINK so? Question for Jeff...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#23-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 22, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#22-01-2025</link>
   <pubDate>Wed, 22 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Trying to finish the trap instruction, but it's hard to concentrate
when it's so dry breathing HURTS. (And that's _with_ three humidifers going
full time.) I can't pace the halls because THAT's so dry I have to come in
and chug a beverage after five minutes. Not doing wonders for my sleep
schedule either.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#22-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 21, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#21-01-2025</link>
   <pubDate>Tue, 21 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>My blog doesn't have comments so I get emails and/or mastodon posts,
and one of the emails replying to <a href=notes-2024.html#16-11-2024>a
post</a> said:</p>

<blockquote><p>
Kind of like how the Thumb2-base of CortexM4 patent expired, I am curious
as to whether
<a href=https://www.amazon.com/Computer-Compatible-Windows3-1-Graphics-Integrated/dp/B0D47H8V4M>DM&amp;P needed an x86 license to produce the 386</a>.
While it's been 40 years since the 386 was made, would they try to block
the manufacture of it at 22nm or 40nm in large enough numbers? (Also, there
might not be as much demand- with new generations preferring phones that
can run tiktok apps and youtube, etc...but still)</p></blockquote>

<p>To which I replied:</p>

<blockquote>
<p>Linux yanked 386 support and made 486 the baseline years ago because they wanted to assume the existence of lockless atomic cmpxchg. (Even UP kernels can take interrupts in the middle of stuff these days, and leverage the SMP plumbing to task switch out of the middle of system calls, mostly to run high priority kernel tasklets outside of interrupt context.)</p>

<p>That said a 486 might have some demand, but the thing is JIT compiling of bytecode was a big deal back in the 90s, then transmeta proved you can support foreign instruction sets relatively cheaply back in 2000, and qemu kinda took over the world translating a page of instructions at a time and keeping the cached ones around (even with the first dyngen code) and was everywhere by around 2005.</p>

<p>And of course apple had the m68k-&gt;ppc transition, the ppc-&gt;intel
transition, and the intel-&gt;arm transition each with an emulation layer
for running old binaries doing JIT-style dynamic translation of one instruction
set to another.</p>

<p>The thing about the x86 instruction set is it's a horrible hack of extension prefixes where the longest documented instruction is
<a href=https://stackoverflow.com/questions/77101149/is-vgf2p8affineinvqb-the-longest-x86-instruction-mnemonic>something like 17 bytes</a>.</p>

<p>Of course an odd byte length means means the instruction starts are not aligned, so jumps need all the bits of precision and can't cheat like other architectures do. Now ask yourself what happens when instruction decoding crosses a page boundary and requires a cache line fetch which fails and generates a fault partway THROUGH instruction decoding. There have been security thingies about that!</p>

<p>This is why nobody wants to clone an x86 chip. If you're going for big fire breathing 64 bit extensively vectorized parallel nonsense, half your chip is going to be an x86 translation and reordering pipeline (which was true back in the original Pentium) which is a recipe for security problems (like spectre/meltdown) and you'll waste tons of effort discarding speculative execution results which means power consumption sucks because you're doing a lot of work you don't keep. And if you want something small and power efficient, just do something sane like j-core and then run a dynamic translation layer to run legacy x86 binaries.<p></p>
</blockquote>

<p>I do long writeups in email all the time, I just thought I'd copy and
paste that one here because I haven't been blogging reliably ever since
the return of fascism became likely. Kinda undermines the desire to
do anything productive instead of just repeating "The Boomers will die"
as a calming mantra.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#21-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 18, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#18-01-2025</link>
   <pubDate>Sat, 18 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Toybox 0.8.12 is out.</p>

<p>I am very tired.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#18-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 17, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#17-01-2025</link>
   <pubDate>Fri, 17 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Ok, the release notes are caught up. I'm not
happy with the paragraph breaks in it (too chopped up), then again collating
different topics into a big run-on sentence isn't great either. But
that's nitpicking.</p>

<p>I rebuilt the mkroot targets against linux-6.13-rc7 and there were no obvious
differences: the same patches apply, and the same targets pass. I was thinking
of waiting for 6.13 proper but even if that does happen this sunday, with the
reichstag fire scheduled for monday I need to get this out of the way NOW,
while I can still convince myself programming has meaning. (My burst of
productivity has already shrunk to every other day. Yes the worst people in
the world are forming a circular firing squad just like last time, but
nowhere is safe to stand when that happens. Schedenfreude isn't the
same as hope, and it's hard to program productively while simultaneously
longing for a carrington event leading to kessler syndrome.) So I'm going
with 6.12 this time.</p>

<p>Of course mkroot/testroot.sh fails all the targets in a clean checkout because
I still need to manually patch the timeout line to call /bin/bash instad of
bash out of the $PATH, because otherwise toysh has an alias for bash so
toybox calls the internal command and I haven't tracked down what's going
wrong here and fixed it in toysh yet (workaround found, todo list entry
added, haven't gotten back to it yet). But I don't want to open any new
development cans of worms THIS release, and am not holding the release for
anything in toys/pending even if it IS load bearing pending. (A category
that should not exist.)</p>

<p>I need to tag a commit to build relese binaries (so --version says the
right thing), and I should check in the release notes to do so, and there's
always a bit of a chicken and egg problem here in that I want to check
in the release notes at the last possible moment in case I hit something while
cutting the release, but need the tag to build the binaries I'm
testing and uploading... Circular dependencies!</p>

<p>This is why I have a release checklist. First thing in it: make distclean
defconfig tests" which fails because of that
<a href=notes-2024.html#04-07-2024>toolchain bug</a> I hit when
I upgraded debian versions.
Right, add a release note about switching off mkpasswd to pass "make tests",
because of the debian ASAN toolchain bug breaking crypt(). (Toolchain
bug! Like pending: not holding up the release! Yes I could de-promote
mkpasswd like I did passwd, but... NEXT release.)</p>

<p>The version lives in 3 places (grumble): toys.h and www/header.html need
to match www/news.thml, but since 2 of those are documentation it's kinda
awkward to have a Single Point of Truth for that.</p>

<p>Ah: scripts/mkstatus.py (to update
the status.html page) says #!/usr/bin/python, which Devuan Deathwish
(I.E. Debian Brainworm) removed from the repository for being too useful.
(The path no longer having
"python" in it, just "python3", would be like the path no longer having
"cc" just "c++". Or just "c99" (which is what posix said to do, because
posix was fscking stupid). Nope, that's not how it works. Yes I need to move
off of python now that "python" no longer exists, and Ray Gardner did send me
an awk rewrite of the rss generator for this blog, but I am NOT fiddling with
scripts/mkstatus.py right now. (It will never be rewritten in python++. I
might do a bash version, but mostly I want to make the NEED for it go away
by finishing and promoting enough stuff.)</p>

<p>Luckily, since python was open source back when it wasn't dead,
the <a href=https://www.python.org/downloads/release/python-2718/>source</a>
and <a href=https://www.linuxfromscratch.org/blfs/view/11.1/general/python2.html>build instructions</a>
are still available, and I can feed it /usr/local/bin as the prefix because
it's easy to wipe and reinstall all that if I need to. (Mine's just got toybox,
qemu, and now python 2 in it.) I'm not adding whatever LFS's security patch was,
nor installing any optional packages... heh, autoconf didn't even find a
c++ compiler. (It's in the $PATH. Needed to build musl-cross-make toolchains.
Dunno why that faceplanted but it's apparently only needed for modules I
didn't use...)</p>

<p>Of course since I didn't install it at /usr/bin (because I'm not mixing
repository and locally compiled packages at the same level) I have to say
"python scripts/mistatus.py" but that's fine. Except THAT still fails
because despite ./configure and install knowing where it put the files,
it tries to load a shared library it can't find. (The BLFS instructions
didn't say how to statically link it.) Ok, prepend
LD_LIBRARY_PATH=/usr/local/lib and... yay, it ran.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#17-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 16, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#16-01-2025</link>
   <pubDate>Thu, 16 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Yay, the release note writing process has consumed all the toybox commits
up to the master tag! I am caught up, and can cut a release!</p>

<p>Alas, this is step one of like two dozen, and I'm tired now.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#16-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 15, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#15-01-2025</link>
   <pubDate>Wed, 15 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I've been trying to finish and commit the shell trap builtin, but I may
have to punt it to next release.</p>

<p>I want to queue up the shell function from the
signal handler, but leave the signal disabled, and only re-enable it
_after_ the shell function returns.
The recent redesign allows me to add a new sh_fcall layer with a function
call from signal context, but if you spam signals to the shell I don't
want it to interrupt the signal handler function call in the middle
with the same signal again. But I don't want to DROP them either, or at
least the same signal coming in while the signal is being handled
should probably be queued to restart (one instance of) the signal handler
at the end. (So you can still stunlock the shell with constant signals,
but not establish a BACKLOG for it to process.)</p>

<p>So what I want to do is leave the signal blocked when I exit the signal
handler. I _think_ what I do for that is use sigaction(SA_SIGINFO) and
then toggle the appropriate bit in context-&gt;uc_sigmask, because man 7
signal says the kernel restores the signal mask from that when the signal
handler returns? (How would I test this?)</p>

<p>The function to atomically re-enable the signal mask when popping the fcall
stack is sigprocmask(SIG_UNBLOCK). If I call sigprocmask(SIG_BLOCK) from
within the signal handler, would that leave it blocked when it returns?
I don't THINK so, it's already blocked in the current signal mask while
the signal handler is running and then the old signal mask is restored on
return from the function, sigprocmask() would have to know to modify the
signal mask that's waiting to be restored. I actually hit a bash bug
<a href=notes-2011.html#05-09-2011>in 2011</a> where longjmp() out of the signal handler left the signal
handler blocked, and bash was doing that and thus my shell script having
an alarm timeout left SIGALRM blocked for all children, causing 
autoconf to hang in an aboriginal linux build. (I debugged into the kernel
and back out again finding that one.) But "it used to do it this way
doesn't mean it still DOES", is something I've ALSO hit on multiple
occasions. And alas "try it and see" then becomes "Does macos have
this field of this structure with the same name treated the same way?
What does posix say? Where would this even BE in posix if it is
mentioned..."</p>

<P>Another fun corner case is the vfork() callback setting up children
needs to restore all the signal handlers to their default values, because
who knows what's blocked at any given moment.</p>

<p>And then, of course, there's interrupting/restarting builtins. The main
reason I'm NOT trying to use signalfd() for all this is I want to
make sure blocking builtins like "read" and "wait" (and for that matter
echo &gt; /dev/thing-that-blocks) get handled properly. So what counts as
"properly"? Should they abort? Restart their operation? I can't REALLY
execute arbitrary shell stuff in the same process and then return to the
middle of a shell builtin function, that's a recipe for disaster.
(Do a blocking "read i" and have a signal handler assign to i in the middle,
without leaking memory; I mean MAYBE, but...)</p>

<p>Right now everything's mostly trying to SA_RESTART so the OS restarts
the operation behind the scenes when you do things like suspend/resume
the process. Which is a signal delivery, which causes syscalls to return
short reads and -EAGAIN, and <a href=https://lkml.org/lkml/2005/3/30/171>yes
I hit this</a> years ago, and it broke stuff I had to fix. (That wasn't
even the first time, before THAT suspending and resuming pipelines could
return zero length reads that piping stuff to tar interpreted as premature
EOF. Because tar or gzip or whatever it was didn't check EAGAIN when it
got the zero length read, and wasn't doing the SA_RESTART thing that
made the kernel auto-restart instead of returning EAGAIN except (at the
time) there were times it COULD still return EAGAIN so you still had to
check! Probably all fixed now, but I was gun-shy about suspending and resuming
piped processes for years after that.)</p>

<p>Anyway, getting signal handling basically in: easy. Thinking through all
the corner cases and making sure they're covered (and working out what
the right behavior even IS): not easy.</p>

<p>So if you SIGSTOP/SIGCONT the shell while doing a "wait" it probably
should NOT return prematurely. If you kill SIGUSR1 with a trap 'echo hello'
USR1 it should presumably print "hello" immediately. The question is,
does it then RESUME waiting? Which means restarting the builtin, since that
had to return.</p>

<p>If you "echo $MEGABYTE_OF_CRAP" to something that accepts the data as
multiple short writes (like a serial port), and the echo gets interrupted
by a signal, you clearly don't want it to restart at the beginning,
just flush the REST of the data...</p>

<p>All this stuff boils down to coming up with tests that demonstrate a
corner case it needs to get right. Alas, that's REALLY HARD...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#15-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 14, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#14-01-2025</link>
   <pubDate>Tue, 14 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Trying to close things down for a release makes the todo list longer,
every single time. I've been <a href=https://github.com/landley/toybox/issues/489>reminded</a> to resurrect my diff rewrite
at the start of next dev cycle.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#14-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 13, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#13-01-2025</link>
   <pubDate>Mon, 13 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Going through and auditing the github issues and pull requests for things
I've already closed, or anything that's REALLY easy to fix. The current
process involves finding the date the commit/issue was opened, fishing
through my email archive to find the email sent to me, and doing a "reply list"
to that which goes to the magic hash that appends my comment to the
relevant discussion.</p>

<p>And I made a gitwhack.sh script that takes the number of the issue or
pull request to close as its argument (they seem to share a namespace),
prepends a "Closes #123" comment to an explanatory file about microsoft
github embracing and extending away my access to the web interface,
the commit itself being "touch dummy; git add dummy; git commit blah; rm dummy",
pushes the commit, waits 5 seconds to make sure microsoft's server side
processing gets to do all its data harvesting and AI training,
and then "git reset HEAD^1; git push --force" to expunge the commit from
the history. And a local git gc for good measure.</p>

<p>Seriously, if I'd EVER responded well to ultimatums my entire career
would have progressed very differently.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#13-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 11, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#11-01-2025</link>
   <pubDate>Sat, 11 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<p>Sigh. So one of the things I've been cleaning up with the Money Concierge
is collating retirement savings. (The fact I have ANY is because I'm at the
financially lucky end of Gen X, mostly due to a pathological avoidance of
debt since graduating college, and because Fade and I have not proven fertile
together (in a sufficiently non-obvious way that the medical establishment
gets dollar signs in its eyes at any mention of trying to track down why),
so our expenses remain low. But if I tried retiring now the money would run
out in a single digit number of years, though maybe with 10-15 more years
compounding I could live very modestly? Especially now that Fade's working
and we're no longer paying for a second residence. It would be nice if
social security still existed, but people recently voted to cash that out
and hand it all over to billionaires for some reason, so...)</p>

<p>I've been saving for retirement ever since my very first job (IBM,
straight out of college), but since I'm not a Boomer nor were my parents
rich, I had a lot of debt to pay off. I've also been part of the precariat
my entire career, meaning I've had Financial Crisis Du Jour that made me
pull money OUT of retirement savings (and pay both taxes and 10% penalty
on multiple occasions), sometimes closing the resulting account and
sometimes leaving small amounts in it. Hence lots of little accounts to
clean up. I remember when I cashed out my IBM stock long ago, a quarterly
dividend payment deposited to the account right after I'd cashed it out because
date-of-record edge case, so for years I was getting printed mail about
a fraction of a share worth less than a dollar.
I eventually sat down and dealt with that because they
were spending more to print and deliver each of those envelopes than was
in the account, and I wasn't exactly _guilty_ but... Please stop.</p>

<p>But some accounts still actually had some money, and one of them was
the old 401k (from either Pace or Polycom, both renamed themselves since
I worked there and I can't remember which is which) that
<a href=#30-06-2023>somehow expired</a> and got sold(?)
to Inspira Silicon Valley Scams, which immedately renamed itself Millennium
Trust Me Bro, which I've wanted to GET IT OFF ME ever since because DUDE (No!)
And the money concierge helped me cash that out and roll it over into my
existing pre-tax IRA at this bank, because that was the corresponding tax
status account I could put it in without having to fork over thousands of
dollars of taxes, and the money's been sitting there since not actually
invested (and thus not accumulating anything, in fact losing to inflation)
ever since because paperwork. (I refuse
to say "earning" there, the same way you don't "earn" a lottery or
insurance payout. That is not the word for what happens there.)</p>

<p>This is a pre-tax IRA, as opposed to the Roth IRA we've been putting
money in more recently. This account has been around forever:
Fade and I went down and set up matching IRAs when we first moved in
together, and neither of us had much spare cash at the time so we did the
pre-tax version that could get us a deduction, and it's more or less
coincidentally at the same bank I'm collating stuff in now (actually at
their semi-attached brokerage firm)... and it turns out the salesbeing at
the time put us in a micromanaged IRA account instead of a
self-directed one. (Probably he asked Fade what she'd prefer and then applied
it to both our accounts.) So if I were to move the money into an index fund in
this account (same as the other account), I'd suddenly owe them over a
thousand dollars in fees for the "investment advice". Which... ow?</p>

<p>I have the option to convert the account type to self-directed, and I
asked to do that, but I can't use online banking because I
<a href=notes-2024.html#20-06-2024>refuse to agree</a>
to the Binding Arbitration shenanigans (if you're not planning to screw
me over, you don't need to preemptively take away my ability to sue).
So I had them mail me paperwork, and today I sat down to sign the paperwork...
which ALSO has half a page on agreeing to binding arbitration this time.
So that's a no.</p>

<p>So I asked the Money Concierge if he can just roll it over into the existing
Roth IRA account I already have (again been there for years, grandfathered
in from before binding arbitration became scam du jour among finance bros),
and I'll just take the tax hit. (It shouldn't do the 10% penalty because
it's still in a retirement account, just tax-free compounding instead of
tax-deferred, but that means investing post-tax money so it gets taxed now.</p>

<p>The invention of the ROTH IRA was a trick Bill Clinton pulled back in the
1990's to balance the federal budget, giving people a good deal on rolling
over their retirement money into "we will never tax the interest this
accumulates ever again" status, so he could get a big one-time-hit of tax
revenue up front when the existing retirement money was rolled over (and taxed
once as income for that year), with which to balance the federal budget. And
then he KEPT it balanced once it had BEEN balanced back when shame worked on
legislators. Until George "putting the duh in W" Bush intentionally
restarted the oligarch embezzlement trough by proclaiming that the government
running a surplus (and thus slowly paying down the giant debts accumulated
by Ronald Reagan and his father Bush Sr.) meant the american people
were "<a href=https://georgewbush-whitehouse.archives.gov/news/releases/2001/03/20010308-22.html>being overcharged</a>" and he was "demanding a refund".
Which is not CLOSE to how any of this works. (We could have had
Norway's soverign wealth fund! But instead we had republicans.)</p>

<p>Anyway, that's why the Roth IRA was actually a good deal in the long
run, but a big tax hit in the short run. And it's why the money paperwork
continues.</p>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#11-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 10, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#10-01-2025</link>
   <pubDate>Fri, 10 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Huh, Elliott <a href=http://lists.landley.net/pipermail/toybox-landley.net/2025-January/030642.html>hit a thing</a>, and I don't see anything obvious in
<a href=https://android.googlesource.com/platform/external/toybox/+/main/run-tests-on-android.sh>his wrapper</a> that
would cause it? Says #!/bin/bash at the top, which should work?
It's not reproducing here, the test works for me when built with the Android
NDK. I want to help but I'm just not seeing it...</p>

<p>I went "git log master..0.8.11" which produced no output, because it only accepts
"git log 0.8.11..master". (Why not show the range in reverse order?
I know there's some sort of --reverse option somewhere, but git UI having
"good" and "bad" hardwired backwards half the time is not a new issue.)</p>

<p>And then "git --stat log 0.8.11..master" barfed and I'm going "is it --status
or something?" and read through "git help log" (I.E. man git-log) forever
until line one thousand, seven hundred, and forty six finally went
"no, it's --stat". Because it's "git log --stat" not "git --stat log",
of course.</p>

<p>I'm a bit out of practice with git, and not instinctively avoiding all
the sharp edges its UI is constructed entirely out of.</p>

<p>Anyway, time to make the release notes. (We've ALMOST got linux-6.13 out,
I should retest everything against -rc6 and wait, but if I don't get
a release out before the 20th I suspect my mental health may take a dip
again.)</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#10-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 9, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#09-01-2025</link>
   <pubDate>Thu, 09 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Mailing list threads! I mostly haven't been blogging here, instead
there's the long thread on <a href=https://lists.gnu.org/archive/html/qemu-devel/2025-01/msg00684.html>qemu-devel</a>
that eventually <a href=https://www.spinics.net/lists/linux-sh/msg66327.html>wandered
to linux-sh</a> and
and from there to private email about the turtle ethernet driver,
various posts on <a href=https://www.spinics.net/lists/linux-embedded/msg04381.html>linux-embedded</a>
about the boot time stuff that were mostly me doing
<a href=https://www.spinics.net/lists/linux-embedded/msg04389.html>unsolicited</a>
computer history <a href=https://www.spinics.net/lists/linux-embedded/msg04391.html>infodumps</a>
at people, plus some things that would
have been blogs went to <a href=http://lists.landley.net/pipermail/toybox-landley.net/2025-January/030635.html>the toybox list</a>
instead just because I've been so behind on editing and uploading entries
for so long that if I _want_ interactive feedback from people, putting
it here is kind of moot. (I <a href=http://lists.landley.net/pipermail/toybox-landley.net/2025-January/030636.html>figured the issue out</a>
on my own anyway...)</p>

<p>Been busy, which remains a bit of a relief. It's just hard to tell from the
commits and list posts because I have SO MUCH BACKLOG to shovel through
now I'm out of the rut I was in. (Off to find a NEW rut. "A whole new rut..."
to the tune of Aladdin.)</p>

<p>I think I've cleaned up the mkroot images about as much as I can at the
moment, and confirmed that at least two of the targets that still fail
require patching qemu instead of the kernel. Punt to next release.</p>

<p>Alas, musl-1.2.5 from 11 months ago is still the current release, so not
much point rebuilding the toolchains (and I need to migrate off musl-cross-make
anyway). Punt THAT to next release.</p>

<p>Sitting on my hands about more shell work before release. I've done most
of "trap" support locally, need to fix the remaining $BROKEN tests' underlying
issues and have SO many more tests in local "sh.txt" notes-to-self files. I
can probably do command editing and history now (I long ago learned that
a polished GUI makes people assume the plumbing must be all done), and
triage the TODO entries in sh.c... Ahem. Release first.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#09-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 8, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#08-01-2025</link>
   <pubDate>Wed, 08 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>In a <a href=https://lists.nongnu.org/archive/html/qemu-devel/2025-01/msg00684.html>conversation on qemu-devel</a> I said:</p>

<blockquote><p>
There are some targets I have to poke harder, armv5l and armv4tl have
QEMU="arm -M versatilepb -net nic,model=rtl8139 -net user" for some reason... Huh, apparently I've been doing that since 2007?
</p></blockquote>

<p>And digging through <a href=notes-2007.html#04-07-2007>my blog</a>
I found <a href=https://github.com/landley/aboriginal/commit/5a51e551568a>the
commit</a> saying "switch to using the rtl8139 driver because PIO doesn't work
on the qemu-system-arm PCI controller yet so I need something with mmio."
Maybe that's fixed by now and I can go back to the default network card there?</p>

<p>So hw/arm/versatilepb.c says the default is smc91c111 and the kernel driver
for that is CONFIG_SMC91X but it won't enable because kconfig has
(!OF [=y] || GPIOLIB [=y]) in one of its stanzas, so if you ENABLE device
tree support it DISABLES the driver, unless you enable some extraneous GPIO
support library I _actively_ don't want to have to care about, which
seems like it's "selected" by 8 zillion things in a horrificly micromanaged
staircase.</p>

<p>Why does this driver not have a "selects GPIOLIB" if it needs it? Why would
it have a BLOCKING DEPENDENCY that prevents the driver from showing UP if
something unrelated isn't selected, instead of just SELECTING IT?</p>

<p>This sort of cleanup is hard because I have to repeatedly prove a negative.
But minimizing variables is science, and "circle the pot widdershins three
times for luck" is alchemy. Accumulating endless dependencies is NOT
SCIENCE.</p>

<p>Anyway, <a href=https://github.com/landley/toybox/commit/65887c2f3cd8>fixed
now</a> I should copy the relevant text back into the
<a href=https://lists.nongnu.org/archive/html/qemu-devel/2025-01/msg01144.html>original conversation</a>...</p>

<p>And the TODO item that comes out of <a href=https://lists.nongnu.org/archive/html/qemu-devel/2025-01/msg01149.html>this</a> is figuring out how to
use the provided <a href=https://github.com/qemu/qemu/commit/d36b2f4e783f>example</a>
to add -hda for or1k...</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#08-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 6, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#06-01-2025</link>
   <pubDate>Mon, 06 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Nuts to your white mice.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#06-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 4, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#04-01-2025</link>
   <pubDate>Sat, 04 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>The sh4eb network thing is weird, when I sntp or wget, eth0 lists a bunch of
dropped packets, but loopback shows the same number of packets sent/received.
I don't even know how you'd screw that up, but it smells kernel-side? I also
tried qemu 9.2 and 8.0 and it behaved the same way, so probably not qemu.
Which makes sense since qemu shouldn't know what the loopback interface IS,
that's an abstraction within the kernel not emulated hardware.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#04-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 3, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#03-01-2025</link>
   <pubDate>Fri, 03 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>I hate when I bisect a problem (in this case the sh4eb kernel not seeing
qemu's emulated hard drive) to
<a href=https://github.com/torvalds/linux/commit/ff9a79307f89>a merge
commit</a>. Right, two parents, first parent works, second parent
panics during boot because "irq123: nobody cared". Use "git describe" on
that second parent to find the last tagged commit, check the tag: which works.
Bisect between the tag and the parent commit... And the breakage is
<a href=https://github.com/torvalds/linux/commit/d9a1dab65aa2>"sh: Convert the last use of 'optional' property in Kconfig"</a>
which seems like it's just mangling config stuff? Except diffing the
.config files produced by the two commits, the change is adding
CONFIG_CMDLINE_OVERWRITE=y and CONFIG_CMDLINE="console=ttySC1,115200"
which doesn't SEEM like it would cause this, but... The patch itself
is adding CONFIG_CMDLINE_FROM_BOOTLOADER=y to a bunch of defconfigs,
which is the DUMBEST SYMBOL EVER. (The default value is NOT to listen to
the bootloader, but to use a hardwired command line. That's the DEFAULT
now. You have to switch on a symbol to NOT do that. Bravo.) Ok, add the
symbol to my miniconfig to tell it not to be so FUCKING STUPID, and...
working again. What does that do to 6.12... and that's working.</p>

<p>So once again just bisecting where a new config symbol needed to be flipped.
Wheee. The network card's still borked though, although now it THINKS it's
working, but no packets are passed and attempts to use it time out.</p>
</span>

]]></description>
   <guid>http://www.landley.net/notes-2025.html#03-01-2025</guid>
  </item>
  <item>
   <title><![CDATA[January 1, 2025]]></title>
   <link>http://www.landley.net/notes-2025.html#01-01-2025</link>
   <pubDate>Wed, 01 Jan 2025 23:59:59 +0000 </pubDate>
   <description><![CDATA[<span id=programming>
<p>Fixing up the mkroot targets: microblaze's network isn't working, because the ethernet driver isn't binding.
Checking current qemu's source, qemu-system-microblaze is running
<b>-M petalogix-s3adsp1800</b> which runs the qemu source
<b>qemu/hw/microblaze/petalogix_s3adsp1800_mmu.c</b> which is pulling in
<b>qemu/pc-bios/petalogix-s3adsp1800.dts</b>,
which says <b>compatible = "xlnx,xps-ethernetlite-2.00.a"</b>
which lines up with EMACLITE from mkroot.sh's microblaze section.</p>

<p>So it's TRYING to enable the driver, but although that string is in the
miniconfig it does not wind up in the resulting
<b>root/microblaze/docs/linux-fullconfig</b>, why is that...
Grepping the 6.12 kernel source,
<b>drivers/net/ethernet/xilinx/Kconfig</b> says config XILINX_EMACLITE
depends on HAS_IOMEM, which grep does not find under arch/microblaze
at all. According to "git annotate" that dependency was added in
<a href=https://github.com/torvalds/linux/commit/46fd4471615c>commit
46fd4471615c</a> in April 2021 by Randy Dunlap to fix a build break,
and git describe --tags on that hash says v5.12-rc7, so back up to the
last release before that...</p>

<p>Huh. I did a git checkout v5.12 which SEEMS like a thinko (that's the release
AFTER that -rc7, not the one before), but the dependency isn't there in the
file and "git log" is saying the 46fd commit _isn't_ in v5.12? And doing a
"git log" from the 46fd commit doesn't find the hash for the 5.12 release.
I think there's some git branch shenanigans going on here, git describe is
finding a misleading last common ancestor. Oh well, the point is v5.12 is
a release that does NOT have the commit.</p>

<p>Alas, my first attempt at feeding the current miniconfig into 5.12 does
not give me any serial output from qemu, and rather than debug THAT let's
just build the board's defconfig... huh, <b>arch/microblaze/configs</b> only has one
file "mmu_defconfig". Microblaze was one of the first nommu targets I was
introduced to, but while this arch has a nommu build option the kernel ships
no defconfig for it. How nice. Anyway, it built, and using the run-qemu.sh
command line against the vmlinux... broke with a register dump. Try the
other endianness? That's spinning eating cpu, hung with no output.</p>

<p>This smells familiar.... <a href=notes-2024.html#26-03-2024>because
it is</a>. Except 6 months ago was 2 kernel releases back tops, so
I was trying to get something like 6.10 working, not 5.12. (Did this EVER
work for me? The downside of a year out of control is I'm not entirely sure
what my baseline was and switching debian versions and different qemu
builds underneath mkroot, it's a bit of shoveling to reestablish a baseline.)
Still, let's try firing up menuconfig and switching the endianness... nope.
The resulting vmlinux hangs for 8 seconds, _then_ barfs with "unaligned PC=12"
whatever that means.</p>

<p>Right. So if 5.12 builds the driver witout either the spurious dependency
or the reported build break, but doesn't produce serial output so I can't
TEST it, that's the classic "too many variables changed" problem of doing
science outside of laboratory conditions. I have a mostly working current (6.12)
build, let's walk back from the version I can TEST through the older kernel
versions to see where the miniconfig stops producing serial output.
(It's not "looking for my keys under the streetlamp" if I use the streetlamp
as a base camp and install a chain of mirrors to build an illuminated path
out from that to where I last saw the keys. It's just tedious. Or "systematic"
if you're feeling posh.)</p>

<p>Ok, 6.10 works, 6.5 works, 6.0 works. The 5.x series goes to 5.19 so
5.15... no output. Ok, git bisect between the v5.15 and v6.0 tags, but once
again I have to reverse "good" and "bad" because the old one is broken and
the new one is working and git calls the old behavior "good" and new "bad"
which is was always a terrible assumption. Bisect, bisect, bisect...
<a href=https://github.com/torvalds/linux/commit/8f0f265e6cf5>commit
8f0f265e6cf5</a> made it start working again, which replaced the "memset"
implementation because gcc 10 apparently introduced a stupid "optimization"
that turned providing your own memset implementation into a recursive call
to itself. (Libc is not special!) That commit went in on top of 5.18-rc1,
so how far back does the patch apply to unbreak earlier versions with current
compilers? Hmmm, it applies to v5.12 but the result still produces no output...
So bisect between THOSE, and
<a href=https://github.com/torvalds/linux/commit/f8f0d06438e5>commit
f8f0d06438e5</a> is what made it start producing output.
(Sigh: global kconfig shenanigans.) Ok, checkout v5.12 and apply BOTH those
patches to it and... I get a shell prompt! Woo! But still no network
interface. Fire up menuconfig and pull up the symbol help... it's because
of an unmet dependency on a gratuitous CONFIG_NET_VENDOR_XILINX menu guard
symbol. And NOW the ethernet interface showed up.</p>

<p>Hang on, was THAT the missing symbol back in 6.12? The gratuitous menu
guard? Yes it was, and now
the network is present there too. Kind of a long walk to get there, but
hey, problem solved.</p>

<p>So next question, why isn't -hda working...
Because the board qemu emulates has 16 megabytes of flash but no other
obvious storage devices, and no probeable busses (pci, usb, etc) to dynamically
attach storage to. So they didn't wire -hda up to anything because there's
no obvious way to dynamically insert a hard drive (nothing for it to attach to).
Sigh, I suppose it could use a network block device, but part
of what I'm trying to TEST on each of these boards is block device support.
I suspect I need another mkroot variable that's "how to add -hda" since
qemu decided to abandon -hda as a reliable user interface concept. I can
export a variable into the run-qemu (sigh at the clutter, but doable)
but how to _use_ it when everything else is just
"./run-qemu.sh -hda file.img"...</p>
</span>

<hr><h1><a href=notes-2023.html>Back to 2023</a></h1>
]]></description>
   <guid>http://www.landley.net/notes-2025.html#01-01-2025</guid>
  </item>
 </channel>
</rss>
