Rob's Blog rss feed old livejournal twitter

2020 2019 2018 2017 2016 2015 2014 2013 2012 2011 2010 2009 2008 2007 2006 2005 2004 2002


July 18, 2021

An amusing anecdote about memory leaks in missiles. (Know your environment and what your program is trying to accomplish.)

As lithium demand increases, new mining operations are scaling up. It's not exactly rare: the earth's crust has 1/3 as much lithium as copper, which is 1/3 more lithium than lead, 250 times more lithium than silver, and 5000 times as much lithium as gold. Plus lithium dissolves in water so you don't have to pan for it, just find old dry lakebeds or brine from once-large seas that concentrated the lithium for you. (And of course there's 5000 times as much lithium in the ocean as on land, but it's too dilute to be economically viable unless it's collected as a side effect of water desalination, the way cobalt is mined as a side effect of copper mining.)

Speaking of which, electric bicycles are outselling electric cars 3 to 1. If your commute is five miles or less and the weather is reasonable, an electric bike makes pretty good sense.

Sigh. I've composed a response to the hexagon guys twice and thunderbird has crashed and taken out my reply both times. (Kmail would save half-finished replies and pop the windows back up when the program restarted 15 years ago. Thunderbird is still not that advanced yet, because Mozilla.) Alright, lemme collect the info HERE and then cut and paste it into thunderbird:

They pointed me at the latest llvm binary release which continues to be dynamically linked on the host against CRAZY defaults:

$ bin/clang --help
/lib/ld-linux-aarch64.so.1: No such file or directory

Each package build in their script adds a lot of extra command line options to the compiler, and I don't know why. The clang_rt build has CMAKE_ASM_FLAGS="-G0 -mlong-calls -fno-pic --target=hexagon-unknown-linux-musl" which the documentation defines as:

I don't understand why the library needs no-pic? (Are we only building a static libgcc.a instead of a dynamic one? I'm fine with that if so, but why does this needs to be specified in the MAKE_ASM_FLAGS and what happens if you DO build -pic code that wants to use libcc?)

Why is it saying --target=hexagon-random-nonsense-musl to a toolchain we built with exactly one target type? How does it NOT default to hexagon? (Is this related to the build writing a hexagon-potato-banana-musl.cfg file in the bin directory, meaning a config file is in the $PATH? Does clang only look for it in the same directory clang lives in?)

It took me a while to figure out that clang_rt is NOT librt.a, I think it's their libgcc? Especially confusing since librt.a has existed for decades and was on solaris before it was on linux, and the OBVIOUS name is libcc the same way "cc" is the generic compiler name instead of "gcc". (In fact that was the posix compiler name until they decided to replace it with "c99" and everybody ignored them the way tar->pax was ignored, largely because make's $CC defaults to "cc" so it Just Works, and yes the cross compiler should have that name but the prepackaged clang tarball above does not. *shrug* I fix it up when making my prefix symlinks.)

Next up build_musl_headers does CROSS_CFLAGS="-G0 -O0 -mv65 -fno-builtin -fno-rounding-math --target=hexagon-unknown-linux-musl" which:

Most likely none of those flags are needed here because this is just the headers install, and this looks like it's copied verbatim from the musl library build. (Why does building librt-but-not-rt need the libc headers? The libgcc build EXPLICITLY does not require that, because otherwise you have this kind of BS circular dependency. Also, how do you EVER build a bare metal ELF toolchain with that dependency in there?

Next up build_kernel_headers has KBUILD_CFLAGS_KERNEL="-mlong-calls" which again, A) why does the compiler not do by default, B) you don't even need to specify a cross compiler when doing headers_install. (I just confirmed by diffing installs with an without a cross compiler specified: they were identical. I thought so, but checked again to be sure. Presumably more "shared wtih full kernel build".)

And then build_musl, covered above under the headers build.

Ok, email sent. Yay.


July 17, 2021

Capitalism is wobbling slightly. Which is good because capitalism is incompatible with continued human life on earth.

An excellent thread on why coddling selfish assholes is what they want and is counterproductive.

Another rich white octagenarian fascist died. Dance on his grave, and ponder the need for at LEAST 50% death taxes. (Each of your kids can have a couple million dollars which seriously is enough to set them up for life, the rest gets BURNED ON YOUR FUNERAL PYRE because we are NOT AN ARISTOCRACY.)

Because of the GOP, the pandemimc is not over. The GOP has been all about censorship since back when it was called "christianity". Defund the police.


July 16, 2021

Walked to the table at UT this morning but just didn't have the energy to do any programming. I'd just sat down to watch a Leverage episode with Fade (doing a rewatch before the new series) when Jeff called and spent an hour on the phone sucking all my energy out. I'm already paralyzed by job hunting and uncertainty about moving, and when I opened my laptop at that table there was that whole wikipedia nonsense which nobody's replied to for 4 days (the page still uselessly lists licenses the project hasn't been under for years, when gcc's page doesn't give the date it switched from GPLv2 to GPLv3 which made half its userbase abandon it and directly led to Apple and Google sponsoring LLVM development as its replacement).

And even though I finished a cut -DF patch for busybox and sent it to the mailing list yesterday morning, the busybox mailing list web archive hasn't updated? Is this an infrastructure hiccup or did google's spam filter eat another OUTGOING message? (Which it usually only does when I try to email a co-worker a windows driver for our in-development USB hardware. This is not a thing I asked Google to block, but it's unshakeably certain it knows better than we do what's good for us and offers no obvious way to contact a human.)

Sigh. I don't mind things being hard. I mind spinning my wheels.

Got a bit of traction on implementing flashcp eventually, which is fairly straightforward (it's just a couple ioctls, modulo the historical dysfunction in the linux kernel development process) but trying to come up with a test environment for it led me down the path of qemu's "-mtdblock filename" option, which turns out to be useless because although you can define it anywhere it only shows up on boards that have mtd hardware in their board profile (or device tree?), which none of the qemu board emulations I've currently got kernels for do.

So I looked at the "block2mtd" driver, which is undocumented so you have to read the source, and said source has its own inexplicable failings where it's allocating space for "device_name,erase_size,timeout" and then only parsing the first 2 of those. It initializes a local variable "unsigned long timeout = MTD_DEFAULT_TIMEOUT;" (#defined as 3) and then never writes to that variable again until it passes it to add_device().

I keep meaning to do a talk "how to bloat code" where I take a simple hello world program and incrementally expand it to over a thousand lines long with "good programming practices" like container structures and generic base classes and get and set methods and error checking for parameters that we're only ever passing to ourselves... this has some of the classics:

(One of the themes here is it's not reuse if there's no re. Infrastructure in search of a user is a bad thing. If you build it, they will find code rot if they ever DO come and then it won't quite fit their needs and have to be adapted anyway. Apply "lazy binding" and "deferred allocation" to actually creating infrastructure in the first place.)


July 15, 2021

Oh look, another example of employer paperwork it is inadvisable to sign.

Climate change is predictably causing massive flooding so of course the denialist loon that Trump appointed to be head of Nasa commissioned a study blaming any flooding on "moon wobbles", and this is being reported as news for some reason. (Of COURSE the Boomercrats aren't pushing back against it, why would they? Good Cop doesn't want to WIN, that's not what Good Cop is there for.)

On the other hand, Biden will eventually go with the flow when a hundred people around him all shout the same thing long enough. Twitter is also capable of learning when enough people scream at it, although they still suck at being twitter. Facebook just sucks in general. So does the Free Software Foundation. And while there are many reasons I will never use AT&T this one's especially bad and should trigger antitrust action.

Billionaires gonna bill, and guillotines gonna gill. (You don't try to get ticks to put blood BACK into the system, you pick them off and burn them, making sure you got the head. Billionaires are parasites. They don't create value, they collect it. They clear-cut forests and take credit for the existence of all the wood. Damming rivers to hoard water and doling it out, when otherwise there would be enough for all. Billionaires claim credit for other people's work and insist they are needed: they are not.)

Of course facial recognition is racist and sexist and also illegal.

A good thread, from the co-creator of dogecoin, about why cryptocurrency sucks.

Interesting point about "the world starts hurtling towards inevitable doom when you personally turn 50" (which there are apparently ancient Roman speeches about): interviews about when things were best always say it was whenever the interview subject was in their early 20's, and that includes questions about "prominent organizations you belong to" and "the industry you work in".

That said, the GOP was was never any good (since the 1964 polarity swap when they embraced the confederate racists via the southern strategy anyway), And the Boomercrats (plutocracy's "good cop") remain intentionally useless.


July 14, 2021

Nope, not doing the water meter job. They offered me the job yesterday and I accepted (three times what Jeff was paying, still 100% telecommuting, doing real work making a product that ships to customers who want it to do everything it does), but today they sent me the NDA to sign and it was... unusual.

I've signed plenty of NDAs over the years, but this was the first one where admitting it EXISTED would violate it, or showing it to my own lawyer after signing it:

"Confidential Information" shall mean and include the contents and existence of this Agreement as well as any information that is not generally known outside the Company relating to any aspect of business of the Company, whether existing or foreseeable, including information conceived, discovered or developed by Recipient.

Agreeing not to disclose anything I might forseeably conceive or discover in the future seemed a bit open ended. Ordinarily violating an NDA requires information to already exist. Also, there's no requirement that I MENTION things to them for this to apply: any idea I come up with at some point in the future that might relate to any aspect of their business? They own it.

If we ever _did_ wind up disagreeing about what that covered, they had a paragraph promising that in case of any conflict I would pay them potentially unlimited amounts of money EVEN IF they lost the "binding arbitration" I would be signing away all right to avoid (which would be performed in the legal jurisdiction of Alabama):

In the event legal action, including any non-adjudicative proceeding (e.g., arbitration or mediation), is necessary to enforce the terms of this Agreement, Recipient shall pay to Company the amount of any award, judgment or settlement sums due to Company or its Affiliated Parties plus reasonable attorneys’ fees, court or arbitration costs and other expenses incurred by Company or its Affiliated Parties relating to such enforcement and, in addition, the reasonable value of Company’s time and expenses spent for such enforcement.

And I'm still not sure what this part means:

Recipient acknowledges and agrees that Company will be irreparably harmed by, and that money damages alone will not be a sufficient remedy for, any breach of this Agreement by Recipient. Accordingly, Company shall immediately be entitled to preliminary and permanent injunctive relief against Recipient for any breach or threatened breach of this Agreement, without the necessity of posting any bond, in addition to any and all other rights that it may have at law or in equity. Company’s right to preliminary and permanent injunctive relief shall be in addition to other remedies available to Company at law or in equity. Recipient expressly waives any defense that a remedy in damages will be adequate and any requirement that Company post any bond in any action for specific performance or injunction.

I'm liable for a "threatened breach"? So if I disagree with them about what is covered but haven't released anything while we negotiate they can get an injunction granting... what? That I post a youtube video clucking like a chicken? And having me "agree" that they get an injunction... either you can get a judge to grant you an injunction, or you can't, I would not be the SOURCE of any injunction.

So let's put this together: if we ever disagreed about WHAT was covered by the NDA, any "threatened breach" about information I could "forseeably conceive" would put me on the hook to pay their "other expenses" and receive a "permanent legal injunction", and I couldn't even show the agreement I'd signed to my own lawyer.

As I said, I've signed plenty of NDAs and expect to do so again, but there's a difference between setting up a well-defined relationship where I keep both the information they provided to me and the work product I provided to them confidential, and... whatever that is.

I sent them back the subset I was willing to sign, and the manager got insulted. (Who was not either of the two engineers I interviewed with, but some other random guy who was now in charge of the process without having spoken to me at all in the "should we offer this person a job" phase.)

I told said manager I was sorry it hadn't worked out, and I'm back looking for other stuff again.


July 13, 2021

Sigh. Biden is good cop. Good cop's job is to do as little as possible as slowly as possible while endlessly asking for more from the suspect. Good cop is still a cop, a servant of plutocracy who does not want the system to change and is not on your side.

A surprisingly good summary of why Google can't pay me to work on toybox: I was telecommuting before it was cool. Google apparently has rigid gender employment roles straight out of the 1950s. All the special chairs and company cafeterias (which suit-and-tie corporations modeled on military commissaries after world war II; IBM had one when I worked there) are designed to lengthen the amount of time employees spend in the office. If working 16 hour days including weekends increases productivity (um, no?) then ramping up attendance hours is a metric they could measure and use as a proxy for productivity. As long as you can keep them from going home, life is good. Now people want to telecommute which means they're not in the office which means they're not working, ergo...

Billionaires continue to suck, as does Faceboot and the GOP. Defund the police and the carceral state.


July 12, 2021

Whee, not satisfied with deadnaming my license, Wikipedia[citation needed] has dead-licensed the project. Toybox is not under any of those licenses. I will happily delete the old tarballs off the website if it bothers whichever clown did that. Seriously? The gcc page doesn't say when it went GPLv3, but mine needs 8 year old licensing decisions that predate android inclusion memorialized in the summary box? Somebody is REALLY threatened by 0BSD...

I'm trying to build the hexagon toolchain by manually following the build script they checked into qemu. They're more or less building vanilla llvm (a mainline commit from a couple months back), the vanilla kernel (a bugfix version of a year old release), and that fork of musl I pointed Rich at.

First thing they do is download and build LLVM, and I ran their cmake invocation in my devuan setup and its configure stage barfed with the "CXX_SUPPORTS_CUSTOM_LINKER" test failing. The suggested fix is to install lld-10 (the devuan banana I recently upgraded TO only comes with lld-7). I trimmed the -DLLVM_ENABLE_PROJECTS="clang;lld" to JUST lld and... same error. The llvm linker wants to ONLY build with the llvm linker, not any other linker? Bravo.

Is it because the command line has -DLLVM_ENABLE_LLD=ON set? No, removing that changed nothing... Oh you little bastard. If I rm -rf the build directory, recreate it, and re-run the config with the changed parameter THEN it stops complaining. It's cacheing command line arguments I'm no longer supplying it when I re-run the configure stage. What a horrible piece of overengineered junk.

Ok, I built lld by itself without the LLVM_ENABLE_LLD=SURE, and then "ln -s lld ld" in the bin directory of that, and then stuck it at the start of the $PATH, ala:

PATH=$PWD/../llvm/bin:$PATH taskset 7 cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$(readlink -f ../hex) -DLLVM_ENABLE_LLD=ON -DLLVM_TARGETS_TO_BUILD="Hexagon" -DLLVM_ENABLE_PROJECTS="clang;lld" $(readlink -f ../llvm-project/llvm)

And yes it has a new output directory because overwriting the linker while you're using it seems like a bad idea. And THAT invocation of their autoconf reimplementation completed without obvious error, so time taskset 7 ninja all install and... Ahem, try that again with the $PATH prefix. (Although complaining it can't find ld is an odd failure message for having forgotten to do that...)

The "taskset 7" is because this laptop is 4x SMP and 7 is binary 0111 so it's restricting the child process(es) to 3 of the 4 available processors, leaving one to keep the desktop reasonable. I often do that when I'm launching a long-running CPU hog but want to still use my laptop while it runs. I tend to "pkill -f renderer" to get chrome tabs to stop eating CPU (reload them when I want to use that particular one), and these days I "killall -STOP thunderbird" when on battery and "killall -CONT thunderbird" when I want to use it again.


July 11, 2021

Cycled back around to busybox cut -DF and I read the testsuite/README file and ran "./runtest -v cut" and it went:

FAIL: cut-cuts-a-field
+ + /home/landley/busybox/busybox/testsuite/echo-ne -ebusybox f1\tf2\tf3 cut
 -f 2
+ test f2 f2 f3 = f2

And I am just <sarcasm>SO HAPPY to be dealing with this infrastructure</sarcasm>. WHAT DOES THAT MEAN? Off to read the source to understand what the test suite output is trying to say.


July 10, 2021

Phone interview with a place making water meters, good solid utility work (a bit like SEI's synchrophasors and JCI's climate control systems). Always nice doing work that the customer wants done and would miss if it didn't happen.

Saw Fuzzy off to the airport at 3am (fencing tournament in philadelphia then visiting her mother in NYC).

A nice video of streets reclaimed for pedestrian use. As robotaxis ramp up we should see a lot more of this, as well as redeveloping parking lots into useful space. (Servicing our travel needs with 1/10 as many cars which don't spend 96% of their time parked means we don't need to devote so much infrastructure to hitching posts and horse water troughs and those guys with the push brooms and circular wheely bins to sweep up the poop.)

Yay, my s390 perl removal patch made it into the kernel.

Ok, upgrading to the new musl-cross-make broke all the 64 bit targets and it's because toysh is segfaulting when it calls free() on the "/proc/self/fd/$NUM" string, which looks fine, but something's making musl mad. Since last toolchain musl replaced its entire malloc implementation, and this segfault because there's a next->psize != self->csize check in __bin_chunk() of musl's src/malloc/malloc.c. (Yes I stuck printfs into musl and rebuilt the toolchain to find that, after first confirming that musl's dprintf(2, blah) does not malloc or free anything.)

Musl's new free() is doing __bin_chunk(MEM_TO_CHUNK(p)); and musl's src/internal/malloc_impl.h defines MEM_TO_CHUNK(p) as (struct chunk *)((char *)(p) - OVERHEAD) also defines OVERHEAD as (2*sizeof(size_t)), and size_t is long. This is kind of weird since in the same header file:

struct chunk {
        size_t psize, csize;
        struct chunk *next, *prev;
};

So we have a struct, but we're only using the first 2 fields of it? (The next and prev pointers would be the first 16 bytes of the user-visible memory returned by malloc()? Weird.)

So self->csize != next->psize, and self is the argument to __bin_chunk() but next is NEXT_CHUNK(self) which is c+CHUNK_SIZE(c) and CHUNK_SIZE is ((c)->csize & -2), which forces it to 16 bit alignment? (-1 is ffff, -2 is fffe, it switches JUST bottom-most bit off. Why? No idea. Not even 32 bit alignment: 16. Huh. Ah, the bottom bit is used to signal that the chunk is mmapped(), IS_MMAPPED() is !(csize&C_INUSE) which is 1. Specifically, the bottom bit is NOT set when it's mmapped, I guess? Right, tangent.)

So I need to check that:

int validate(char *p) {
  size_t *st1 = ((size_t *)p)-2, st2 = (void *)(p+(st1[1]&-2));
  if (st1[1] != st2[0]) barf();
}

So I need to stick in stuff that validates that string's header and bisect to where the damage happens, and THAT means reading the musl malloc code. Hmmm...


July 9, 2021

Today I learned that most of the viral "missing person" notices are abusers trying to track down a victim that escaped them.

I still advocate for guillotines (billionaires are modern kings, france had a solution to its aristocracy a couple centuries back), but antitrust and taxes are good things to do on TOP of that.

Defund the police. In the USA cops take more money from people via "civil asset forfeiture" than all burglaries combined, and you have to pay hundreds of dollars for the RIGHT to challenge it and then it's a civil matter (so you don't get a lawyer, but they do). No crime on your part has to even be alleged. Cops only spent 4% of their time on what THEY call "violent crime". The thread ends with a New Yorker article.

Right wing loons are bad, frantically denying that american culture is steeped in sexism and racism for the same reason fish don't see water (and couldn't survive without it). Internet advertising not only doesn't work, it never worked. Capitalism can't outlive the Boomers.


July 8, 2021

Pointed Rich at the musl hexagon fork and their docker test image and llvm build script in the qemu test suite. I'd previously pointed him at the musl xtensa fork (which is against a stale branch, and he says was done wrong), but qemu-system-xtensa and qemu-system-hexagon both exist and I'd like mkroot to build systems that run there, which means getting a working toolchain for those targets, and musl-cross-make is a FLAMING PAIN to feed external tarballs into. (I have to do it for llvm anyway, but it would be nice to at least use vanilla musl and a vanilla kernel.)


July 7, 2021

The thing about guillotining the billionaires is that Mackenzie Scott is an interesting edge case. She IS the mythical "good billionaire"... so how does that work?

Mackenzie Scott divorced Jeff Bezos exactly two years ago, inheriting 4% of amazon then worth around $36 billion. She didn't work to BECOME a billionaire, she disentangled herself from one, and immediately vowed to give away money until she wasn't a billionaire anymore. She has already given away over $10 billion, which is almost a third of the money she inherited, but her net worth has GROWN by $23 billion (almost doubling since the divorce) because the system is so slanted that being a multi-billionaire is giving her money faster than she can dispose of it. (It's not "earning" her money, she's doing nothing for it and is literally trying to get rid of it, an outright Brewster's Millions situation.) In the last 4 months of 2020 she was giving away a billion dollars per month which was just about breaking even with her rate of income.

The reason her generosity is rate limited is she's researching to have the greatest impact and do the most good with the money. For example she gave $10 million to the Navajo covid-19 relief fund, matching their donations so far. That amount didn't require them to disruptively scale up their operations, nor did it render irrelevant the outpouring of Irish generosity. Instead it let them continue what they were already doing for the rest of the pandemic. She didn't give them more because she could easily have flooded their engine: too much money can destroy an organization even _without_ depending on volunteers to do most of the work. She made a targeted donation that had a real positive impact, one of many.

It's HARD to spend a billion dollars on anything real: a single million dollars is enough to set someone up for life, and a billion dollars is enough to set a THOUSAND people up for life. She's basically trying to mobilize a new army of a thousand people, every month, permanently.

Yes, a million dollars properly managed is lifetime financial security for one person (at least while Obamacare holds out). Even if you didn't earn ANY interest on it and just spent through the big pile of cash, the $1000/month "basic income" rate would take 83 years to spend a million dollars. At the "fight for 15" full time salary rate, $15 an hour times 40 hours a week times 52 weeks a year is $31,200, which means 1000000/31200 = 32 years to run through it all, spending as if you had a "good job" without ever having to show up to work. And unlike working a job this money would be tax-free because you're spending money you already HAVE (no income tax, social security tax, medicare tax, state taxes...) which makes that $15/hr more like $25/hour which is edging up into "job requiring college degree" territory without the student loan payments.

If instead you invest that million dollars in Coca-Cola stock (a company that's been around doing basically the same thing the same way since 1892 and thus a reasonably "safe investment"), that's currently $54/share with 42 cent per share quarterly dividend so you'd get (1000000/54)*0.42*4 = $31,111 each year in dividend checks mailed to you (almost exactly that fight-for-$15 rate). That's taxable, but the dividend goes up over time (it was 40 cents in 2019) so not only would you NEVER work through your principal but you'd get a raise every year or two. (And your principal would grow as the stock price went up.)

Mackenzie Scott is trying hard to stop being a billionaire, and the system is so rigged it's actually difficult for her to do so (without just giving the money to somebody ELSE to be a billionaire on her behalf, or giving life changing amounts of money to thousands of strangers). But "didn't intentionally become a billionaire" and "giving away over 10% of her net worth per year" are mitigating factors. That said, the longer she remains a billionaire... being a meth addict would probably be psychologically healthier? J.K. Rowling was one of the most beloved people in the world when she became a billionaire in 2004, and seems to have avoided being publicly hateful for about 10 years after that until "I know better than everybody else because I am a superior person" disease set in. Notch, the creator of minecraft, became a billionaire in 2014, immediately faceplanted, and by 2017 there were articles about how much of an asshole he was. You can argue "reveals" vs "corrupts", but either way the timeframe is pretty bleak.


July 6, 2021

Freenode continues to circle the drain. People are connecting the audacity nonsense with this as an "assault on open source", but it's the same market-cornering that capitalism has always done. Sellers of bottled water MUST attack tap water in order to have a market, whether by badmouthing it or sabotaging the infrastructure via regulatory capture. (Meanwhile, nobody anywhere should be surprised that microsoft buying github is working out as well for github as microsoft buying hotmail worked out for hotmail.)

Wow, somebody's reinvented car2go and thinks it's a new idea. Remember that Morgan Stanley analyst with a 4-quadrant chart from individually owned manually driven cars to app summonable self-driving fleet vehicles? Yeah. Those other two quadrants ain't stable.

We had a similar migration over the past quarter-century from "landline" to "smartphone", which _also_ had two other quadrants that weren't stable. Back during the dot-com boom lots of people tried to make "smart landlines", but they only succeeded at connecting the internet to devices that already had a reason to exist (like a computer, game console, or television), and NOT by selling any sort of new dedicated "phone with extra abilities". Meanwhile non-smart cell phones were the only option for decades, but once the "attach cellular service to general purpose computing" cell provider monopoly bottleneck was broken, smartphones rapidly caught up and these days 4/5 of all cellphones in the world are smart phones (despite still being significantly more expensive and having much shorter battery life than "feature phones").

I suppose you could say "yellow taxicab" and "rental car" have been around forever, so once again silicon valley douchebros think reinventing the idea of public transit is somehow new. But if you specifically put "my own car in my own driveway" on a grid with "self driving" and "app-tracked car sharing" as competitors to it (rather than supplements for people who are either keeping their car in their driveway or never had the option because New York City apartments don't have parking spaces)... the answer is going to be "both at the same time".

Robotaxis have a problem similar to smartphones in that everybody knew it was coming, but until it could overcome the gatekeepers (monopoly phone carriers last time, regulators of what is "street legal" this time) it couldn't deploy. People quibble about self-driving technology's readiness, but remember with cell phones the ergonomic issues were a perennial complaint until touch screens replaced keyboards, but it didn't stop the "thumb generation" or palm pilot users. The real blocker was gatekeepers preventing the new techology from attaching to existing infrastructure. Once AT&T acquiesced to unmetered data going into a full fledged posix system, all the other carriers fell in line (using Android because of Apple's exclusive 5 year contract) within months rather than be left behind. Once a major city allows a full robotaxi fleet deployment, the rest will probably do the same? (Hard to tell with regulatory hurdles, but "I can move to where cars just pick me up and drop be off at will and never need to be parked, for a flat monthly rate that's less than I paid for car insurance" is on the level of "we have broadband and you don't" when it comes to civic advantages.)

The cell phone market could take off in the days before smartphones because regulation and lawsuits forced open access so people could go into businesses that the incumbents weren't yet interested in. But the market for self-driving individually owned cars has never had a chance to take off because its regulatory hurdle (what is and isn't "street legal") does not have a successful history of legal challenges. Cars are big and dirty and dangerous and were only allowed into cities because they replaced horses, which were already big and dirtier and even more dangerous. Around the world cars kill over a million people annually, which is why both cars and drivers have been heavily regulated. But regulatory capture protects incumbents from competition, and the 1997 book the Innovator's Dilemma pointed out this is why electric golf carts weren't acting as a disruptive technology in the united states: the electric vehicle market couldn't scale up organically from existing cheap short-range vehicles because they could never drive on public roads for short commutes or trips to the grocery store. This delayed the switch to electric cars by multiple decades and forced it to take a different path to regulatory approval. Giving a driver's license to software programs has met similar resistance, but again it's just delaying the transition, not preventing it.

The blocker for individually owned self driving vehicles is the same blocker for robotaxi fleets, so there's no window for non-fleet self driving to build any sort of lead on an app-summonable self driving subscription service. When self-driving gains regulatory approval, robotaxi fleets get to recruit subscribers at the same time car owners get to switch to self-driving. Tesla is trying to cheat by installing self-driving hardware in all its vehicles so it can just "flip a switch" once it gets regulatory approval... but they're half the reason approval has taken so long: every time their self driving stuff gets enabled people die. (Waymo does not have that problem.)

Meanwhile, shared manually driven cars have a long list of companies that have already tried it (zipcar, getaround, silvercar, hubber, Japan has Orix, there's a european one that focuses on RVs...) without ever really making much of a splash. As with the "smart landline", it's just not very interesting.

The point of robotaxi fleets is they're sufficiently cheaper to run that solar powered electric vehicles cleaned inside and out by an automated car wash honestly could be a service "too cheap to meter"... if capitalism ever allowed such a thing under any circumstances (instead of constantly striving to replace tap water with bottled water because profit). If waymo puts a "Go" button next to "Directions" in your phone's Google Maps app (which when pressed turns into a countdown of the number of seconds until a vehicle arrives at your location to take the holder of that phone to the selected destination) no humans except the passenger(s) are involved, so nobody has to be PAID.

You only ever pay PEOPLE. You don't pay cars. You don't pay batteries. When there are no people providing the service, only rentiers (a form of legacy parasite charging repeatedly after the fact for work that's already been done, often lasting long after the people who did the actual work die) get paid.

Automating away the need for people to do manual labor is often attacked as "putting people out of a job", but it's actually an obvious form of progress. Once upon a time we had people called "operators" manually connect every phone call, then they invented rotary dialing, then touch tone dialing, then speed dial, and now it's usually a voip app. "You'll never get rich by digging a ditch" because we have hydraulic excavators now, which means we don't need prison labor to perform that task; machines allow one person to do the work of hundreds, and computers allow NOBODY to do it.

The problem is capitalists hate "free". They want to insert themselves as unnecessary middlemen so they get paid for doing nothing, because they own... the right to get paid, by you, for doing nothing. (IP law is probably the purest expression of this.) But the big draw of robotaxis is the flat rate model. If you get charged per ride people will have loss aversion for paying for a ride, but not loss aversion for driving a car they've already filled with gas... It's analogous to charging for internet connections by the megabyte: it's the business model greedy providers want to provide, but not what customers want to buy. The "unmetered" option beats the metered option, and with more than one provider in the city the flat rate offering is likely to win out. But there may be a lot of churn to get there from here, especially with...


July 5, 2021

I made special K bars for the first time in ages. The recipe's pretty straightforward, but I had to dig to confirm bits of it:

2 cups corn syrup
2 cups sugar
4 cups creamy peanut butter
12 cups special k
2 cups chocolate chips
2 cups butterscotch chips

That's one 16 oz bottle of clear karo syrup, one package each of chocolate and butterscotch chips, and there's a box size where it's exactly enough cereal but I almost always buy the wrong one. Can't avoid measuring the sugar and peanut butter.

Mix together the sugar and corn syrup and bring it to a boil (but don't LET it boil) stirring more or less constantly until it goes clear-ish. Add the peanut butter and stir until smooth, which takes longer than you expect. Pour the result over the special K and mix until everything's evenly covered (big steel bowl and wooden spoon, yes it is enough topping, this takes too long, your arm will hurt). Upend result onto 2 cookie trays while still hot (it sets up like concrete as it cools) and flatten evenly (you want a smoothish surface on top for the next step). Let cool for a bit.

Melt together the chocolate and butterscotch: you're supposed to use a double boiler, but you can do it in the microwave if you're really careful (30 seconds, stir, 20 seconds, stir, 15 seconds, stir, 10 seconds, stir, 10 more seconds, stir...) Burns VERY easily though, which makes hard lumps. When smooth, spread evenly over the surface of both trays: again there is enough but it takes spreading. Let the whole mess cool at least half an hour before trying to cut it.


July 4, 2021

There was a tiny kitten on the front porch last night, mewing loudly in distress. Fled every time I opened the very loud screen door, but I left the inner door open and screen door closed for a bit and saw it sitting on a corner of the porch. Left chows and water out for it.

The Audacity audio editor project appears to be imploding. (New capitalist owners changing the license and filling it with spyware.) This is clearly working up to an ethereal->wireshark, xfree86->x.org style retrench under new management, and there are already a couple forks but no clear successor yet. (Here's some backstory on the change of management, from someone who seriously did not see it coming.)

An explanatory thread about why Linux has so few women involved with it anymore.

Ok, got tail -F hopefully sorted. What else is on my todo heap from the 24th? Plus new things coming in. And other stuff I don't even think I wrote down, such as "I updated the musl-cross-make toolchain and now none of the 64 bit targets make it through init". (Sigh, my s390x patch removing perl from the makefile didn't make it upstream this release, it sort of seems to have been accepted...?)

Blah, I've still got pending j-core mailing list messages to reply to...

Asked how to stop windows from jumping between workspaces on the #xfce channel on liberia, no reply for 2 hours. Let's see if this gets a reply... (Spoiler: haha, nope.)


July 3, 2021

Not feeling up to organizing today's linkdump into a narrative, so here's a bunch of snippets.

One of the many reasons to defund the police is that in many cities they are profoundly useless.

All that child sex abuse stuff the right wing loons are on about is projection: organizations ACTUALLY doing bulk child abuse include the catholic church and the boy scouts.

Billionaires continue to demand guillotines.

Climate change is still a problem.

The world athletics organization is sexist and racist.

Worries that the USA might become fascist ignore the fact that the USA has been fascist for quite some time, it was just harder for white male middle class american citizens living domestically to notice before the massive concentration of wealth Ronald Reagan started moved almost everybody into the "them" camp that a very tiny plutocratic rump "us" exploits.

Blockchain is the new Godwin's law.

Christianity is literally trying to overthrow democracy. Christianity is also fascist.

3800 artifacts stolen by hobby lobby's fundamentalist christian owners have been returned to Iraq.

Medical debt owed by individuals is less than 1% of hospital revenue: it's about control. Capitalism's carrot ran out so the stick's getting bigger and bigger.

Medical science is misogynistic.

You've got to know where the bodies are buried in order to hide them.


July 2, 2021

Videos of my talks are being reposted in china now? *boggle*

Phone interview for a job in New Mexico on tuesday. It's not one of the telecommuting positions, but they got back to me first and I've historically gone where the work is. (And it passed the "seems interesting enough" filter.)

WHY is thunderbird getting itself stuck in a CPU eating loop doing nothing? I'm not making it out to the table (if Fade is home, I want to hang out with her when she's awake) so I'm getting a couple hours at Wendy's, which is like an hour tops when I don't notice Thunderbird gratuitously draining my battery: killall -STOP thunderbird should just be standard practice when I'm not actively checking mail; anything written by the Mozilla foundation is crap. Which does not say nice things about Rust.

And yes, this is why I held off updating devuan for so long. I dowanna have to track down all the new bugs in a giant flag day change I can't easily bisect with no option to revert and stick with old non-broken versions of individual packages. Ubuntu had LTS. Devuan does not. But ubuntu has systemd now, and is thus dead to me.


July 1, 2021

Today I learned that EMTs stopped asking who was president around 2017 because most people either got angry or refused to answer. The GOP is not popular anywhere, they've just done extensive voter suppression: if only 50% of the population votes, their 27% support can produce a nominal majority. The south has been voter suppressed since the civil war, spreading it to the rest of the country is fallout from the "Southern Strategy" and has taken off since the GOP-packed supreme court repealed the voting rights act in 2013. (The 5-4 decision was Scalia, Roberts, Thomas, Alito, and that Kennedy guy who retired so Trump could appoint Kavanaugh rather than let a democrat nominate his replacement. RBG did a Leeroy Jenkins that was merely stupid, but Kennedy actively sold out.)

And yes, RBG was stupid (and/or senile): in 2009 she was diagnosed with her _second_ cancer at the age of 76, and decided to keep going until she died in office (of complications from that cancer) and could be replaced by an absolute loon. She judged this preferable to letting Obama name her replacement, because gerontocracy or something.


June 30, 2021

Exhausted. Emailed three recruiters, but got nothing else done today.

Jeff called and sucked the life out of me again. We had another hour long talk about his grandiose scheme du jour to resurrect the company, and these talks consume SO much emotional energy. (I would LOVE to see his plans succeed, but even attempting them demands more commitment to his cause than I have left in me right now. All that coinbro stuff burned through my faith in the viability of any of this, and I need to pay the mortgage.)

The sad part is he's finally got a good idea (resurrected one from last year) that he isn't poisoning with crypto shenanigans, but it just seems too late. He keeps performing heroic CPR on something that's about to tick over in the second month of not paying any of the employees; the team will break up before we can do anything that might eventually turn into money. I can't fix that part.

For months Jeff was convinced that only coinbros would invest in his ideas anymore (no conventional investors left anywhere who actually wanted something real), so every time we fleshed out a new idea he'd eventually derail the conversation with "how do we work issuing a new coin and/or NFT into the business model". (Answer: we don't, and I CAN'T HELP there. I cannot wrap my head around "this will never be real but coinbros will buy it because they think they can sell it for more to bigger fools in a month". I cannot make issuing a coin be a retroactively inextricable part of an idea that did not initially contain such a coin. There IS a version with no coin, that's what we've been talking about, therefore gluing this to a blockchain is demonstrably NOT an inherent part of the idea.)

Now we're past that because I got very explicit about the "talk to the hand" part the last couple times "Coin!" came up, so now he's back talking about good solid technical stuff. Specifically, there's a fully open source toolchain path to FPGA now (on lattice ice-40 and ecp5 anyway), and Jeff thinks he can put one together for ASIC too, which nobody's done yet.

Ordinarily creating an ASIC (making chips from silicon wafers) involves feeding the fab high-level information which they run through their proprietary toolchains, linking against proprietary libraries to suck in things like their SRAM implementations and I/O pads which are all black boxes you license per instance. Their toolchain does its own physical layout and inserts test chains and so on, so the result is something where even if you decap it and examine it under an electron microscope you don't know what it's SUPPOSED to look like, so how can you make any security (or reproducibility) statements about the result?

What we wanted to do (a year ago) was dig up our own implementations of all those components, and use open source tools to create our own mask (I.E. a big graphic file with all the rectangles the fab needs to make a mask from, where they just PRINT it as-is instead of compiling or rendering anything). Then we can feed this file to simulation packages (called magic and spice) that can simulate the actual physics and run a virtual chip burned from this virtual mask, albeit very, very slowly.

There's all sorts of complexities, like "each fab process has its own specs about each dimension of the rectangles and the gaps between them for each type of component" (which you have to sign an NDA to get but Google paid Skylake a bunch of money to release theirs, and some old 350 nanometer ones have leaked multiple times over the years and it's a table of numbers which is not copyrightable and it's not a trade secret if it's been handed out to hundreds of people over the course of decades so we got it from multiple different sources and never signed anything). And the rectangles need to be distorted because the burning process is kind of a fisheye lens that distorts it back, and THOSE equations are also propreitary (and fab-specific), but that's manageable too. Jeff knows the full list of things that need to be done, he's made ASICs before, has friends that work for fabs.

It's a bit like cross compiling, where each fab has its own proprietary toolchain and we're trying to come up with a generic one that makes a standard AST and then has understandable backends for each target. What skylake did is buy tech from one fab and release it, resulting in open watcom (only targets one architecture, has its own unique behavior all the way up and down, and is immediately abandonware). Another common solution (berkeley did some of this years ago) was creating a website you upload your design to and they do the black box transforms and send you back a file: we want you to be able to reproduce this on your own laptop.

So there's a lot of really cool stuff there, and this description is just scratching the surface, and we've talked about it for hours, and I CANNOT get enthused about it because it won't happen. This is at least six months worth of work to get some good demonstrable prototype output, and maybe a year to produce a fully open arduino-style processor running at like 8mhz. And that's IF we were fully funded and not distracted chasing contract du jour to keep the lights on.

The company won't last that long. We can't finish it. And even if we DID, how would that attract funding? Yes it's a lovely thing worth doing, and lots of people who don't understand what they're doing have uselessly half-assed it. (Imagine if the gnu project only ever made userspace tools like "tar" which needed a proprietary compiler and proprietary OS to run on: that's Risc-V. Companies spend $2 million designing a chip and $100 million manufacturing it, and they can save you most but not all of that $2 million. Bravo.)

I have done many things over the years which were "retroactively obvious". Nobody could do this thing, I made it work, then everybody went "well of course, it was inevitable" and obviously I didn't do anything important because it was always going to be like that. That's normal, but when I don't get around to things (like initmpfs) they're still on my todo list 10 years later because nobody ELSE did it. (Which is annoying.)

This is another retroactively obvious thing. Of course it should happen, but nobody's going to fund it ahead of time. I can't even turn working on toybox into my day job, and that has users now. (I had hopes patreon would, but my monthly health insurance is 6 times what patreon brings in, the mortgage is 3 times THAT, and then there's food, electricity, internet, cats...)

I've already GOT hobbies. The scourge of late stage capitalism says I need a paycheck. Thus talking to Jeff drains the life out of me. Yes I can do the work he proposes. It would be great to do. But I'm spread too thin. If we'd started working on this the last time we talked about it (what, November?) I'd at least have momentum.

Speaking of momentum: do you know why all diesel lotomotives are actually electric, with a diesel generator driving electric motors? Because only electric motors produce enough torque to get a stopped train rolling. No piston can manage the amount of compression required to get four hundred stopped cars moving. Once it's moving, pistons could KEEP it moving, but only electromagnets can pull hard enough to get it STARTED. And that's why trains have been electric for a hundred years, steam engines replaced by disel generators driving electric motors allowed much longer trains of cars, and the limiting factor is that it's so much harder to get started than to keep going.

I can keep going on a project for Jeff, but I haven't got the energy to start a new one right now. And there are probably better ways of job hunting these days, but I'm repeating the old tried and true "poke recruiters until one of them tells me to fly to $CITY" because I rode another startup down until I'm too tired to break a new trail and have to follow an existing one to a rest area where setting up camp may be a bunch of work, but much less of a gamble about whether that work will pay off.


June 29, 2021

Late stage capitalism has now given us mattresses full of fiberglass that goes airborne. Bravo.

Random people are saying (without studies or real evidence) that the delta variant requires booster shots for people who took J&J vaccine. I'm not sure I buy it? The pfizer and moderna vaccines are paying for new MRNA manufacturing and distribution infratructure that lets drug companies treat-but-not-cure a wide range of conditions, so those companies would LOVE the covid vaccination gravy train to become an ongoing profit center, which puts them in conflict with the CDC which says that isn't necessary.

That said, I have motivated reasoning of my own here: I have a PROBLEM with needles. The answer I believe is correct seems to have a lot of support: delta spreads faster (it has an R value of 5), but doesn't cut through existing immunity better, and the earlier scaremongering about astrazeneca being ineffective against it turns out to be more of the smear campaign against the technology that DARED to waive patents in the face of a pandemic... But I also WANT it to be true, which is a problem for trusting my conclusion.

That said, I've more or less resigned myself to probably getting covid a THIRD time at this point. (I got the original via jury duty, and got it AGAIN in November when either the UK or South Africa variant was going through the Japan office; my co-worker Mike was hospitalized for a bit.) My wrist has finally recovered to the point I can do push-ups again and I keep meaning to try the Chloe Ting videos again. Walking 4 miles/day made my knee stop hurting (both times covid gave me joint swelling bordering on arthiritis) but that didn't help my wrist, and she hasn't got any exercise videos that DON'T involve some variant of push-ups at some point. No vaccine (or previous exposure) prevents you from getting a mild case of a new variant, and that's apparently enough for my old high school sprained wrist to ache for a couple months when I put weight on it. Sigh.


June 28, 2021

Austin is slowly limping towards robotaxis, one business model change at a time...

The musl-cross-make toolchains I just built haven't got include/linux directories for m68k and s390 because the issue from last year never got fixed. Ah, it did get fixed but never got integrated because nobody was regression testing m68k and s390x. (Hello, I PUBLISHED my builds. Anybody should be able to do this now, why are you waiting for ME to do it?) Right, m68k works and s390x does not... except ALL the 64 bit targets are broken with the new toolchain? Why...

Um, wait, what? Why is that repo mentioning my name? Is that my linux-fullhist tree? On kernel.org? (Yay! What?)

Highly useful, and I did not expect that. It seems to clone cleanly and everything. It's good to know people are still using a thing I did (and good that I can point people at web versions of older commit hashes), but... I'm not part of that community anymore? I'm very angry about a number of things, and do not feel part of some communities I once felt part of, which makes participation difficult. I'm not sure how much of it is that I've changed, that they've changed, that I HAVEN'T changed... Hm.

I try hard NOT to ossify into a loon, which I've seen far too many people do over the years. I have to regularly examine my beliefs to figure out (and ADMIT) when I'm wrong about stuff, which is hard painful work that falls somewhere between maintenance and cleaning.

There are many luminaries in the field who once upon a time did good work (Bill Joy, Eric Raymond, even Richard Stallman once upon a time) who stopped being a net positive and had to be excised from the productive flow. Other fields have plenty of this: Richard Dawkins once did good work which stopped abruptly, and these days Neil DeGrasse Tyson is constantly being corrected by Steak-umm's marketing department... But we still use the ancient artifacts handed down from the days their creators Weren't Obviously Crazy Yet. (Or at least were still presenting as a net positive within their niche, despite them being Bill Cosby or Hans Reiser behind the scenes.)

I'm hoping that the work I leave behind won't be tainted by senile ramblings or closet skeletons where "this person wasn't a net positive because the work they did was a tiny fraction of the work that WOULD have been done by the people they kept from participating". (Linux no longer has Sarah Sharpe or Val Henson. Grace Hopper built the field of computer science with her bare hands but manbaby dudebros have been chasing cooties out of that playground since about 1983. Seperating the creator from the creation goes both ways: sexists basically did cultural appropriation on the invention of the compiler.)

Then again this is what most of IP law does too: protect a small privileged class of creators at the expanse of the far larger group that would positively outclass them if not suppressed.


June 27, 2021

New research on how the Boomers' chronic lead exposure (from burning billions of gallons of leaded gasoline in all major cities for decades) caused brain damage and crime sprees, and basically explains why the Boomers express so much widespread brain damage as they become senile.

The remains of the GOP are a giant elder abuse financial scam (and other more specific financial scams, such as Trump's postmaster general gratuitously announcing another US mail slowdown), which is otherwise spiraling inwards. Right wing loons are a tiny minority that constantly screams to see the manager. (They also lie about their racism a lot. Canada found another 750 umarked graves under another christian boarding school they forced kidnapped native children into. Wasn't really hidden, they just weren't looking.) But as with the Tea Party jumping up and down yelling "clean cup move down", there really aren't that many of the truly dedicated assholes, they're just loud and constantly writing letters to the editor. Heck, kids are going behind their parents back to get vaccinated because the old and out of touch are wrong, same as it ever was.

Disney was built on copying and is now a major supporter of the IP law regime destroying content. Pulling up the ladder after them is what billionaires do.

Never trust cloud anything, Apple edition. Apple wants to voraciously consume all your data including state ID, but private companies can't be trusted with it. And gatekeepers like Youtube are seldom on the side of the good guys either.

Another reason we can defund the police is that most theft is wage theft by employers. Boomers are terrified of hoodlums breaking into their house to spraypaint their cat but that's just another way they're out of touch with reality: the big ACTUAL threats are corporate, brazen, and ongoing.


June 26, 2021

Rich did several commits to musl-cross-make, and I pulled them and rebuilt the toolchains last night (and well into this morning), and now mkroot is rebuilding all the images against the current toybox and linux kernel (v5.13-rc7 and change), and... huh, I didn't actually install rebuilt qemu binaries in /usr/local/bin. And typing "make install" in that directory is trying to rebuild everything. Right, "git clean -fdx && git checkout -f && git pull && ./configure" to make sure I'm building the CURRENT random git snapshot du jour. What dependencies did that ./configure find... No virtfs support. Not tracking that down right now.

Current qemu lists 30 qemu-softmmu targets but 34 qemu-system-user targets? System emulation and application emulation aren't quite lining up, what's different there.... -linux-user has aarch64_be, armeb, mipsn32, mipsn32el, ppc64le, and sparc32plus that don't have -softmmu equivalents, and -softmmu has avr, hexagon, rx, and tricore that don't have -linux-user versions.

Oh right, hexagon-linux-user. It has application emulation (but not system emulation) for hexagon. I asked about that ages ago (they were using musl). Where do I get a toolchain? There was that llvm build script once upon a time, but do they have a prebuilt sdk? Apparently so. Except trying to actually download it is "access restricted" requiring a 'validated account'. Of course. (And that's gonna be bare metal and not linux anyway.) My ex-boss Taylor Simpson did a KVM forum talk on qemu support for hexagon.


June 25, 2021

Ever since I updated devuan versions from Alcatraz to Brunhilde, all patreon creator main pages turn into a blank white page a couple seconds after loading. The console errors when this happens are "datadog-rum-us.js:5 TypeError: Cannot read property 'value' of undefined at postFormatHook (index.tsx:26)", "react-dom.production.min.js:161 Uncaught TypeError: Cannot read property 'value' of undefined at postFormatHook (index.tsx:26)", and "instrument.ts:129 [Facebook Pixel] - Duplicate Pixel ID:...". Which mean very little to me.

I tried Patreon's suggestion of loading the page in incognito mode and it didn't help. I checked chrome://extensions and there were still just the two builtin ones, the PDF viewer and "cryptotokenextension" which despite the CREEPY NAME is a builtin google thing for 2 factor authentication. (Why is a base part of the browser called an extension? Jazzhands!) Anyway, you can turn it off in incognito mode and I did and tried again and it didn't change anything.

I note that the version of chrome I had before the "upgrade", which had been complaining about being out of date for 9 months (because Devuan Artichoke stopped providing updates for it in the previous version repo despite still nominally being maintained) rendered all these pages just fine. "Upgrading" broke it. And you wonder at my reluctance to do so? I have elaborate experiments set up all over this lab bench happily bubbling away, and you want to SWAP OUT THE BENCH and change the brand of beakers in use? Decanting everything in the process? And this will be non-disruptive, will it?

Also annoyed that when a chrome page finishes rendering, the chrome window jumps to my currently active desktop. And modern pages load MEGABYTES OF CRAP behind the scenes. (Pages can easily take 5-15 seconds to finish loading/rendering.) So if I start a page loading and then switch desktops, the chrome window winds up on the desktop I'm on now a moment later, but NOT at the top of my window stack because I told the window manager background windows are not allowed to randomly jump in front of the one I'm looking at, so they insert themselves UNDER the stack, on a different desktop, and I have to figure out where they've gone later. It didn't do that in Devuan Aspartame, it's probably an "updated" xfce window manager thing in Devuan Brobdingnag, but I dunno how to MAKE IT STOP yet.


June 24, 2021

Good news: connecticut just made all prison communication free which is at least a small blow to the prison-industrial complex that uses everything as a profit center. And the NIH stripped 75 principle investigators from grants as a result of sexual and racial harassment probes. Baby steps are still progress.

Samsung is now putting solar cells on small electronics like remote controls. I dunno if their "goodbye batteries" tagline is because they're using a capacitor (supercap?) or just recharging a small battery from the solar cell, but it got me wondering if our old "two chips, an IR sensor, and an LED scotch taped to the front of a coin cell" j1 demo could be done with a capacitor and a solar cell instead? Hmmm... (It would be so nice if coresemi actually got useful amounts of funding. There's so much good technology we could DO if we weren't constantly scrambling to keep the lights on.)

Sigh. WHY is thunderbird eating 100% of a CPU for the last hour? It still seems to be working fine, the gui isn't blocked. It's just... spinning endlessly for some reason eating cpu. Can't take it to a battery powered table like this, but gotta close email windows before killing it... And it STOPPED eating 100% cpu when I sent one of the pending email messages I'd been composing on and off for a couple days now. *boggle*

Alright, what's my current todo heap before I can get back to toysh:

Rich actually did a commit to musl-cross-make! (For the first time in 8 months.) Time to rebuild all my cross compiler toolchains...

Blah, I did an xxd -I patch for busybox and then threw it away again because it's probably unnecessary because the language-specific wrapper around the CSV isn't output when reading from stdin. So I can implement it and Elliott can fix his use cases.

Implementing it is a bit tricksy though: xxd -i has non-obvious naming, adds leading underscore for non-alphabetic first file/dir name including "xxd -i _/two" which is a legitimate C identifier without the extra underscore? (I guess the test is just isalpha()?)

cut -F needs -O because otherwise regex can produce inconsistent delimiters:

$ echo "one  two   three    four" | toybox cut -DF 2,4
two four

You don't "output the delimiter the regex consumed", out output a single space as the default delimiter. (To replace the common AWK use case.) Which is funky and means you really should be able to SPECIFY the output delimiter, hence needing -O. (Which is just a short option for the existing --output-delimiter which busybox doesn't currently implement. Hmmm, did I already test that "echo one,two,three,four,five,six,seven,eight,nine,ten | cut -d, -f 7,2-4,1-3" produces "one,two,three,four,seven"? )

I'm trying to use busybox's tests, but:

$ make check
...
10 failure(s) detected; running with -v (verbose) will give more info
$ make check -v
GNU Make 4.2.1
Built for x86_64-pc-linux-gnu
...

Thank you busybox. Ever so helpful. Meanwhile, running the toybox tests against busybox is just "PATH=$PWD/somewhere:$PATH TEST_HOST=1 VERBOSE=all make test_cut" which is easier for ME to do, anyway...


June 23, 2021

Abigail Disney describes her family's dynastic wealth in The Atlantic. Does this make her the mythical "good billionaire"? Nope, google says she's worth $120 million. In the same "still has a soul" range with Dolly Parton and that Zappos guy. People are starting to figure out that "income" isn't the important metric, it's wealth.

Today billionaires figured out a new way to fleece small investors in... spins the wheel... cryptocurency. Hands up everyone who is surprised by this.

Rule of law is breaking down in the UK because the tories have sabotaged their court system (while increasing funding to their police). Here in the USA the "unreasonable search and siezure" prohibitions in the constitution mean nothing to modern police. Obviously we need to defund the police, but it goes deeper than that.

The Boomers don't actually want to retain democracy. The madness of Boomers is the same as the Madness of King George that the USA revolted against over two hundred years ago. Senile old farts with unquestioned power gone to la-la land. Many Boomers have literally stopped being functionally human, and it's expressing itself in myriad ways from homophobic racism to plutocracy, but also acting like insane control freaks against anyone younger than them.

Boomer capitalism's hostility to youth continues to try to ban the idea of sex while fetishizing sexless supermodels. Corporations are enforcing prudishness and bigotry on behalf of the Boomers via surveilance capitalism, which is a very Boomer "get off my lawn" type of thing that's obviously bad and should not outlive the Boomers, but afterwards all these corrupt business models need indictments and prosecution.

Boomers love to pardon nixon and go "back to normal" (a return to the mythical golden past on the fascism checklist), but "you can keep what you've already stolen, just stop stealing MORE" is never a fix. Every cycle of it escalates when there are no consequences.

Random examples du jour: capitalism just created a motorcycle airbag vest that stops working if you miss a payment, and Peloton is all-in on attacking the concept of ownership. Airbnb found a new way to be evil (on top of the various previous ways.) "Covering up rape on a large scale" was not a previously published issue for them that I know of. As with Uber their business model was always to bankrupt the competition and then raise prices, which ain't new. And here's a thread about the "gig economy" model moving into IT.

Geriatric plutocracy's current exit strategy is regulatory capture, hence the need to lobby for guillotines rather than taxes. The downside of "fighting to steal all the money" can't be the same as "not fighting to steal all the money", I.E. merely not getting more money.

Without serious loss aversion there's never any reason to STOP fighting to steal all the money and power from everyone. France guillotined its aristocracy a couple centuries back, and these days has government funded child care, 35 hour weeks, and 5 weeks annual vacation. They went though a bit to get from point A to point B, but it seems to have worked out for them ok.

The racism and sexism on the fascism checklist are why the GOP is so upset about "Critical Race Theory". The people attacking it are mad about historians explaining how white men committed genocide against native americans, enslaved millions of black people systematically for hundreds of years (and still doing Jim Crow today), treated women as property (requiring a woman to have a male co-signer to take out a business loan was legal until 1988)... That's why they're eliminating humanities education in favor of STEM STEM Uber Alles, because fascists hate science but love technology.


June 22, 2021

Last month I watched a couple of videos about how Kraft foods got acquired by a predatory private equity company known for milking its acqusitions dry and moving on to the next purchase. (A bit like the way Bain Capital destroyed Toys-R-US, or that Ann Rand fan looted Sears.) Ever since then I've been purchasing the HEB store brand rather than the Kraft version.

Today Jeff noticed that the canadian verson of Kraft mac-n-cheese (there known as "Kraft Dinner") just switched to a "new improved flavor" that swapped out half the cheese for sugar. As in the amount of added sugar mentioned on the label works out to half the weight of the flavor powder packet in the box (although you have to do the math yourself to work this out, he was clued in by the taste). The new owners just sold Kraft's cheese business (which was Kraft's original business), so presumably cheese is now more expensive to Kraft than sugar is, hence this unhealthy cost cutting measure.

Working on the busybox patch adding cut -DF, but debugging it's a bit of a pain. Not familiar with this infrastructure.


June 21, 2021

Just-in-time delivery supply chains continue to collapse. Container based shipping is acting overloaded and swap-thrashing, with regularly scheduled delivery producing nothing for months and then multiple deliveries at once. First you have nothing to work with, then nowhere to store it.

Free Software people continue to work out the limits to their philosophy. I remember pointing out to them how various GPLv3 drafts meant if the World of Warcraft servers were running busybox and I had a WoW account, the license required I get root access to the server to replace the busybox binary. Which is stupid, but it's what the then-current wording required. Any license that gives manufacturers incentive to burn code into ROM instead of flash and cut the jtag traces so NOBODY can update it is probably not an ideal license, but the FSF has consistently been a net negative since 1993.

Microsoft Github is deleting security tools, while the rest of Microsoft is signing rootkits that connect to IPs in china. Microsoft co-founder Bill gates is using 22 shell companies to surreptitously buy US farmland. Twitter continues to suck at being twitter.


June 20, 2021

Ok, when I upgraded from devuan ascii to beowulf, xfce changed its default window manager policy from "click to focus" to "focus follows mouse" (luckily it's fixable but an upgrade changing that kind of preference is just CREEPY) and THAT'S why I've been randomly typing into so many unintended windows recently. Also, the thunderbird key binding for "a" is "archive". So the reason when I click on a text window and try to pull up a man page and the email message I was looking at disappears and is NOT in the trash folder is it got moved to some sort of archive->year folder.

Linux on the desktop: smell the usability! 30th anniversary edition! (Yeah, I'm trying to salvage _android_, not desktop Linux.)

I'm coming up with a patch to add cut -DF support to busybox (because Elliott thought it would be a good idea), and WOW do I miss my infrastructure. My menuconfig text IS my help text, my #defines are all autogenerated from the OPT_STR (which parses itself before main is called), and instead of having to:

#define CUT_OPT_NOSORT_FLGS (1 << 6)

My plumbing generates a header I #include at the start so I can check FLAG(D) and it Just Works. And if -D had an argument it would be in "TT.D" which would be NULL if none was supplied...

Instead I'm staring at busybox's:

opt = getopt32(argv, "^"
        OPT_STR
        "\0" "b--bcf:c--bcf:f--bcf",
        &sopt, &sopt, &sopt, <ok
);

And going "why is that second line of string data not in the OPT_STR #define up above?" Is there a REASON, or just a convention? It SEEMS like it's #defined up top and then used once and there aren't any other #includes in between, but then why do it that way? And then I'm assuming all that "x--abc:y--"... syntax is busybox's way of saying "[!bcf]" at the end of the option string? So instead of changing it to "[!bcfF]" I need to add a fourth stanza and add F to the first three? "b--bcfF:c--bcfF:f--bcfF:F--bcfF"? WHY does "-b--bcf" have b in it twice? Selecting -b switches off -b? What?

Except I need to make the new -F conditional because busybox micromanages size and has the regex support drop out, and they did it individually in each command instead of having ONE global symbol in the config indicating the presence of regex support (which would be probed for rather than manually selected based on what the toolchain had) and then xregex.h could give you stub functions so it all drops out? But no, they have this nonsense. Sigh...

Is my cut easier to read than their cut merely because of familiarity, or is the busybox one actually harder to understand? I can measure that mine's 100 lines _shorter_, but that's not the same metric...

Oh goddess, I don't want to KNOW what POP_SAVED_FUNCTION_VISIBILITY in busybox's xregex.h does. Not going there.


June 19, 2021

Android has added rust as a supported language, there's an MIT licensed coreuilts reimplementation going on in rust, and Elliott doesn't think C is "salvageable" and is talking up Rust. Sigh. I can see which way the wind is blowing, but I'm not really interested in jumping on board this particular new bandwagon. I intend to get toybox to a 1.0 release anyway, even if Android migrates off of it. They haven't yet, and I'm trying to view this as "deadline pressure" rather than "lost cause".

Meanwhile, once again "not selling past the close" I composed the following big long email and did NOT send it. I need to just reply to the first paragraph with "here's the patch". But for posterity:

On 6/19/21 6:50 AM, Denys Vlasenko wrote:
>On Tue, Jun 15, 2021 at 3:01 PM Rob Landley <rob@landley.net> wrote:

>> The pending follow-up question to my previous email beyond "do you want this
>> feature" was "are you willing to add it yourself, or do you want me to
>> refamiliarize myself with busybox cut.c and whatever libbb sharp edges I hit
>> enough to knock up a patch". I felt the odds of you implementing it yourself
>> were higher if I DIDN'T offer a patch in the email, but if the busybox project
>> only wants the feature if I provide a patch, yes I can provide that patch.
>
> I would be quite happy if someone posts a patch.

I'll take a stab at it, let's see...

Sigh. It would be easier if I could use the existing toybox regression tests for this. Toybox has TEST_HOST=1 so I can run my tests against the host versions to make sure they're testing something real, and if I put busybox cut in the start of the path and run the toybox cut tests against that four of them fail:

FAIL: cut -bO overlaps
echo -ne '' | cut --output-delimiter ' ' -b 1-3,2-5,7-9,9-10 abc.txt
--- expected	2021-06-20 05:22:37.975989241 -0500
+++ actual	2021-06-20 05:22:37.979989241 -0500
@@ -1,3 +0,0 @@
-one:t o:th
-alpha beta
-the q ick 
FAIL: cut high-low error
echo -ne '' | cut -b 8-3 abc.txt 2>/dev/null || echo err
--- expected	2021-06-20 05:22:37.987989241 -0500
+++ actual	2021-06-20 05:22:37.991989240 -0500
@@ -1 +1,3 @@
-err
+:
+e
+c
FAIL: cut empty field
echo -ne 'a::b\n' | cut -d ':' -f 1-3
--- expected	2021-06-20 05:22:38.031989239 -0500
+++ actual	2021-06-20 05:22:38.035989239 -0500
@@ -1 +0,0 @@
-a::b
FAIL: cut empty field 2
echo -ne 'a::b::c:d\n' | cut -d ':' -f 3-5
--- expected	2021-06-20 05:22:38.039989239 -0500
+++ actual	2021-06-20 05:22:38.039989239 -0500
@@ -1 +0,0 @@
-b::c

None of those are the -DF test, that has a "toyonly" annotation so it'll only run it on a command where --version spits out the string "toybox". (Or "This is not GNU" for sed, which would also trigger on the busybox sed I wrote all those years ago...)

I find it ironic that we're arguing how it's ok to be missing stuff (like --output-delimiter or error checking that a range goes from high to low), but anathema to add stuff. I personally consider it an equal judgement call in both directions. One is easier to FIX, but NOT doing stuff for 20 years because a perfect solution may present itself someday and in the meantime doing without becomes the status quo? Most people who hit an issue won't tell you they did.

Even the switch from toybox "ls" default escaping from -q to -b broke some people's use cases, and we coped because where it was before was slightly more broken (the change was to match ubuntu's behavior). That wasn't even a feature, that was a default value. Everything inconveniences somebody. Balance the goals, minimize the damage, apologize where necessary, fix it AGAIN when you get more info...

>> (You may remember I had a dim view of the FSF _before_ the Second Coming of RMS.
>> Now that they've warmly embraced his post-#metoo self back into their ranks, I
>> don't think I'm cynical ENOUGH about them.)
>>
>> >> and assumed it would be easier if both busybox
>> >> and toybox already supported the same syntax.
>> >
>> > Yeah...
>> >
>> > What I worry about is gratuitous divergences we create.
>>
>> Hence us asking busybox if they wanted the new options, yes.
>
> Yes, I would accept new options.
>
> My point is, I would be happier with new options if coreutils
> people would be at least semi-positive about having these
> options as well. With the same option letters and syntax.

I checked the bsd man pages at the time to make sure they weren't using the new option letters. (I think I still had a bsd image running under qemu at the time...)

> The situation of "oh no, fork XYZ added essentially the same
> functionality too...but with other option letters, and they
> count fields from 0, not from 1... and they used OUR option
> letter for something entirely different! ARGH"
> is irritatingly repeating itself, as if we never learn.

I'm aware. I vaguely recall the 0 vs 1 field thing switching awk versions in 2002...

>> So rather than add missing features (or fix incompatibilities) in the
>> implementation busybox already had, you added a second implementation (alongside
>> the other one, without removing it),
>
> Yes. Because now we have users of this other, incompatible implementation,
> and if they upgrade bbox and their scripts break, they will be rightly
> pissed off.

I've generally worked out ways to fix up this sort of thing using the existing code base so far? Abandoning any users the CURRENT tool has isn't good, and adding a second incompatible one is the opposite of help.

But I couldn't even offer to do that with busybox netcat because you didn't say what it was that was needed in the new one, and these days I put that sort of effort into toybox instead of busybox.

> This is one facet of the incompatibility landmines: they are so innocuous-looking
> in their infancy. "I can add this useful option, what can possibly go wrong?
> People who don't need it will simply not use it!"

Many moons ago I split "catv" off as a separate command because I agreed with the article objecting to cat doing -v (it never should have been added, doesn't belong in this tool). Which made sense in the context of busybox already being a subset of existing functionality, but didn't survive my OWN work expanding it into something you could use in an actual development environment running existing scripts. Shifting goalposts...

You haven't been following my bash replacement shell implementation stuff, have you? It's compatibility corner cases all the way down. 90% of that work is figuring out what bash is doing. The actual implementation of toysh plumbing is the easy part. If I didn't care so much about compatibility I'd be done by now, but I'm making a _bash_ replacement, not just "a shell"...

> Right now, with these proposed options, we are doing EXACTLY this.

No, I just think it's a thing cut should be able to do, and that a cut implementation that CAN'T do that is a whole lot less useful.

Why can "sort" trivially work on word ranges but "cut" can't produce them? Needing "awk" for this is a bit like needing perl or python for it, that's a LANGUAGE not a tool. "Slice bread off the loaf? Sure, mount it in the laser cutter and run this program..."

>> with no additions to the test suite or
>> other documentation of the use cases motivating its addition, reasons you had
>> already forgotten by the time I noticed and asked ~3 years later.
>
> Trying to recall... I found my old posts about nc:
> https://seclists.org/nmap-dev/2010/q1/44
> https://seclists.org/nmap-dev/2010/q1/42
> https://sourceforge.net/p/netcat/bugs/37/

In 2003 I posted my "count" tool to the busybox list, which I'd been using for several years at that point, demonstrated as an example in an intro to unix course I taught at ACC in 1999, etc. The busybox list bikeshedded this into "pipe_progress" with a very different user interface. It was kind of annoying that they didn't respect the existing UI, but the new context immediately had more users than the existing one, so that's what won out.

> TL;DR: (at the time of me writing these comments in 2010,) OpenBSD, GNU
> and Nmap's reimplementations of nc were *mutually* incompatible.

Which is why I didn't implement compatibility with "the standard" because there wasn't one, yes.

> Not only
> they broke trivial use cases like "nc -l -p PORT", they broke them
> in different ways!

The functionality in my netcat worked in my testing. There was no standard interface for it to be compatible with. (I looked. ftp was similarly fragmented, as I recall...)

Back in the day I emailed the guy who did busybox awk when his code needed fixing. Even though he wasn't a regular busybox contributor I gave him a heads up about issues in case he wanted to handle it before I tried. But I didn't get emailed about any busybox netcat deficiencies, never had a chance to fix them, and instead found out about the change ~4 years later. (I believe defconfig changed so the other one built instead and broke an aboriginal linux thing?)

Again, do you have a compatibility example OTHER than netcat? (Are there any other commands that busybox has two implementations of in the tree, other than the command shell situation?)

> This should not be happening. People who code Unix utilities should not
> be this oblivious to what happens in real world when people try to use
> their tools.

I'm still subscribed to the austin group (posix mailing list) but stopped posting there after this interaction because I'm not going to deal with Joerg Schilling on a volunteer basis.

That said, they continue to more or less function as _a_ standards body, and the Linux Standard Base does not, so that's "the standard" to eventually try to get into. (IETF doesn't cover this, man7.org doesn't have versioned releases defining a coherent API so what "the cat man page" says can theoretically change a year from now which is why SUSv3 had a 3 in it...)

"Eventually" try to get into because back in the day the IETF had a requirement of two interoperable implementations for anything presented to it for standardization, and that sounded like a good rule to me and one I wanted to follow before bothering posix. Hence poking busybox about the new option.

> I get it that some developers were never wearing
> an admin hat in their careers, but still...

Do you believe I fall into that category?

Working on a patch. Very much out of practice with this infrastructure (and already homesick for mine), but I'll blog about that rather than bothering you here. :)

Rob


June 18, 2021

I'm circling back around to implementing flashcp, and I want to use the 64 bit API but they only merged 64 bit erase, but not the 64 bit write and info commands? The submission had all the commands, but they didn't merge half of them? (Wha...? Seriously guys, it's been TWELVE YEARS since that commit. You wanna finish what you started, or...? I know Linux kernel development culture's gone toxic and dysfunctional but this is just silly.)


June 17, 2021

A decade ago china built a bunch of nuclear power plants in response to the 2008 Beijing Olympics (the same time it started seriously copying Germany's solar panel technology: because its air quality was an international embarassment), and modern chinese construction projects tend to fall apart after a few years. Which brings us to the reactor leak du jour in china, which made me curious about whether anybody sold a geiger counter that plugs into phones, and it turns out yes they do (and they seem reasonably functional).

I miss having a twitter account so I could ask Sarah Taber about this. (Meanwhile, here's a fascinating thread I have absolutely nothing to contribute to other than attention.)

Republicans invent labels (like "partial birth abortion") to steer the narrative. It's called "framing the debate" and THAT link goes to a 20 year old article about when the first went all-in on this strategy.

Billionaires gonna bill. Billionaires are buying up residential real estate (although it's not _just_ blackrock doing it), and Bill Gates is buying up all the farmland he can. France fixed this kind of market cornering with tax policy, but they deployed guillotines first. (You have to get the parasites off before you can prevent their recurrence. Cut the tumor out THEN chemo. Drain the abcess then antibiotics.)

The Boomers will never go for that, for a definition of "never" that has maybe a decade left, during which they're trying to make The Handmaid's Tale become a documentary. Boomers are blind to their own biases, and immediately forget anything they don't like.

We still need to defund the police. We can at least start by disarming the police.

Handy infographic to help spot the left wing wrapping around to fascism.


June 16, 2021

Ok, I like the new FTC chair. That's good news.

The remains of Freenode seem to have found a way to faceplant harder. The obvious reason to switch servers is moving from the volunteer-provided servers to ones owned by Andrew Lee. That's why "the old servers are still up": because Lee doesn't operate them, and thus can't take them down. Other intersting tidbit from this article: Freenode had 70k users before this. The old volunteer-run freenode servers they're migrating off of collectively report 27k users. The new ones... 1500. No that's not missing any zeroes. Freenode has even lost the Free Software Foundation, leading to the obvious joke. *shrug* #toybox and #jcore are still at libera.chat.

Implementing the "declare" statment in toysh, and... "g" and "x" are different! Of course they are. You can export a local. Global means "not local". And of COURSE "declare -pg" does not work. The local still completely hides the global from the point of view of the function, but now I can write to something I can't read. How nice.

$ X=potato; chicken() { local X=42; declare -g X=abc; echo local=$X; declare -pg X;}; chicken; echo $X
local=42
declare -- X="42"
abc

Except locals NEST. Is there a syntax to say "write to previous nested context before this one?" Of course there isn't. Why would there be?

Sigh, how much of this is because I hadn't noticed before, and how much is because I finally updated from devuan 2018 to devuan 2020 and thus got a new version of bash? Compatibility with a moving target. Grrr. (Yes I stayed on an LTS for 3 years. The horror.)

To be honest, I'm mostly trying for compatibility with bash 2 (which was released in 1996 and just had bugfix releases until 3.0 came out 8 years later) and anything else is a bonus. The FSF had a multi-year period where they were dead and irrelevant (gcc forked to egcs, tar went 5 years between 1.13 and 1.14 releases where all the distros patched in -j to support bzip)... They were snapped out of it when their ftp site got cracked because nobody'd paid attention to it in forever, and people went "oh hey, we inexplicably depend on this stuff, it's easier to put work into it than migrate off". Bash 3 was part of the gnu revival that led to GPLv3, which is not exactly an endorsement. But Chet seems reasonably independent, and several of the new things get used (for a definition of "new" that's over 15 years at this point), so I _am_ implementing against the current bash man page and what the bash on my laptop right now runs. I'm just not _that_ bothered by it being a moving target.


June 15, 2021

I emailed 4 recruiters yesterday and asked an organization about sponsorship for open source work. Two follow-up phone calls so far. (Job hunting is emotionally exhausting, and tends to START when a job has already wrung you dry.)

I'd follow up on the "how google sponsors open source projects" link Elliott sent me back in March if it hadn't gone down shortly thereafter. I can fetch it out of archive.org but I'm assuming it's no longer current policy. Google the corporation does not culturally understand paying people who are not full time employees, and the money side of the company has only EVER shown interest in me as a "Site Reliability Engineer" which just SOUNDS like being paged out of bed is your job.

VOIP call with Jeff went a bit sour today: he's been bait-and-switching me on work where we sketch out a technical thing that would be great to do, and then he tries to turn it into "how do we issue an NFT coin on this", which I have zero expertise or interest in. Today I wasn't having it: I do not understand the coinbro mentality, I don't know why "issuing a new coin" is ever a good thing. I cannot help with that part. I understand that bitcoin is used for money laundering, and by the "unbanked" like sex workers who can't get access to the existing banking system due to stupid prejudice and persecution, and that's the fundamental underpinning of that having a nonzero price. (Its use as a medium of exchange is nearly drowned out by the Beanie Babie speculative tulip bubbles, of course. Governments spend a lot of money each year stabilizing exchange rates. Libertarian clowns who think stuff "just happens" because their servants operate discretely are pampered idiots.)

I've been focusing on plans where we make a thing that works and can then manufacture and sell it to people, and today when pressed Jeff said he no longer believes investors looking for that actually exist. He didn't quite phrase it this way, but he now seems to think the ONLY source of funding left (to him) is crypto-bros looking to pump-and-dump a coin they'd buy from us and sell on to someone else for more money. (Why would it be worth MORE money to a second person? </jazzhands>...) And that the business model actually DOING anything discourages them. (It's a responsibility, obligation, unnecessary complication...)

I... can't help with that.

(I just want to program. Unfortunately there's all this capitalism getting in the way.)


June 14, 2021

Why do I do zero clause BSD? Because copyleft easily turns into a trap.

The ELC CFP says it closed at 11:59 pm pacific time on the 13th, so looking at it at 4am central time I'm pretty sure I'm off the hook for any obligation to submit a proposal. (The button still seems active on the web page, but they made the deadline and I assume their database would discard it. That solves the "I feel like I should" vs "yeah but I don't really WANT to" conflict. Pressure's off, I can relax and take the loss.)

Sure there's plenty of stuff I want to talk about, but... I normally submit 4 proposals on different topics to give the commitee something to chose from. It's a defense mechanism for the ADHD symptom Rejection Sensitive Dysphoria: when I submit one proposal and it's rejected I tend to lose interest in the conference, that's why I didn't bother with the O'Reilley conference even though it was in Austin for 2 years: I'd previously submitted a talk proposal and been turned down and my brain Sour Grapesed it into a conference not worth attending. (And I can't go and NOT talk because they charge $500 to attend; the talk is literally the price of admission.)

Coming up with many different topics of potential interest isn't usually hard for me, but right now I'm in a "focus and get things DONE" mindset. I have been stretched too thin, and things I wanted to see happen may never come to pass which means I wasted (a lot of) effort on them. Leaving this job means leaving the j-core/gps/vpn work without any of it getting properly commercialized. The C++ crowd driving everybody from C to Rust means circling back to tinycc/qcc someday... may not happen?

At my day job I've been suggesting interesting things we COULD do, and building development/business plans around them, for months. Hey Jeff, here's another plan you can wave at investors and maybe get funding, it would be great if we could do THIS... and I'm tired.

Work still has not managed to run payroll yet this month. That's two full weeks into the month with no paycheck, I should really start looking for a new job. (I love the people, I love the technology, I love going to Japan, but running up a home equity loan to keep doing somemthing is not a job.)


June 13, 2021

I honestly didn't realize that the news articles about last night's mass shooting here in Austin weren't talking about the previous mass shooting until Fade informed me. I was around 25th street when it happened, 19 blocks north. Remember that new GOP law that guns no longer require permits? (But cars still require licenses.) Expect more of this, I guess. (That law doesn't even kick in until September 1, this is the pre-anarchy level of shooting.)

There should be a NAME for the big problems being easy and the small problems being enormous time sinks. Things like dunning-kruger and "disruptive technologies" become so much easier to talk about once there's a name for them. (Yeah people misuse the name, welcome to humanity.)

The sh2eb support in toysh had a regression, which I'm laboriously tracking down on my turtle board with "add next debug printf(), cursor up to big long compile line, pop sd card from board, stick in adapter, cursor up to sudo copy vmlinux to sd card (type in expired password), pop adapter, click sd card back into board, plug usb serial/power cable back in, cursor up to sudo microcom to see serial console, unplug/replug board about 3 times until it actually boots (something about this bitstream, it works fine once it's up but doesn't want to load reliably...), frown at output, rinse repeat". It's not HARD, but it's very tedious.

There's almost certainly a more elegant way to do this. The REAL fix is "I should remember to pack an ethernet cable next time" (and script the dance of the loopback cable setup with 192.168.1.42 and 192.168.1.43 addresses assigned manually via ifconfig/route, which was a real PAIN making work on ubuntu because networkmangler would ifconfig them back DOWN again twice a minute so I had a "while sleep 1; do ifconfig...; done" loop going in a tab because making networkmangler STOP DOING THAT without killing it was impenetrable, and killing networkmangler meant bringing the wifi up was painful....) Anyway, hopefully devuan doesn't have that problem and I can just DO it, but I need to remember to pack the cable.

Meanwhile, I could uuencode the vmlinux and paste it across the serial console, but that's not really FASTER than popping the card and copying it. Nor is it fewer steps using mousepad to actually cut and paste a file. A quick google finds xclip -sel c probably does what I want from the command line (hopefully without size constraints, the file is 4 megabytes before uuencoding and I was using mousepad because it doesn't choke on selections that big). And then there's the problem that our current turtle j2 bitstream doesn't support soft reboot because our "boot rom" is just an sram block that's initialized to known contents via the bitstream load, but then that sram is repurposed as L2 cache when Linux comes up so when you reboot there's nothing to reboot INTO unless you reload the bitstream. There's a physical button on the turtle board that does that, but I can't reach it without taking the board out of the case (downside of repurposing rasperry pi add-ons) and I dowanna. (Exposed circuitry, no anti-static wrist strap.)

It's one of those things where I can spend cycles on infrastructure to come up with a faster way to do this, or I can just do it manually, and figuring out which is the best use of resources is non-obvious. I know the tedious way at least makes measurable progress and termiantes. The tangents tend to spawn tangents...


June 12, 2021

As the temperature has risen the mosquito population at my nightly work table at the UT geology building has gone up with it. They're not a problem late at night (yet), but around 6am they start to converge. I re-apply bug spray but there's a CLOUD of them hovering about a foot away. You'd think the bats would eat them, but in rainy years the bats can't keep up and Austin has an outright monsoon season now. (That's not a joke, it's climate change. The monsoon band that used to hit Mexico has shifted up to cover Austin, and the droughts we were getting have shifted north.)

The ELC call for papers closes tomorrow, and I just don't feel like trying to deal with it. I should make and upload videos, not fly across country (at my own expense!) to visit rooms full of white middle aged men.

My job going under is part of it. They haven't managed to pay me yet this month, so I took more money out of the home equity loan and gave my first "here's my resume, tell me more" reply to a recruiter email instead of the usual "sorry, I'm busy". (It's not a job if I'm not getting paid, it's a hobby. And I have plenty of hobbies already.)

Still banging on toysh. I do not understand what $SHLVL is for. I _thought_ I did, but:

$ echo $SHLVL; (echo $SHLVL)
1
1
landley@driftwood:~/toybox/clean2$ echo $SHLVL; echo $(echo $SHLVL)
1
1
landley@driftwood:~/toybox/clean2$ echo | echo $SHLVL
1

I mentioned bash "optimizing out" subshells, but this is a bunch of cases where it seems to need to HAVE subshells?

$ time if true; then sleep 5; echo $SHLVL >&2; fi | if true; then sleep 1; echo $SHLVL; fi
1
1

real 0m5.005s
user 0m0.006s
sys 0m0.004s

The two sleeps happened in parallel therefore it HAD two shell instances, one for each if/fi in the pipeline occurring in parallel, but $SHLVL was 1 both times? So what's it measuring?


June 11, 2021

Trying to wean myself to "every 4th day" instead of "every other day" on the <span id=politics> entries, but boomerdamarung has not slowed down. Just been locally muffled. Maybe I can just stick one paragraph at the start of entries without accumulating too much of a backlog? Especially if it's "good news", whatever that means these days.

I'm trying to figure out if the proposed antitrust legislation is good news. I think it is, but I've been tricked before. (Meanwhile, Google's most recent attempt to eliminate the URL so people have no navigation option except google searches was about as well received as I would have expected.)

The "tether" scam propping up the price of bitcoin is nearing implosion, and sadly may take down El Salvador's economy with it.

As a white male american, I grew up thinking "we are the good guys" in basically everthing. It's important to recognize that we are not always the good guys. Sometimes you have to acknowledge, change course, and often fix what you broke to the extent you can even when it wasn't you personally that broke it (the "royal we" has splash damage). That's why it's my job to acknowledge that you can sing T-mobile is sexist to "Every Sperm is Sacred" (although the accent falls on the wrong syllable, and it's not so much them as a pervasive cultural problem). Or boggle at attempts to dodge accusations of racism by being even more racist.

The REASON I grew up thinking "my tribe never does anything wrong" is I was shielded from it by people who never mentioned the many things my tribe was doing wrong. The police were represented as incorruptible and upstanding instead of a net negative resource drain in serious need of defunding. We replaced aristocracy with plutocracy. The fight over what lies public school textbooks should contain is not new; heck, that's what the Scopes Monkey Trial was about in 1925 (the 1960 movie about which was nomiated for 4 oscars).

Of course recognition that "yes, we did wrong" can be weaponized against the people doing the recognizing. The "plastic straw" style hairshirt distraction remains effective and is an explicit strategy used against people who want to performatively repent and make others do the same. I've grown tired of watching left wing activists wrap around to the far right. ("Fanaticism consists of redoubling your efforts when you have forgotten your aim." - George Santayana.) But our sexist culture killing young women and making the rest alcoholics is a PROBLEM. Racism is a problem, global warming is a problem, plutocracy is a problem: the world the Boomers have steered into a ditch is collapsing around us all and they need to STOP DRIVING.

The supreme court just unanimously ruled that the FTC can't force companies convicted of scamming their customers to pay them back. The Boomers' system is broken, and the fix is to remove all Boomers from elected office. Electing Boomercrats fixes nothing. We need to fix the system.

Sigh. No, don't use facial recognition as yet another way to deny benefits. (Don't means test the benefits at all, just make them universal like public school and the ability to call the fire department.)

Internet should be municipally provided like water and sewage (and in Austin, electricity). The private ISPs suck at it.

A common GOP trick answer all questions in private, off the record, with no recording or public accountability.

Lip service (n): anything Merrick Garland does.


June 10, 2021

It's always nice when people who used to actively oppose what I'm doing come around to my side of the argument.

Once again Devuan failed to suspend my laptop when I closed the lid, and I didn't notice, so the battery drained in my bag and I lost all my open windows. Since I did a full backup yesterday, I decided it was as good a time as any to bite the bullet and "apt-get dist-upgrade" from Devuan Ascii to Devuan Beowulf. Except running that command as root turns out to be a NOP, first you have to manually edit files and then the process is a lot of steps, and prompts for many things I do not care about. (I'm not reading the release notes of hundres of packages, I don't care what they decide to show me and get me to click through. "Just do it.")

And yes, the power management bug that thing says to manually downgrade a package to work around is still there a year later. The last few entries in that bug tracker are literally spam emails. (Query: does that package simply never upgrade again? Stuck at that version forever? Will this cause a problem with library version skew at some point using ancient binaries?)

So much user interface stuff changed and needed to be tracked down and changed back. The background color changed from a light grey-blue image to a dark red image (changed it back). The terminal window font changed to something that wasn't even MONOSPACED but a reboot fixed that. Thunderbird's changed fonts and decided the list panels need to have a dark grey background so the text has less contrast... and it's replacing > in replies with outlook style vertical reply bars! URGH. KILL IT WITH FIRE. How do I...

(2.5 hours of searching later.)

Ok, this comment from five years ago is still current, albeit the .css file is ignored. But there's an advanced magic config editor ALL THE WAY AT THE END of the "general" tab of preferences, where you can toggle the magic booleans indicated and now it merely COLORS the reply lines insted of microsoft-outlooking them. But "reply color" has its own separate config thing under the general tab where I can set it to black, and then thunderbird is spending a lot of extra effort to behave normally, which is Mozilla in a nutshell.

Back on Kwajalein age 7 I was diagnosed "hyperactive". These days we'd call that ADHD with definite elements of the autistic spectrum I've spent a lot of effort learning to performatively paper over, but I still REALLY DISLIKE my daily environment changing out from under me without warning. If you get into your car and the steering wheel is on the other side today, I feel you have the right to be annoyed by that. I didn't like twitter doing it, I don't like my Linux distro doing it, and I'm still using stuff like Google and Chrome because they DON'T do that much. They put the new stuff off to one side and there's always a way to make it stop bothering you until you have some downtime to experiment.

That said, my resistance to systemd (I.E. reason I used devuan rather than debian) isn't because I haven't tried it. It's because systemd is an insecure pile of unnecessary complexity with a design that violates the unix philosophy.

And hey, devuan/chrome even restored my open browser tabs after the upgrade. (Here's a good history of tumblr.)


June 9, 2021

Didn't make it to the table tonight because of 3 hours of intense intestinal distress shortly after eating the rest of that absolutely delicious date cake fuzzy made. Last time I ate some I got my first visual migrane since I stopped drinking energy drinks. I think I'm allergic to something in that cake.

The finance guys have finally pulled the plug on the keystone xl pipeline, which is probably a sign that all oil projects are now categorized as stranded assets, which is sort of the commercial version of an underwater mortgage. It means the revenue stream from this won't last long enough to pay off the loan taken out to build it, even before you include cleanup costs decomissioning things like oil wells. (One reason abandoned gas stations STAY abandoned for so long is it can cost quite a lot more than the purchase price of the property to clean up old underground fuel storage tanks that slowly leak petroleum products into the surrounding soil over the years, and of course the purchaser would be on the hook for that (ala love canal). This has been a known problem for decades.)

Twitter remains bad at being twitter.

Israel's far-right (led by 71 year old Benjamin Netanyahu) is losing power, and thus gearing up to do their own January 6th style insurrection to topple the government that didn't re-elect them.

$DAYJOB has now gone through THREE different "money/sales guy" Boomers who went senile on the job and had to be eased out to pasture because they could no longer function. Some were only in their late 60s when it happened. (Of course "Boomers never let go" was operative every time; denial of incapacity and doubling down in the face of all evidence.)


June 8, 2021

Sorry if the toysh blog entries get a bit repetitive but job control is one of those changes that refuses to break down into smaller chunks, and I keep having to restate stuff to get it clear in my head what I'm trying to do next, especially when small parts of it don't quite line up right yet (leaving rough edges that may indicate unresolved design issues).

I think I've got most of the subshell backgrounding sorted out now (parentheticals, pipelines around curly brackets, and blocks like if true; then echo hello; fi > filename & getting backgrounded). The trick was ripping the run_subshell(NULL) option back out and instead adding another if (CFG_TOYBOX_FORK) check to the one-and-only caller of run_subshell() with a NULL, and have it do the fork() stuff itself, and in the nommu else case do the pl2str() itself and call run_subshell(str, len) like all the other callers do. The run_subshell(NULL) option was trying to avoid extra if (CFG_TOYBOX_FORK) stanzas, but there's already multiple instances of that test in toybox and the result of having the test in run_subshell() was "sometimes it runs a child shell, sometimes it returns twice to the caller" which was just incoherent. Now run_subshell() always spawns a child process to "eval" a chunk of shell script, returning the child's PID. When that's not what we want to happen, we don't call it and the caller does the fork() itself instead.

But tying that off still leaves four unfinished functions: fg_pp(), bg_pp(), wait_main(), and run_subfunc().

The foreground and background process functions (fg_pp() and bg_pp()) take a struct sh_process *pp and either foreground it (waiting for it to end) or background it (adding it to the jobs list). My current thinking is the foreground job shouldn't be ON the jobs list, it should be in TT.fg which previously existed as a hack for exec_main() called TT.pp but is being renamed and genericized.

The wait_main() function implements the wait command, which is a bit of a can of worms due to the 4 types of things you can wait for: %tasks, numeric pids that were backgrounded at some point, the most recent $! process which is kind of a special case for <(a specific bash extension), and the TT.fg foreground job. Except TT.fg is only waited for by fg_pp(), you can't use the "wait" command on the foreground pipeline (which would already wait for itself and have to complete before you could run the wait command), but they're both sort of the same infrastructure? You don't know what child process is exiting next, and "set -b" says to asynchronously report jobs so the plumbing needs to handle each exiting process as it comes rather than doing waitpid() for something specific. And that means doing waitpid(-1, &stat, maybe_nohang) and hunting though TT.fg, TT.jobs[], and TT.bangpid, and when the last pid in a TT.jobs[] pipeline exited adding it and its exit code to the dead process memorial.

And since TT.memorial[] needs to store the PID and the exit code, I can combine them as (pid<<8)+exit and as long as I'm doing that anyway I might as well eliminate pp->exit and keep it in pid always. Which is another "pull the thread and see what unravels" change pass but logically part of this design shift.

The run_subfunc() function is about running individual functions and builtins in their own process (whether backgrounded or not). Where run_subshell() is handling blocks and pipelines, run_subfunc() is handling individual commands what WOULD be run_command() except there's nothing to exec() out of the $PATH for this one. This still involves marshalling data to a child shell, but the command line you run in there has already been parsed, it HAS to be to see what we're running:

$ X=echo; > potato $NOTHING $X hello
$ cat potato
hello

We can't know that we NEED to run a shell function until we've parsed the command line, and yes that redirect is BEFORE the command to run; variable assignments also come first. You can expand the entire command line and wind up with an empty string at the end and thus not run anything (although running $NOTHING as its own command blanks $_ which just hitting enter doesn't, thanks bash).

Avoiding parsing the command line again isn't just an efficiency thing: repeating variable expansions would make side effects like $(x++) happen twice, and repeating redirects would cause "set -o noclobber" exclusive file creation to error out. Re-parsing the command line isn't just expensive, it would be full of buggy corner cases. So instead, we wrap each already-parsed argument in $'stuff' with appropraite backslash escapes, although bash's ${x@Q} logic is doing something more complicated and if I implement that I should reuse the function...

The problem with doing all THAT is $BASHPID is going to resolve to the parent PID, since that's the context in which the expansion took place: "true | echo $BASHPID" would give the $$ pid not the "readlink /proc/self" PID. Supporting vfork() makes that VERY HARD to get right, because you don't know the new PID until after the vfork() and you don't unblock the parent until the child exits (discarding said PID) or execs() which needs to know the new command line and have all the redirects resolved already. Unless you do the variable expansion and redirects in the child process after the vfork (which is DEEPLY inadvisable) expanding $BASHPID can't know the right values.

The only[1] way to get $BASHPID right would be to run EVERY pipeline segment through run_subshell(), so the command line is expanded in a child process, and then add an implicit "exec" on the front of single command subshells. Even WITH a fork() that's expensive because it glues the parsed arguments back into a string (which is what nommu needs to send the data through the pipe) and then parses them back into individual arguments again.

Sigh: run_subshell() started life handling $() contents which were kept as a string all along because "$(blah)" is logically one argument until it's evaluated. But now with case patterns) potentially living in $() blocks the simple parentheses counting approach isn't good enough, although supporting that remains a todo item. But having the caller produce the string instead of having run_subshell() traverse a list of pipeline segments is what I just went BACK to, noticeably simplifying the design.

The thing is, most commands don't need any of this. The "parse command line, vfork() and exec()" approach is the COMMON CASE. It's fast and efficient when you're NOT in a pipeline, and in that case $BASHPID is showing you your shell's PID anyway. Running "echo $BASHPID" several times in a row, typed in at the prompt each time, will repeat the same PID. And for ( echo $BASHPID ) subshells, the toysh design would get it right, or at least match bash:

$ (echo $BASHPID; readlink /proc/self; echo $BASHPID)
14860
14861
14860
$ (/bin/echo $BASHPID; readlink /proc/self; /bin/echo $BASHPID)
14866
14868
14866

This is bash implementation details bubbling up to the surface. (Note how readlink is one higher than echo but 2 higher than /bin/echo because shell builtin: implementation detail!) I'm not sure TRYING to match it is the right thing to do? In toysh, evaluating arguments to the function CALL happens in the host context, running the argument BODY takes place in the child process, and $BASHPID shows that. That's... not wrong? But not the same. Hmmm...

[1] Modulo horrible in-band signalling that's probably even worse.


June 7, 2021

Canada is still in denial about the whole child murder thing. Late Stage Capitalism has now invented a barbecue with proprietary charcoal. Disaster patriarchy is analogous to disaster capitalism: the haves using any crisis to tear down the have-nots. Defund the police. Atheism is a religion the way zero is a number (they have specific beliefs, prostletyze about them, persectue unbelievers, and so on) so of course that cult has joined the GOP right alongside the evangelicals.

Microsoft continues to suck. Not that Faceboot and Google are exactly covering themselves with glory these days, and I sent the last Amazon recruiter to contact me (ten days ago) the first three links that came up when I searched for "amazon employee" in recent news, which did not include yesterday's facepalm about taxes. (Amazon doesn't report a profit because it chooses not to, it's always spent the money on growing bigger instead which just HIDES the profits. They've always used it to dodge taxes, and are trying to nerf new tax laws so their trick still shields them.) And don't get me started on Elon Musk, who's still regularly mocked about buying credit for things he didn't create; dude's been operating under a cloud of drama since before paypal.

Intellectual properly law is not salvageable. In a post-Boomer world we need Universal Basic Income to support artists and inventors, with improved systems like Patreon, plus better snopes-style attribution tracking. Today our political system is paralyzed by Boomers and nothing can be done until enough of them leave the voting pool.


June 6, 2021

I have once again lept to the defense of C when perhaps I should have kept my mouth shut. I'm old enough that I'm constantly scrutinizing my opinions for "is this right or merely comfortable". I'm willing to learn other languages, but so far nothing does what C does better than C.

Technical merit aside, I'm not sure that C can be politically defended because the C++ people are trying hard to drag C down with them. That's a shame, and a practical annoyance, but FIXING it would require as much marketing effort in FAVOR of C as the C++ people have put into standing on top of it and screaming "look at me, not them!" Failing that, all I can do is watch it happen and adjust to the fallout.

So toysh forks a subshell if A) the curent command ends with the "&" background operator, B) we're in a parenthetical block, C) we're in a pipeline. Right now I literally have code doing if (TT.ff->blk->pipe || !strcmp(s, "(") || (ctl && !strcmp(ctl, "&"))) to see if it needs to call run_subshell() there. The problem with that is if a command is in a pipe, and in parentheses, AND backgrounded with & it only spawns ONE subshell to handle all 3 cases. Shouldn't it spawn multiple nested child processes if you annotate multiple times?

Testing bash's behavior, the answer appears to be... no?

$ echo $$; echo $BASHPID >&2 | ( echo $BASHPID ) > $BASHPID
6206
6377
$ ls -tr | tail -n 1
6378
$ cat 6378
6378

The parent shell is 6206, the first pipeline segment is 6377, the second pipeline segment is 6378 when evaluating the redirect and it's STILL 6378 when running echo inside the parentheses. The ( ) in that pipeline is being ignored (optimized out?) because the process is already in its own shell. And it looks like it does that a lot:

$ echo $BASHPID& (echo $BASHPID)&
[2] 13068
13068
[3] 13069
[1] Done ( echo $BASHPID )
13069

Consecutive PIDs even though the second one was inside parentheses, and the PID output by echo is the same one that got backgrounded as a job. Translation: the parentheses did not spawn a subshell within the context they ran.

$ readlink /proc/self& (readlink /proc/self)&
[1] 13196
[2] 13197
13196
13197

Not an artifact of how variables are evaulated, it's what the commands themselves see when they run.

$ readlink /proc/self >&2 | (readlink /proc/self) & readlink /proc/self
[3] 13286
13286
13285
13287

Three consecutive PIDs (if in a different order, partially due to one going to stderr and the other two going to stdout).

$ readlink /proc/self >&2 | (readlink /proc/self) >&2 & | readlink /proc/self
bash: syntax error near unexpected token `|'

I.E. you CAN'T have an & within a pipeline, the terminators are exclusive.

$ (readlink /proc/self&); readlink /proc/self
14117
14118

It's not an attribute of ( ) either, & inside parentheses won't fork an extra process going in the other direction either. Hmmm... and this is related to:

$ readlink /proc/self; bash -c "readlink /proc/self"
14264
14265

Which I've had on my todo heap forever. The bash process doesn't fork(), it does exec("readlink") from within the bash PID that ran -c, because it knows that this is the last command (presumably with no "trap EXIT") and thus it's already IN an otherwise empty process context. Note that the Defective Annoying SHell doesn't do this:

$ readlink /proc/self; dash -c "readlink /proc/self" 14367 14369

Non-consecutive PIDs because the dash process forks to run readlink.

A nommu shell has to vfork() and re-exec itself, which means FINDING itself. This makes

A NOMMU subshell is way more expensive than just a background process: a background process is just vfork()/exec() of a command line we've prepared. The difference between fork() and vfork() there is minimal. But a subshell has to re-exec the current process, which is awkward: I first asked the linux kernel developers if there was any way for a process to re-exec itself without /proc being mounted 15 years ago, and most recently brought it up last year, but just haven't had the spoons to engage with linux-kernel for a while now.

And then once the shell has re-execed itself to unblock the vfork()ed parent, it has to re-establish the current context in the child shell by creating strings representing all the currently defined variables and functions the new shell snippet might use (local variables, read only variables, integer variables...) and send them through a pipe to the new process which reads and digests them, and then reads and executes the command(s) the new child process should execute in the new context.

I have that code already, but it's expensive. (And I need to update bits of it to fully support functions.) To avoid this expense, I want to do enough analysis to see if the command in the pipeline is a shell function (needing to run in a shell), a shell builtin, or an external fork/exec command, so the 99% of the time it _is_ running something like "ls" it can just vfork() and exec the thing without depending on /proc/self/exe to exist or marshalling anything through a pipe.


June 5, 2021

Catching up on Paul Krugman's columns, when people talk about 1970's inflation (stagflation) they often treat it as a labor supply problem. Except the Baby Boom was entering the workforce so there wasn't exactly a shortage of labor. (There may have been a shortage of Greatest Generation skilled labor from World War II veterans; but warm bodies to throw at a problem weren't hard to find.) The real problem was the origin of the phrase "volatile food and energy prices".

The "food" part was a series of worldwide crop failures (due to the initial climate shifts that started the modern alarm over global warming), resulting in trade shenanigans that caused the price of food to spike. This popularized an alarmist book about how humanity was all gonna die because those dirty foreigners would breed faster than the food supply and eat all the white people's food. This fearmongering lead china's easily influenced dictator Mao "Dunning Kruger" Tse-Tung to institute the famous "One Child" policy in 1979 (following up on his violent revolution murdering millions to take over the country, "The Great Leap Forward" murdering millions more, and the "Four Pests Campaign" starving millions, with a way to just _prevent_ millions from ever existing). Meanwhile in the reality-based community, Norman Borlaug's Green Revolution quadrupled the world's food supply and put us all into permanent food surplus ever since by (among other things) removing limits on application of the Haber-Bosch process to agriculture. Borlaug won the Nobel Prize for for this in 1970, but it took a while to deploy globally and scale up. (And yes, the 1967 Star Trek episode "The Trouble with Tribbles" named Quadrotriticale after the same "triticale" wheat/rye hybrid he was working on at the time in his nobel prize biography. Mao started his mass sterilization campaign 12 years later.)

The "energy" part was the OPEC oil embargo, started as boycott to punish the USA's support of Israel when the arab states attacked it in 1973 and turning into an economic bonanza for Saudi Arabia when oil demand turned out to be way less restricted by price than anyone had realized, since especially after World War II we were using it for EVERYTHING. (Home heating, transportation along the new brand new interstate highways, electricity for refrigeration and air conditioning, newly invented plastic soda bottles, all that Haber-Bosch nitrogen powered by fossil fuel energy...)

The spike in food and energy prices gave us the inflation, and the federal reserve added the stag- part.

Today, things like used car prices are being driven up by catalytic converters, where covid-based rare earth mining/refining disruption has driven the prices of the platinum/palladium/rhodium in them up over a thousand dollars an ounce, so old cheap cars are being junked to sell the catalytic converters (when the part isn't outright stolen from parked cars). Of course Boomer Media writes entire articles about the dwindling supply of used fossil fuel burning cars without ever MENTIONING this issue.

Articles about the "global chip shortage" never seem to mention the sanctions against China's largest chip manufaturer when discussing said global chip shortage. Orders they would have filled have now gone to the other fabs, which are now backlogged. Sure, SMIC is only the fifth largest global semiconductor foundry, but that seems kind of significant? And Japan had TWO semiconductor plant fires (the one in March made news in the USA, but one back in March didn't) which makes me think there might have have been some sort of insurance fraud with the covid-idled plants that still had to pay rent? Dunno...

It would be nice if we had a little more "why", but you have to TEACH history before you can analyze it and apply that analysis to current issues...


June 4, 2021

Last night I had my first serious visual migrane in several years. No idea what triggered it, but it was really annoying. (Way better than having a stroke, of course, which is the other thing that comes to mind when "there is a serious problem with my vision and it's the same in both eyes" happens.)

Circling back to weaning the $DAYJOB root filesystem off of busybox, I have a current vmlinux but not the cpio.gz file? Let's see, readelf -a gives me a file offset for the start of init.data, and the gzip signature is "1f 8b" so find a plausible start, dd the data out starting there and pipe it into zcat and pipe THAT to cpio -tv and ... boom, got the files.

Ok, run the busybox out of that and it says:

[, cat, dd, dumpleases, echo, flashcp, httpd, hush, ip, ntpd, route, sh, sleep, stty, test, tr, udhcpc, udhcpd

Toybox already has "[ cat echo sleep test" (which are probably enabled in busybox for sh/hush), and toybox also has an sntp client which can be used instead of ntpd -p. (You can use an sntp client with an ntp server, but not the other way around.)

Toybox pending has dd, stty, tr, route, dhcp client and server (dumpleases is a udhcpd tool), and although there's also an ip in toys/pending that was being used to set up the kernel wireguard implementation (which is being replaced with a userspace one). This means the commands toybox hasn't got ANY implementation of are just httpd and flashcp. I actually started on flashcp last month, I should dig that up...

A toybox httpd is basically reverse wget, and just needs to serve static files and cgi. Either it's a file sent verbatim, or it's a child program to execute in a netcat-ish way with known environment variables. (That even handles cookies, which are sent from the browser to the server as http 1.1 "keyword: value" lines. I did that at some length in 2002, don't remember the details but I can look them up.)

Plus some basic rate limiting (as in drop connection, not 503 error: that's also SENDING A PAGE. If somebody tries to flood/tiergruben you, refusing to ack and close connection for 503 errors is just as paralyzing).

The tricksy bit is supporting https. I wanted to pipe it through the openssl/bearssl/stunnel command line wrappers, but Denys built an https engine into busybox? Sigh. Feature parity implies I should too. Supporting ONE handshake crypto and ONE symmetrical data flinger crypto type doesn't seem that hard (and there's RFCs on them?) and it's not that far off from learning/implementing another data compression engine; a largeish timesink but I've done worse. But the list of server keys (while easy enough to install) is an external dependency, so by default toybox would only serve self-signed pages? (It should come up with the signing key in a secret but consistent way for a system, and I have NO idea what that would be... Hmmm.)

Right, first pass, get http:// right without the s.


June 3, 2021

Amazon is creating a mesh network protocol so refusing to give your washing machine access to your router won't stop it from automatically connecting to your neightbor's wifi to exfiltrate data about you for their information gathering. Starting to think I need a remodel to install faraday cage wires in the drywall. (My phone can get the password to my router, the point is ME granting internet access to devices. My TV does not get it. Admittedly I expected cheap cell modems with ipv6 addresses to eventually show up in everything, but thought I had a few more years before it would be cost effective enough to worry about.)

Tesla continues to suck at self-driving. Google spent 8 years longer than everybody else working on self-driving (mostly at a maximum speed of 25 mph) before trying to deploy for a REASON. Every time those clowns make another stab at monetizing this they set back regulatory approval of the technology another 18 months.

78 year old Biden continues to sabotage his own plans to beg for republican approval he will never get. (Meanwhile, the administration's cleaning house goes very slowly, but it's still it's refreshing to be up against a snorlax instead of a nihilego.) 71 year old Netanyahu continues to want to destroy his country rather than give up power, but then attacking the process is how fascists advance their agendas. And yet another source points out conservatives focus on STEM because studying humanities makes people less likely to vote "conservative".

Canada's processing of the discovery of hundreds of dead children buried under those catholic schools they forced indigenous children into to destroy native culture has advanced to the finger pointing stage. If you're wondering where the taliban came from, this thread on soviet atrocities in afghanistan and this one on the USA making it worse are a good start. The Bitcoin Money Laundering Protocol has been having a bad week.


June 2, 2021

Dan Brown submitted a patch series to md5sum.c to add sha2 support, doing all 4 (sha224, sha256, sha384, sha512) variants. I've cleaned it up and am pretty happy with it. (Bit more I might do, but it's good for now.)

That's one of the big remaining chunks of TODO stuff in the roadmap, and lets me remove two items from the $PENDING list in scripts/install.sh, which implements "make install_airlock". The remaining $PENDING commands there are:

dd diff expr ftpd less tr vi wget awk sh unxz xzcat bc bison flex make nm ar gzip

I'm guessing dd, expr, tr, awk, sh, bc, bison, flex, make, ar, and gzip are needed to build the kernel, leaving diff, ftpd, less, vi, wget, unxz, and xzcat as things the target system should have for native building. I don't believe this was the full aboriginal linux dependency list, but that's what the roadmap is for.

I should dig up my latest analysis of toybox road-to-1.0 status and recheck everything.


June 1, 2021

Somebody on twitter asked a really good question: If oil is so profitable why does it need state support? (The answer is probably "the resource curse".)

Here's an entertaining story about how broken corporations are. People are standing up to the Boomers. IP law is slowly collapsing. Billionaires gonna bill. The GOP remains terrible (but GOP Evangelicals remain the worst). Women's tennis is having an attack of misogyny. The police still need defunding.

The ex-british colonies seem esecially racist, which implies britain is where we got the racism from? But then again it was the dutch trading empire in south africa who invented apartheid on the land they'd taken to control the Cape of Good Hope. (They also had an East India Company.) Capitalism creates plutocracy which finds racism extremely useful to divide and conquer the populace. I suppose the UK was just an early and enthusiastic adopter of capitalism, and hence racist as all get out.

The bitcoin-demanding cyberattacks have now hit the meat pipeline. The JBS plant in Texas is up in the panhandle between oklahoma and new mexico, probably not affecting fresh meat in Austin much? We just don't work that way. (HEB has an onsite butcher that takes delivery of half-cows from ranchers. That's why the one on Far West could convert to a kosher butcher.) Might drive up the price of steak-umms though. I should stock up.


May 31, 2021

Fade is back in Austin for the first time since the pandemic started, so I expect to spend far less time on the computer this week.

I got a response to my must recent perl removal submission (for s390x kernel build) and replied quite tersely because of the concept of "selling past the close". (If they offer to do a thing you're happy with, say yes and stop talking.)

There's a lot I WANTED to say about his earlier points, how I'm working to counter trusting trust by creating a minimal build environment and it needs to be able to rebuild itself under itself as a verification step so adding perl to that means perl would need to be binary audited. I don't care if peripheral drivers need perl to build, I just want to build a basic minimal system that can run the build tools without extraneous dependencies.

I've been maintaining perl removal patches for basic builds since Peter Anvin added the dependency in 2008, before the documentation changed to mention perl, and when I got most of the perl removal patches merged back in 2013 I didn't try to remove it from things like the RAID driver because that doesn't block my use case. Possibly if that was a mistake if it's going to metastasize and be entrenched as policy. (We're not THAT far from a day where to build a kernel you need perl, lexx, yacc, the BPF compiler, rust, openssl, and the latest version of python 3 not the previous version of python 3...)

But he needed agreement, not nuance. Yes please, merge my patch with a different description, doing so still removes the depencency.

Meanwhile, there's a good reason a reason I'm trying to steer Android rather than turn vanilla Linux into a desktop OS.


May 30, 2021

I have three functions that try to hand off to subshell in a nommu-friendly way without significantly penalizing the fork() case.

The core is int run_subshell(string, len), which is fairly straightforward when run with a string: for the fork() case it runs do_source() in a new function context, and calls _exit() when that returns. For the nommu case it runs a child instance of the shell using xpopen(0) and marshalls state to it through a pipe to a known high filehandle, ending with the command to run in the new context.

Second, run_subshell() grew the ability to have its string be a NULL pointer. The nommu case is not too different, it would still xpopen(0) a new child shell and pipe data to it, but it would create its own string using pl2str(TT.ff->pl, 0) to convert the child's block of parsed context _back_ into a string for the child to run. But in the fork() case the function returns twice: the parent returns the child PID and the child spawns a new function context and returns 0 PID so the parent can continue until end of the block the child should run. The problem in both cases is figuring out where the child's block starts and ends: for ( ) it should advance past the ( and stop before the ) but the parent already did trailing redirects so those don't get marshalled to the child. But for & case you run a single command, except when you background a block...

Third, I'm making a run_subfunc() to handle running functions in subshells, which also includes the four NOFORK functions that aren't NOPs. When called in a pipeline they need context marshalled into a child shell to be able to work as a background process. This is basically another wrapper around run_subshell() except its job is to convert the already parsed command line (minus redirects and such) into a string (series of $'' quoted literal strings) for run_subshell() to run. And again, it only needs to do that in the NOMMU case and the with-mmu case can just fork and keep (some subset of) the existing context.

I need to add SO many tests...


May 29, 2021

I'm very lucky to have opted out of windows years ago. Apparently Windows 10 is terrifying.

Huh, European cars are way more efficient than american cars.

Google is so bad at privacy even google engineers are complaining about it. (I keep meaning to install a different image so I can try out locally built binaries and do system development on the thing, but I use my phone as a phone.)

Boomercrats suck. The GOP is throwing everything they can at the supreme court they hacked (abortion bans, the texas gun thing) because they know Biden will never pull an FDR and expand it to undo the Merrick Garland thing plus the "Boomers never let go" expiration of RBG and justice Kennedy during the Trump administration. Heck, Biden hasn't purged the DOJ yet or gotten that clown out of the post office (let alone prosecuted him). Boomercrats even kept the filibuster. The Boomercrats are Boomers. They are the problem. Bad Cop is entirely predictable, but Good Cop retains the capacity to disappoint.

Boomer media organizations are apparently not allowed to call white people terrorists. (Was the Unibomber a terrorist? Was Timothy McVeigh a terrorist? Gun massacre du jour it's always a white guy pulling the trigger, with the very occasional white woman.)

Of course it was at christian schools that hundreds of students were murdered and buried in shallow graves. Christianity has been about racist murder since emperor Constantine made it the state religion of Rome. (Christian schools murdering their students are also powered by sexism.) When not actively suppressing indigeous cultures, white people lie and claim to be experts about them.

Defund the police. They cannot be reformed.

The GOP is using Jurisdictional disputes to divide and conquer investigations (when not just stonewalling them) so they can loot and pillage on behalf of the billionares. For example, remember how 150 died during the Texas blizzard and prices spiked over a thousand percent? The republicans running the Texas legislature see this as an excuse for a permanent rate increase and doubling down on fossil fuels.

Meanwhile billionaires (in this case Peter Thiel) are forming their own extrajudicial vigilante squads (as-a-service).

Capitalism has always been dehumanizing. They do it to brown people _first_. They never ONLY do it to brown people.

North Carolina keeps finding ways to be even more racist.

Cory Doctorow makes a case that billionaires have already defeated democracy. As in we haven't got one anymore. I still have hope that enough Boomers dying will drain their power base, but as with solar displacing fossil fuels before global warming kills us all, it's gonna be close. But this is also why I advocate for guillotines, not taxes. It's not about re-establishing parity or funding necessary programs, it's about purging a cancer from the body politic. You don't rehabilitate a tumor, you cut it out. And your negotiating position can't be the MINIMUM you will accept, the Overton window must extend past your "safe school" fallback.


May 28, 2021

It's still monsoon season in Austin. Today it rained hard enough to turn 45th street into a river (cars still driving down it but threw up spray walls like they're going through a big puddle the whole time), and it shorted out the train crossing signal at the corner so the barrier was down and ringing for an hour and change.

I tried to go out to the table during a break in the tunderstorm around 10pm, and made it about a block before running into tree that broke in half in the storm where there weren't enough streetlights for me to be comfortable about NOT stepping on a downed power line I wouldn't notice soon enough, so I backed up and went down Red River instead until I Noped right back home at the second big lightning flash. I set up at the kitchen table and got nothing whatsoever done because Fuzzy did the usual "you're home I can talk to you" thing that's the bane of telecommuters everywhere. (Not the cats this time!)


May 27, 2021

I'm still under the weather. Freenode continues to implode.

Oh hey, the toybox entry in Wikipedia[citation needed] just replaced the link to the long detailed command analysis of what's still left to be done before 1.0 (which came to the conclusion the project's about 80% of the way to 1.0) with a hundred word release announcement mentioning an upcoming anniversary and that one of the commands in pending is enabled in defconfig. Bravo, Wikipedia! Golf claps all around. (Never read Wikipedia about any topic you already know anything about. It'll make you queasy at how easily we swallow everything ELSE they say.)

I went out to Wendy's and sat in my old booth from The Before Times, where I used to do a bunch of programming in between lunch rushes. I'm vaccinated AND kept my mask on, but wasn't comfortable enough to actually pull out my laptop (just ate and went home again). I'm hoping I can get used to it again? Walking to the table at UT is nice exercise, but consumes 2 hours of travel time, is easily blocked by weather or minor health issues, and imposes an inconvenient schedule. It's good to have other options.

Finally sat down an worked out how to get diff --color=always -u toys/*/sh.c sh.c | less -R to show me colors in less, but when using the gnu tools in debian it doesn't work right? The FIRST line of each range is colored, but if there are multiple + lines or multiple - lines in a row, only the first is colored and the rest are white. (These are colored properly in "git diff" but that 90% likely wrote its own implementation of all this stuff.) Anyway, there IS a way to do it, even if the gnu/dammit crap is buggy as usual. I just need to replicate the interface but not the bugs.

I'd really like to get toybox to do that automatically, but even when toybox "ls" and toybox "less" are talking through a pipe launched by "toysh", it's a bit awkward? I can have less default to -R (dunno why it would ever NOT do that?) but "ls -l" knowing that its output doesn't go to a tty and yet is color safe is less obvious. It definitely should NOT do it for "diff -u > file.patch". The design question is when SHOULD it do it? I can make "less" a MAYFORK, but "you were started by toybox and piped into another toybox command" is a bit inside baseball to special case? Hmmm. I suppose toysh COULD export an environment variable into child processes to that effect. Except "diff -u | gzip" is a toybox child that probably should NOT get the escape sequences. But then gzip isn't a MAYFORK, it's an always fork? Hmmm, are they any MAYFORK commands that SHOULDN'T get the color escape sequences output to them? Let's see...

$ grep MAYFORK toys/*/*.c | grep -v NOFORK | sed -n 's/.*TOY(\([^,]*\).*/\1/p' | xargs
help echo false kill printf pwd test [ time true

None of the current ones even look at stdin. :)

Of course IMPLEMENTING less as a mayfork is tricksy, it has to clean up its memory allocations and filehandles even in the error paths, and listen for interrupts and gracefully exit back to the shell with whatever "trap" integration needs to happen there (dunno, haven't implemented "trap" yet, the generic trap handler sets toys.signal to the signal number so later code can respond to it, and that's part of the preserved context that DOESN'T get cleared for NOFORK commands so signals caught that way should be presented back to the shell infrastructure normally). But that seems doable...


May 26, 2021

I've had some sort of stomach bug gradually getting worse for a few days now. It causes that kind of persistent nausea that reads as anxiety even though I know(?) it isn't. (Alas, masking doesn't stop other kinds of viruses. My hypochondriac streak immediately jumps to "Intestial cancer!" or, somehow, "Heart attack!" but both seem unlikely. Possibly I ate something that disagreed with me? It's vaguely like food poisoning, but a lot more persistent than usual.)

Got a couple bug toybox reports on the list, find -quit was easy enough to add, but making date handle +0000 timezone stuff turns out to be tricksy. I cc'd Elliott on the email to see if he has an opinion (he worked on the date command more recently than I have), but I'm cranky and irritable at the moment. Not at my best.

Toysh job control actually has 4 categories of jobs (not just 3): the current non-backgrounded pipeline you're running is something the shell has to wait for. But it hasn't got a job number (until backgrounded). That's why I currently have two functions: wait_job() waiting for those first 3 categories, and wait_pipeline() waiting for the current foreground pipeline. I'd like to merge them, but have to work out the data representation I want. (Do I temporarily add the pipeline to the job table? Do I use that TT.pp entry that's currently just used to hand off a process context to 'exec' so it can drop the unredirect info on "exec 2> boing" redirects that should persist?

Right now a job is a linked list of sh_process entries, one for each PID in the pipeline, with no encapsulating data structure representing the job itself. This means pointing to the _first_ job in the list is important, but exec needs TT.pp to point to the CURRENT context (so it can yank the correct unredirect info)... well, no. Because "true | exec > /dev/null | false" is running exec in a child process where it's once again being a NOP. So the only time exec > /dev/null clearing urd matters is when it's the only process in the pipeline. (Not even the FIRST process, because "exec > /dev/null | cat" is still running exec in a child process that can't persist redirects past its exit. It only matters when it's the ONLY process, because that's when it runs in _this_ shell.)

Anyway, yeah I can probably use TT.pp to point to this job's pipeline, and have the wait plumbing check all 4 cases to match the PID it waited for. It's really TT.fg at that point.


May 25, 2021

Half of US states have fully vaccinated 50% of their adult population. That's a lot of qualifiers (half have gone at least halfway if you ignore children), but it's still progress. We need to get to around 70% of the total population vaccinated to prevent the health care system from overloading again from the next variant du jour that can reinfect people who've already had it. (Jeff got the UK variant after having had the original variant, and now the new india variant is reinfecting people again. That's why non-iditos vaccinate even after having had it, especially since "long covid" seems likely to act like shingles or polio where you recover from the initial infection and are fine for years and then problems crop up in later life. Fauci's already said to expect annual booster shots, which I do not look forward to. Texas is a little behind the national curve, but we're getting there.)


May 24, 2021

I'm switching toysh to storing PID and exit value together in an "unsigned" by doing (pid<<8)+exit. A process exit code is an 8 bit value and PID_MAX_LIMIT is 4<<20 (4 million) even on 64 bit systems (since 2002), so 24 bits of PID should be enough for the forseeable future. (Even supercomputers are only going to stick so many threads into a single shared address space.)

Job control seems to have three categories of process you can "wait" for: 1) numbered jobs (including %+ and %-), 2) the PID of the last process in the pipeline of backgrounded jobs, and 3) the $! PID. (Which is PID of the last backgrounded job, but is also updated by <() and >(), but not $() because that's not asynchronous, its exit is already waited for and the exit value discarded.)

Bash keeps a memorial to dead processes of type 2, as in you can wait for the PID of an exited background job (to query its exit code) long after the job is gone. Except you can wait on the SAME pid multiple times without consuming it, only calling "wait" with no arguments seems to clear that table. The Defective Annoying SHell only lets you wait for active pids, and returns 127 immediately for any PID that's already exited (meaning there's a race condition waiting for anything if you care what its exit code was). Which is a pretty strong argument that I should do it bash's way: dash, like most FSF code, is mainly useful as a counterexample. (I consider it a dishonorary gnu program in that regard.)

My existing wait_pipeline() function is designed to wait for a foreground pipeline, but jobs are backgrounded: I don't think bash assigns a job number and adds things to the job list UNTIL they're backgrounded? So I sort of want wait_job() and wait_pipeline() to share code, but the data structures are wrong-ish?

The naming of my current data structures is slightly confusing, but data goes through a multi-stage life cycle: "struct sh_pipeline" is parsed command data ready to be run, and WHEN you run it you create a "struct sh_process". The former hasn't got the environment variables expanded and has the "name=value" leading assignments and "<file" arguments for redirects still there. The latter has all that sorted, the variables are expanded and the assignments worked out and the redirects are done and sh_process's "struct sh_arg arg" member is what got passed to exec() -- either real execv() in a child process or toy_exec() for builtins -- and it has an unredirect array to clean up redirects.

There's actually a TT.pp global instance of struct sh_process pointing to the current one being processed, so the "exec" builtin command can reach out and clear the unredirect array when you perform persistent redirects. (They persist because they don't get cleaned up when the command exits.) I suppose I could use pp for the foreground pipeline and teach wait_job() about that? Hmmm...

The UI is inconsistent between & and the bg command:

$ sleep 5
^Z
[1]+  Stopped                 sleep 5
$ bg
[1]+ sleep 5 &

vs:

$ sleep 5 &
[1] 3622

That's three different kinds of output, each preceded with the same job number. (And the & backgrounding output doesn't identify the job as the most recent job.) Hmmm...

Right: I need to track when a pipeline has exited. I can't use pp->exit because exit 0 is a valid status (and it's becoming a 0-255 range). I want to use the "pid" part being 0 to indicate process go bye-bye (after copying the (pid<<8)+exit value into the memorial array), but builtins also have pid 0 when they run in the shell's process context. In theory only the NOFORK builtins should do that, the MAYFORK ones fork their own PID when run in a pipeline. But if you run a NOFORK like "exec" toysh won't run a child process, and bash will although you've gotta be sneaky to catch it:

$ echo $BASHPID >&2 | exec boink > blah-$BASHPID
6984
bash: exec: boink: not found
$ ls blah-*
blah-6985

Another corner case is "abc=def | echo hello" where the abc=def doesn't actually RUN anything, but has a PID! Because every pipeline segment has a PID in bash.

$ echo $BASHPID >&2 | abc=def > $BASHPID | echo $BASHPID
4094
4092
landley@driftwood:~$ ls 4093
4093

I'm supporting nommu so don't want to gratuitously fork() when I don't have to because relaunching the shell and marshalling data into it to get the child process back to where the parent process was so the parent can unblock is EXPENSIVE. That said, "echo hello | read i ; echo $i" doesn't print anything because it didn't set $i in the parent process but in an immediately-exiting child process.

Sigh. I'm forking at the wrong level compared to bash, and I know it:

$ echo one >&2 | echo $(sleep .25)two >&2 | echo three
three
one
two

That $(subshell) should happen in the second child process context of the three pipeline child processes, and NOT block the launch of the third process. The problem is, NOMMU makes that expensive so I dowanna. I want the parent process to do as much as possible, and fork children as late as possible. My design performs all the variable resolution and redirects in the parent process (and duplicates the displaced filehandles to high FD numbers keeping an "undo list" to move them back afterwards) before running each command (via vfork/exec as necessary). So I've accepted that as a behavior deviation, but it has ramifications that I'd like to minimize.

Of course if I treat the NOFORK and MAYFORK commands the same for pipeline purposes (scrute the inscrutable, vince the invincible, fork the noforks), would that imply you can call NOFORK commands through the multiplexer? Well, I can still filter them out there if I want to. The currently implemented NOFORK commands are cd, eval, exec, exit, export, jobs, set, shift, source, unset, and wait. (The punctuation ones are both aliases: "." is an alias for source and ":" is an alias for true.) I can trivially make exit and true MAYFORK commands (true already is, it's ":" that's NOFORK so the toybox install doesn't make a symlink for it), and exec sort of drops out as a MAYFORK? (It just... runs... the thing?) Lots of noforks are NOP in a pipeline: cd, export, shift, set, and unset do nothing but possibly with error messages ("cd /doesnotexit" would complain, but whether or not it succeeded the PID the chdir() applied to would then exit) and the big question is making sure they're happy running in an uninitialized shell context (since the nommu toybox entry path would call command_main() without going through sh_main() first) so might need an extra if() statement or two. The other four need shell context marshalled to them in order to function: eval and source are running code in a context that has functions and local variables and such defined, and wait/jobs needs to know what the active jobs are.

Ok, so NOFORK marks commands that don't show up in the command list when you run "toybox", but if I add a few extra tests then almost all of them can MAYFORK (even if a lot become essentially NOPs when that happens). But four (so far) can't, and shell functions also can't. Those need to do the $() subshell dance, which implies I should annotate those four as part of a THIRD category. MAYFORK, NOFORK, and... SUBFORK?

Hmmm, have I added the correct sequencing tests to sh.tests yet?

$ x() { echo potato; }; X=x; $X
potato
$ X=y $NOTHING; echo $X
y

Ok, for farming builtins (functions, eval, jobs, source, and wait) out to child processes, I need to marshall full context BUT I've already parsed the command line and don't want to parse it again. (Not just to save effort: an argument that evaluates to <blah or $BLAH would get mangled if it was re-parsed. Can't re-split for $IFS either.) The EASY thing to do is encapsulate each argument in $'blah' which is probably what I should do even if I need to eventually reproduce the crazy user visible escaping for declare -p.

Right, annotated eval, jobs, source, ".", and wait with NOFORK|MAYFORK (instead of adding another SUBFORK bit just chord those together). The rest nommu re-exec toysh with the command line. (Gotta make sure it always re-execs THIS process rather than trying to find "eval" in the $PATH.)

Always forking background processes in pipelines means I always have a nonzero PID which I can set to 0 to indicate that process exited. (And add an entry in the memorial for looking up its exit code later.)

It would be nice if I could figure out how to do this in stages. I should try to chip off a few of the smaller pieces of this diff and check them in if anything looks easily severable...


May 23, 2021

Russian fighter jets forced down a civilian airliner flying from Greece to Lituania so they could arrest a putin critic. And of course Boomer Media is downplaying it.

The observation "Boomers never let go" provides useful insight. Nothing can come from negotiating with them, or convincing them, they never voluntarily relinquish ANYTHING, to anyone, ever. Boomers have held the presidency for 39 years now. Biden is watering down his proposals to beg for republican approval he'll never get, but his job is to do the absolute minimum necessary to delay any sort of reconing. The Boomers are way past their sell-by date, with fallout ranging from squeamish Puritanical Prudishness to the ongoing racist hypocritical GOP insanity. Boomers are what currently preventsdefunding the police, and AT THE SAME TIME the rich white mindset leads to stupid vigilante crap by wannabe Batmen. (You can't "but what if" when it's already happening.) But the Boomers HAVE to die soon. They will take as much with them as they can, crapping on everything on their way out, as is their way. But they will die. It's the reassuring thought that lets me sleep at night: this too shall pass.

Venmo sucks, Venmo is Paypal, and the alumni of Paypal funded Tesla, Linkedin, Palantir, and Yelp (all evil in their own ways, Facebook is another such metatstic disaster, and the bitcoin money laundering protocol is the main reason ransomware is back which similarly boosts identity theft when not just just directly scamming "investors"). Billionaires have have always been terrible, but the Silicon Valley Douchebro is its own peculiar strain of sexist/racist evil. The USA's broken medical system is also full of full of guillotinable billionaires, and has gotten too capitalist and sexist to be compatible with civilization.

So they lie. The lies don't even have to be consistent: fossil fuel companies can simultaneously claim plastic is recyclable and point to plastic straws as a hairshirt people can performatively give up to hurt disabled people. When gas companies point to farting cows as a source of non-fossil atmospheric carbon with a half life of 7 years, PETA happily jumps on the bandwagon because they like the hairshirt. New york has a bill that would forbid unions from striking: define "union" please?

Apparently american jews aren't driving the USA's policy towards Israel, christian evangelicals are. (Because they want to bring about "the rapture" where they're bodily taken to Narnia to meet Thor and Black Widow and ride the teacups. They can't wait to die of old age and go to heaven that way because they don't actually believe it will happen. That's just what they chant in church while tithing, much more reliable to try to start a nuclear war, that'll CLEARLY turn heaven into a real place. Gotta die in battle and be collected by a topless valkyrie, or something.)


May 22, 2021

Looks like libera.chat is mostly winning out over Debian's OFfTopiC, so I moved #toybox and #jcore to there. I then emailed the mailing list of both projects to point at the new channels, because Freenode's new owner is treating attempts to point to new channels from the old ones as "spam", so I dunno if a regex is going to find the topic changes and blank them in the next few days. (He's updated the terms of service to say he'll reclaim "abandoned channels", which there are an awful lot of now. What did he THINK a sudden hostile takeover of a volunteer organization was going to do? The Linux Foundation spent TEN YEARS subverting the linux development community before the frog boiled enough Microsoft could buy github and officially join the Linux Foundation board of directors.)

Reading a twitter user listing channels that have moved over to libera, #devuan has a support channel. Ooh there's an Austin Hackers group... which requires a keyword to join their channel. Nope, not interested in exclusionary "prove your worth" bs. Huh, lots of old freenode volunteers have come out of retirement to help the migration. (amdj has been quite helpful getting me set up, it's been ages since I've had to change the flags to get auto-opped and so on.)

Got pinged about the ELC CFP which is in Seattle in September this time. Hmmm, I suppose I could talk about writing a new Bash compatible shell since I've spent two years working on that now. Or talk about mkroot and system bootstrapping. Or countering trusting trust. (I mean they're all related.) And of course I could talk about 0BSD...

But really, I should just do youtube videos. I mostly speak at conferences to give me a deadline to prepare a talk somebody will record and post, and I could cut out the middle man here rather than paying my own way to these things.


May 21, 2021

Finland did a pilot of universal basic income and (once again) found that it doesn't reduce incentives to work (instead employment actually increased).

I look forward to buying Sarah Taber's book, but suspect it won't cover anywhere near all her fascinating threads.

Israel allowed a ceasefire because palestinians went on a general strike and shut down israel's economy (which needs the cheap labor to function). Hands up everyone surprised Netanyahu's government immediately broke that ceasefire (because if the crisis ends he has to give up power due to failure to form a government; he's transparently bombing civilians to stay in power).


May 20, 2021

Some rich guy bought Freenode, which now appears to be imploding. People are trying to figure out if they go to oftc (the irc network Debian's used for many years) or the new libera.chat the ex-freenode volunteers are setting up in some sort of "etherial-vs-wireshark" thing. (This takeover seems to be about as healthy for the old project as xfree86 relicensing itself was.)

I wrote a summary of current toybox plans to patreon, but of course when I sat down at the table today I went back to grinding on job control because I have a half-finished commit it would be nice to finish and check in.

And job control is full of corner cases. If I "sleep 10 & jobs %sle" bash shows the "sleep" job because it matches the start of the name, but if I "make sleep && ln -s sleep 42; ./42 10 & jobs %4" bash does NOT show 42 because a numeric job reference is unconditionally taken as a job number and not a prefix to match against jobs. So even when there IS a job that matches by prefix, and no job of that number, it doesn't fall through. And speaking of falling through:

$ sleep 30 &
[1] 20093
$ sleep 30 &
[2] 20094
$ jobs %sle
bash: jobs: sle: ambiguous job spec
bash: jobs: %sle: no such job

My current code just returns the first hit. I think I'm ok with that if the alternative is printing _TWO_ error messages. (I more or less expected it to show both jobs and have to do more work, but they somehow managed to do more work to accomplish less? Sigh. Implementing this is easy, figuring out WHAT to implement is hard.)

$ sleep 3 & sleep 3 &
[1] 24186
[2] 24187
$ jobs %2; jobs %2; jobs %2; echo hello
[2]+  Done                    sleep 3
[2]+  Done                    sleep 3
[2]+  Done                    sleep 3
hello
[1]-  Done                    sleep 3
$ jobs %1
bash: jobs: %1: no such job

Displaying a job by % marks it as reported so the prompt doesn't show it again, but doesn't remove it from the table? What removes it from...

$ cat test.sh
#!/bin/bash

sleep 3 &
sleep 5 &
jobs %1
sleep 4
jobs %1 %2; jobs %1
jobs %1 %2
$ ./test.sh
[1]-  Running                 sleep 3 &
[1]-  Done                    sleep 3
[2]+  Running                 sleep 5 &
[1]-  Done                    sleep 3
./test.sh: line 8: jobs: %1: no such job
[2]+  Running                 sleep 5 &

Once again, ; and newline behave differently. Advancing to a new line clears "done" jobs from the job table. I don't think my parse plumbing is maintaining that distinction? (Because it's ALMOST never relevant otherwise? Sigh.) How about line continuations?

$ if true; then sleep 1 &
> sleep 2
> jobs %1; fi
[1] 24960
[1]+  Done                    sleep 1
bash: jobs: %1: no such job
$ cat test2.sh 
#!/bin/bash

if true; then sleep 1 &
sleep 2
jobs %1; fi
$ ./test2.sh 
[1]+  Done                    sleep 1

This behavior is NOT CONSISTENT. (It's reproducible, but shell script and command prompt are behaving differently.)


May 19, 2021

Huh, apparently Google caved to the NSA and is going to distribute backdoored apps now? This sounds like a bad thing.

The CDC has gone to to plaid. Seriously, getting the science right and getting the POLITICS right are two different things, and the second they are very much not doing. (I mean, still better than Canada's government, or the previous administration, but neither seem like a very high bar at the moment. In the Boomerdamarung "mediocre" is high praise.) And even the Economist is estimating the global covid death toll is between twice and four times the official figures. (And in some places measurably 14 times the official figures.)

Bitcoin is propped up by something called "tether" which is a giant scam.

Billionaire Elon Musk's "starlink" ISP has terms of service forbidding "obscene" or "sexually explicit" use of the internet, such as mentioning the existence of gay people. (Not that other ISPs have clean hands.) A common failure mode of naieve white men is thinking that someone who is nice to them is a nice person. Dave Barry saw through that one 20 years ago, in the book "Dave Barry Turns 50". This is how naieve young silicon valley douchebros get led down the path of racism and misogyny, because it doesn't pesonally affect THEM so all these squeaky wheels complaining about being subject to it must be imagining things, blowing it out of proporation, oversensitive, weak, lying... Cognitive dissonance takes it from there: the only way to defend your established position, originally arrived at by inertia and militantly defended ignorance, is to declare everyone saying you're wrong to be evil. (A good scientist admits they're wrong six times before breakfast, but it's not science if you can't reproduce it from first principles under laboratory conditions and 99% of silicon valley is doing computer alchemy at best.)

But the OLD white man are the big unsalvageable problem. It doesn't matter how they got there, Boomers in government are just as intrusively condesecendingly puritanical because obviously now that dried up old Boomers are done with sex everybody else should be too. The septuagenarian (and octogenarian) Boomercrats aren't dying fast enough. Sure the GOP is both insane and irredeemably evil without a single mitigating factor remaining, condensing into a personality cult held in place by fraud and lies and late stage capitalism, with the main remaining attribute of the GOP being their ongoing collapse into a black hole of racism. But the real problem is Boomers in general. Boomers have been a net negative for decades, have stuck their fingers in their ears and gone la-la-la about the entire concept of learning from history, and won't relinquish power until they die. (The racism is actually a big driver for this "STEM STEM Uber Alles" nonsense at universities: if they eliminate teaching history they can replace it with white supremacist messaging.)

Here's another excellent thread by Cory Doctorow explaining why the Boomercrats are incapable of fixing the IRS to actually tax billionaires, and thus the proper goal is to guillotine the billionaires, not just tax them. The federal government needs to declare hoarding a billion dollars a capital offense punishable by guillotine, and THIS is what we should lobby for as post-Boomer reality. (Turnabout is fair play, and given the ever-increasing concentration of power the question is _how_ it collapses.) Guillotining the billionaires isn't primarily about the well-known billionaires, the real damage is from the other 600 that stay out of the news, those are the people driving up rent and privatizing the water supply.


May 18, 2021

Time for a toybox release. (If full job control is out of scope for the next release, might as well cut it now.)

I did release notes for the news page and COULD just ship what I've got, but the mkroot images are still failing. Alright, where were we... Last time, the set of architectures included aarrcchh6644 armv5l armv7l i486 i686 m68k mips mipsel powerpc s390x sh2eb sh4 x86_64.

Sadly musl-cross-make hasn't had a new commit to the repo since October, despite musl itself having a release in January (fixing a security bug), so mcm is still building a stale version of musl by default. Oh well. My toolchains built from mcm-buildall.sh running in the repo from October 20th contain the following architectures:

aarch64 armv4l armv5l armv7l armv7m armv7r i486 i686 m68k microblaze mips64 mipsel mips powerpc64le powerpc64 powerpc s390x sh2eb sh4 x32-cross x86_64

Of those, mkroot didn't even try armv7r (a nommu armv7l) or x32-cross (the x32 abi), because those toolchains are borked. (The armv7r one hasn't got a "cc", looks like binutils built but gcc didn't), and x32 has inconsistent prefixes: there's no x32-*cross/bin/x32-*-cc because A) x32-cc wouldn't match x32-*-cc and B) the binaries in bin have the prefix "x86_64-linux-muslx32-". I thought I had that working at one point, but it seems to have bit-rotted.

Neither mips64 nor armv4l have kernel config descriptions in mkroot, and those images didn't ship last time. Possibly I should make another stab at 'em, but neither one is a regression.

The kernel developers are blaming the m68k hang on qemu version skew, which isn't something I can test right now because of python 3 version skew in the qemu-git build. Pass for now, upgrade my devuan image after I get a release out.

I've poked at the arm64 vs armv7l virtio qemu boards differing for no obvious reason, but it turns out it was broken last release so that's also not actually a regression? (Should fix. Tired.)

The kernel's s390x build is failing because this commit reintroduced perl into the kernel build. Sigh. Emailed a fix to the list, which is enough of a fig leaf I'm willing to ship the result. (It's build code, doesn't even wind up in the binary...)


May 17, 2021

Ooh, another excellent article on how efficiency and resiliency trade off, this one casting it as an efficiency vs effectiveness tradeoff, and pointing out that idle cycles are a vital part of low-latency responsiveness. ("As a practical matter, it is impossible to keep everyone in the organization 100 percent busy unless we allow for some buffering at each employee’s desk. That means there is an inbox where work stacks up.") Having 3 people do the work of 10 is more "efficient", even if those 3 do the job badly, with long unpredictable delays and things falling through the cracks.

I'm poking at updating the j-core roadmap and the first link it makes is to Hitachi's "introducing the superh family" PDF which we linked to a mirror of on a random russian .doc site that's gone down. I checked archive.org and their first record of the URL is a cached 404 error from 2019.

I have a copy of the file (I compulsively mirror stuff), and could put it in the roadmap directory on j-core.org, but the reason we didn't previously do that was licensing. I suppose I could put it on landley.net (presumably in my history mirror directory) and link to that from j-core.org? Or submit it to archive.org as a library document? Either is a grey area...

The thing is, it's PROBABLY on hitachi.org somewhere, since the document said hitachi, but their archive isn't very well indexed and Googling for Hitachi document number "19-040a" isn't helping. I found a similar announcement about the dsp (years later, less generic), and another one about shipping 133mhz processors back in the day... But they're not THIS document.

Whatever happened to Sony's sh4 by the way? Ooh, here's the sh4 intro press release. And one about porting wince to it. (Microsoft itself called it Windows CE, how did they THINK that was going to be abbreviated? Things like "hey Microsoft, I'm bending over, windows me" can't be ENTIRELY accidental...)

Sigh, I could link to an old encyclopedia article, but don't want to? Hmmm, here's an old Hitachi glossy flyer on another fly-by-night site that could be 404 again in a couple years. Ooh, fun history article. And j-core.org should probably link to this series (which I had a todo item about already)...

But none of them are the article in question...


May 16, 2021

Some students and/or security researchers at the University of Minnesota submitted three backdoored patches to linux-kernel as part of a research project (about which they wrote a paper they'd planned to present at a conference this month). The kernel devs flipped out when they noticed, and Greg KH (my nemesis) decided to blackball the entire university Damnatio Memoriae style and revert every patch from a U of M address since the Obama administration. (A calm and well-reasoned response to the situation, obviously.)

Greg came up with a list of 190 patches that still "patch -r" reverted without failing hunks, and wanted to mass yank the lot of them without particularly caring what they did (which would obviously cause rather a lot of regressions and reintroduce WAY more vulnerabilities than the researchers had done, but the important thing isn't code quality it's avenging the insult).

Other people less defensive about their egoes objected, and actually reviewed the list of patches, and narrowed it down to 42 they were willing to revert because they're not actually very good. And this is the part I boggle at: 1/5 of a completely arbitrary list of linux-kernel patches turns out, on closer review, to be crap. This means if you review ANY list of patches that's gone into the linux kernel, it's quite likely that 1/5 of them probably shouldn't have gone in.

You know how I keep insisting I don't want to get the linux-kernel community on me anymore because it's a toxic pile of insular bros? Turns out this may be impacting the quality of the Linux development model faster than I thought. I know the average age of kernel developers is Linus' age, and he's no spring chicken anymore, and I guess this is just early symptoms of the expected rot, but it's still sad to see it happen.


May 15, 2021

Good thread explaining why buying a new iPhone does not mitigate a compromise. (You have to turn off Apple's iCloud data harvesting service or the new phone is immediately compromised too.)

Insatiable late stage capitalists have become "so desperate" they're... allowing basic supply and demand to apply to labor wages again? After their actions killed a significant chunk of their employee pool.

71 year old Benjamin Netanyahu's government was falling apart and he was about to lose power to his political opponents, so he started a war against civilians as an obvious distraction (which did indeed keep him in power, at the cost of over a hundred civilian lives so far), and 78 year old Joe Biden is cheering him on for some reason?

A mid-level CDC functionary suddenly decided to end masking via clusterfsck with no warning, in a way that's among other things an endorsement of the insane florida governor. So of course Biden immediately endorsed the decision. I boggle: yes the numbers have recently been heading in the right direction, and being fully vaccinated reliably prevents you from getting covid in a meaningful way, but not a single state has hit 50% fully vaccinated yet and we're only aiming to hit 70% vaccination by the end of June, so we won't have "herd immunity" for at least a month and a half. The new policy forces business owners to figure out who is and isn't vaccinated, and even if you are willing to card the vaccination cards being handed out are trivially forged, not even laminated, and the wrong shape to fit in most wallets. (Speaking of which, do we count the 22,000 flu deaths that didn't happen this year because of masking, social distincing, and hand washing AGAINST the Covid total?)

The reason that big oil pipeline shut down was the billing system failed. They could still pump gas just fine, they just couldn't accurately invoice people, and capitalism will happily create widespread shortages (up to and including mass casualties) before allowing even the POSSIBILITY that someone somewhere might not pay full price.

Google just hired the surveilance expert who created the NSA's warantless wiretapping infrastructure for AT&T, to replace the researcher they fired for reporting on their intrusive data collection practices.

The GOP is a full blown terrorist organization at this point. Sadly, this is not hyperbole.

The first step towards defunding the police is to demilitarize them. Using local police as a dumping ground for surplus military hardware (because the pentagon buys more military hardware each year than it can store, let alone use) is bad policy. The fundamental mistake in the Vietnam war was using the military to perform a "police action", and militarizing domestic police is the exact same failure mode here at home. It gives you domestic vietkong, to which the military inevitably loses by attrition but causes massive chronic civilian casulaties and gives the entire population PTSD. This was common knowledge in the 1970s, and yet the Boomers managed to recreate this failure mode anyway.

Late stage capitalism conditions "consumers" to respond to any stress by buying things,which results in panic buying of gasoline, panic buying of toilet paper, panic buying of microchips... which creates shortages. Just-in-time delivery is brittle, there are no reserves anywhere, so news of possible shortages easily creates actual shortages. Add in covid, and that cyberattacked gasoline pipeline being out, and now a bridge is out that takes out I-40 and the Mississippi river simultaneously. I expect america's suppy chains to curl up in a ball and rock back and forth whimpering for a bit.

Despite the pipeline hackers apologizing to Putin (presumably for accidentally spending Russian political capital without promising him a cut), their ransom demand was paid and presumably Putin was too.

Uber's core business is tax avoidance. That's the "secret sauce" that makes its business model profitable enough to undercut existing taxi fleets.

Racism remains pervasive.

Right to repair and open source meet HIPPA. Capitalism in medical care, like capitalism in food and shelter, is Darth Vader's "he will join us or die my master" level of evil.

Guillotine the billionaires, reason du jour.

Religion continues to suck.


May 14, 2021

A github thread on 0BSD has resulted in a tweak to their template turning the "Copyright Rob Landley" to "Copyright Your Name Here" (which is how I submitted it to SPDX in the first place).

Toybox release prep continues. I'm cleaning up the new unicode command so I can promote it (and merging it with ascii.c because it's got the same low-ascii string), which raises the question "what is the valid unicode range anyway". I remember it's 4 utf8 bytes (even though utf8 encoding can go to 7), but not the exact cutoff, just that it's weird and stupid? I had to look it up: 0x10ffff. (Because microsoft, which is also why 0xd800-dfff are occluded.) I tweaked demo_utf8towc to only test that range (which records WHAT the range is).

This also means that wchar_t is "int". A utf8 code sequence starting with 0xff could encode 42 bits requiring a 64 bit number, but unicode capped at 21 bits ain't doin that. It's too big to fit in a short and never even touches the high byte of an int. So I should go through my utf8towc and such functions in lib/lib.c and just convert them to use "int". (Ah, the function going the other way is already using unsigned, I should make 'em consistent.)

I've mentioned the bootloader stuff I was poking at in $DAYJOB. It's one of the balls I'm juggling, anyway: the immediate task got handled by another engineer who already knew our bootloader code, but I'd came up to speed on this domain a little before they got around to it and have been picking at it since.

Which means I'm also glancing at u-boot and coreboot and such and trying to see if any of them are a good fit for j-core. Years ago u-boot threatened to move to GPLv3 and I've been leery of it ever since, but coreboot seems minimal... and also incredibly user-unfriendly.

In _theory_ coreboot supports both x86 and arm (because chromebooks) and thus could do other architectures, but the first google hit for "coreboot arm" announces itself as obsolete and then links to a git tree that isn't there anymore (and the redirect loses context because of course it does).

Going to coreboot.org and clicking "videos" is just "would anyone like to make videos" (so why is the tab there on an equal footing with all the other tabs?) and clicking docs and going to "CPU architecture" in the nav bar... doesn't even mention arm?

Sigh. I dunno what code coreboot actually _has_ that might be of interest. J-core's bespoke bootloader already has DMA init code, ELF and FAT handling code, and a gdb stub to load a kernel over serial. It would be nice to have pxeboot: we used a tftp/bootp loader on the old red boards that had ethernet but not sd card, but I couldn't find that code in the archive. I could always poach the toybox implementation to redo it if I needed to, but haven't yet.

It seems like 90% of what coreboot does is maintain "not device tree format" versions of hardware layouts so it can do enough hardware bringup to hand off to grub or similar. It's tempting to add our board to their list (as a form of advertising if nothing else), but possibly the easy thing to do would be make a device tree parser to produce their format and feed our device tree through it and call it good? In which case... why would WE do that? Why hasn't someone else already done it...? (Maybe they have and it's just unintelligible to me...) So far I haven't found any interesting platform-independent drivers, but it seems like a project where you have to read the source because the docs are useless...


May 13, 2021

What is the lifetime of job control remembering old PIDs? Because I can go:

$ for i in 1 2 3 4 5 6 7 8 9; do exit $i & done

And then "wait 12345" on any of those PIDs multiple times and it will remember them (and give me their exit code more than once), and if I run it AGAIN it will still remember the ones from previous rounds. If I call "wait" with no arguments it clears the table, but the prompt displaying exited PIDs does not, and waiting for a PID does not. (I haven't checked if returning from functions or source context does.)

Meanwhile, "wait -n" returns 127 because the prompt display reaps what "wait -n" is looking for. (Ok, fine...)

I thought this meant that bash HADN'T special cased $! and it was just this "retains old PIDs until you call wait with no arguments", but nope:

$ echo <(exit 37)
/dev/fd/63
$ echo $!
31474
$ echo <(exit 42)
/dev/fd/63
$ echo $!
31481
$ wait 31474; echo $?
bash: wait: pid 31474 is not a child of this shell
127

What design idea am I missing here that makes this make sense? It seems like a gratuitous hash table of old PID exit values is endlessly leaking until you call "wait" with no arguments, and on TOP of that $! is special cased? That can't be right...

Anyway, my specific question is "does something OTHER than wait clear the pid result table"?


May 11, 2021

Yes of COURSE all Bill Gates' "philanthropy" have been about exerting control. All billionaire philanthropy is like that.

Fraternities are white gangs. They do exactly the same things as any other gang, they just have money and police smile on their activities instead of repeatedly raiding them.

The oil industry remains irredeemably evil.

People keep trying to work out tax based alternatives to guillotines; what they have in common so far is that none of them work. Historically, the divine right of kings was not taxed away.

Rich people keep stealing poor people's victimhood and draping themselves in it. For example, farm owners are rich people. The median net wealth of farm owners is 9 times higher than average and 97% of farm owners have above average net wealth. But they steal the stories of farm WORKERS by lumping themselves together on the census to say "half of all farm households are losing money": which is true, the farmowning landlords pay their hired help TERRIBLY. This is how they finagle endless farm subsidies and bailouts, that and by being white landed gentry.

IP law needs to die with the Boomers.

Defund the police.


May 10, 2021

I'm tired of the endless C++ developer microaggression regressions eroding C support in the FSF's compiler, but alas nobody's stepped up and added support for all the other hardware targets to llvm yet. (We haven't even gotten superh support merged yet, because we're woefully understaffed and it's a moving target.) And I haven't had time to poke at tinycc/qcc for over a decade.

My sleep schedule's been creeping forward for weeks, and today I woke up at 5am after falling asleep somewhere before midnight, which USED to be a very productive schedule when I lived on west campus and could walk to Einstein's Bagels to get a couple hours programming before it was time to head to $DAYJOB. The problem is, due to the pandemic there's nowhere to go work indoors (modulo the "home under a cat" part), and it gets progressively harder to see my laptop screen outdoors as the sun rises; by 10am it's outright annoying even in deep shade.

On toysh I'm trying to tie up basic job control (not even the signal handling parts yet, just "sleep 10 & jobs", fg/bg, kill, reaping children from the jobs list, displaying backgrounded and finished jobs in interactive mode...) but I struggled for a couple days with "what integer represents a job", the options being "pid", "job number", and "index into job table". The problem with PID is I need a table search each time I use it (and error handling for "this PID was not in the table") to find the corresponding struct sh_process, and job number turns out to be basically the same as PID in that regard. (Especially once I figured out that the %+ and %- entries don't need TT.job_plus and TT.job_minus variables to track them, but can just be the last 2 entries in the table if bg moves the selected entry to the end of the table; it never DIDN'T require a search since jobs can exit out of order, but that means it can't even be a binary search.) But "job number" and "index into job table" are still conceptually similar enough that I confused them a LOT writing the code, and had to go back and clean it up to consistently use index.

Another issue is that toys/posix/kill.c is currently its own file, but I need to inline it into sh.c to add job control support, and that's wrong and hairballish. Maybe I need a toys/shell directory I can move all the MAYFORK commands into, and a new sh.h they can #include, and a lib/sh.c with shared infrastructure? Hmmm... Right now with sh.c in pending it's sort of moot, but when sh.c moves _out_ of pending that's going to need addressing. Of course at the moment I can't merge kill.c into sh.c in pending without de-promoting kill and taking it OUT of defconfig, which I dowanna do.

There we go, I have pressure to promote sh.c out of pending, which means defining a "usable" stopping point. (Before heading back to Japan and downing tools on it all again for who knows how long... Huh. June 25 is the 2 year anniversary of my restart on toysh. That might be a good goal to try to get something promotable, if not necessarily finished. "Better than dash" is not a high bar, and I'm already using it in some mkroot systems...)

Speaking of releases, the first failing mkroot target is armv7l, which hasn't got an ethernet adapter. Which is sad because it's the exact same target as arm64. I mean the miniconfig is the same (qemu virtio board), all that differs is the ARCH=arm vs ARCH=arm64 passed to the kernel make command line. But somehow dependency resolution is turning this into the virtio ethernet device being disabled in one expanded kernel config but not the other.

What I did is booted the two in adjacent terminal windows and lines up the kernel messages, and... why does aarrcchh6644 have five lines of RCU spam that armv7l does not?

-CONFIG_TREE_RCU=y
+CONFIG_TINY_RCU=y
 # CONFIG_RCU_EXPERT is not set
 CONFIG_SRCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_RCU_STALL_COMMON=y
-CONFIG_RCU_NEED_SEGCBLIST=y
+CONFIG_TINY_SRCU=y

Because that. Why is that different? Why do most of these options not even have help text in menuconfig? Why is there now a CONFIG_RCU_EXPERT menu with FAST_NO_HZ and NOCB_CPU sub-itions? (Sigh, the Linix devs added a great big horrible CONFIG_EXPERT menu in init/Kconfig -- which is NOT the same as the horrible CONFIG_EMBEDDED menu they special cased having to switch _off_ in allnoconig -- and then they sprinkled extra expert crap all around the tree. They really SUCK at all things user interface, don't they?)

Sigh, I have no idea if this change is even relevant, it's just the first difference in the boot messages that isn't trivially explained by the architecture being different. There's no obvious reason for a significantly different RCU implementation from a selectable list here? The miniconfig didn't ask for it, the dependencies working from the architecture information _supplied_ it...

Still trying to work out quite how to represent job control, because:

$ echo hello >(false)
hello /dev/fd/63
$ wait $!; echo $?
1
$ echo hello >(true)
hello /dev/fd/63
$ wait $!; echo $?
0

I think I need to retain the exit code of the $! process so wait can special case returning it. That's unpleasant. It's not even a special job table entry because the prompt would reap it and wait couldn't fetch it after the next prompt? No wait...

$ false &
[1] 29401
$ echo hello
hello
[1]+  Exit 1                  false
$ echo hello
hello
$ wait 29401; echo $?
1
$ wait 29401; echo $?
1
$ wait; echo $?
0
$ wait 29401
bash: wait: pid 29401 is not a child of this shell

Ok, wait with no arguments removes it from the table. The prompt reporting does not. Waiting by PID does not. And it's not a $! thing because I can wait for the last 2 PIDs alternately and it remembers them.

Right, I figured out that <(echo) sets $! but $(echo) does not because the first is asynchronous and the second is synchronous. It's the same reason (echo) doesn't set $! which is because it's not a background process.


May 9, 2021

Huh. I knew Gen Z hated the Boomers (with good reason), but I underestimated quite the level of visceral disgust they have for any reminder that Boomer and Gen Z are even related biological species.

Here's an excellent thread explaining exactly why we need to guillotine the billionaires.

Waiving patents increases vaccine production, exporting from rich countries to poor countries does not. (We need to vaccinate 7.7 billion people, arguing about single digit millions of doses is completely irrelevant. But capitalism is a mechanism for regulating scarcity. In the absence of scarcity, capitalism CREATES scarcity by wastefully using up all the "too cheap to meter" clean air and clean water and shooting all the buffalo and passenger pigeons until it can put a price on what's left. The idea of REMOVING scarcity from the equation, ever, even temporarily, rubs capitalists the wrong way. That's why capitalism has BECOME the problem.)

An excellent thread on why intellectual property law needs to follow the billionaires into the guillotines when the Boomers finally keel over. (The Boomers' misogynist capitalist prudishness also needs to end with them.)

Over 80% of the FCC "net neutrality" comments in 2017 were broadband industry astroturf.

Amber Ruffin did a good report on how Obama "compromised" away the infrastructure tracking right-wing terrorism created in response to the oklahoma city bombing, allowing white supremacy to flourish leading to the January 6 capitol attack.

The GOP sadly continues to GOP.

One route to reducing police is the record numbers of retirements caused by making "police" be on par with "tobacco lobbyist", but they still need to be completely defunded.

India is lying about its covid death toll, the reality is far worse. But then that's true globally, and here in the USA the death toll is estimated at over twice the official figures, something even Fauci admits now.

The last time capitalism teetered was the great depression of the 1930s, but it's doing it again now. Last time we patched it up because high levels of unemployment give rise to nazis, and then when we got done fighting them we were opposing the Soviet Union which draped itself in communism the same way "neoliberals" use the world "liberal" (and Germany's "National Socialist Party" was not about providing universal healthcare or rent control: fascists pretend to be the exact opposite of what they are: they accuse their opponents of their own crimes and give lip service to the other side's goals while actively preventing them from happening). The backlash against soviet "communism" led the USA to double down on capitalism (with massive state subsidies and protective regulation) long past its expiration date, circling us right back to the gilded age that led up to the great depression.

A reminder that Vladimir Putin is a mass murderer. It is how and why he's in power.


May 8, 2021

My tea is back in stock at HEB! They haven't had it in MONTHS. (I tracked down the mainfacturer last month and sent email through their website form, and their US distributor replied with an import store halfway to Round Rock that carried it, and I've been meaning to bike up there ever since, but HEB is finally carrying it again!

The kids are all right.

A few days ago I didn't understand this part of the "wait" command's explanation in the bash man page:

If no arguments are given, wait waits for all running background jobs and the last-executed process substitution, if its process id is the same as $!, and the return status is zero.

So I emailed Chet Ramey (who remains very nice), and he clarified that: 1) the return status of "wait" with no arguments is always zero when it runs to completion, but a signal interrupting the foreground process has its own return code regardless of what command was interrupted. 2) "wait $!" has to "always work", even though $! can be set by <(process substitution) which isn't a job.

For a certain definition of "has to always work", anyway. In a new tab where $! starts unset. (Or at least I think it's unset, declare -p can't see "!" at the best of times):

$ echo $!

$ wait $!
$ wait "$!"
bash: wait: `': not a pid or valid job spec
$ wait 0
bash: wait: pid 0 is not a child of this shell

But my code wasn't doing the "pid X is not a child process of this shell" test. I _can_, but I didn't see the point in arbitrarily limiting it like that? (If I disown a PID, why can't I wait for it later? It hasn't got a JOB number anymore, but it's still a process? I know I've hit this before, the lack of a wait --raw as it were...) So whitelisting $! wasn't a thing I needed to do?

And while we're at it:

$ echo $(echo hello)
hello
$ echo $!

$ echo $(echo hello &)
hello
$ echo $!

Why is <(thingy) different from $(thingy) for setting "$!"? And (in yet another new tab):

$ wc <(<README)
      0       0       0 /dev/fd/63
$ echo $!
12264

Why is that a process? Come to think of it, why is it fd 63 instead of the path to the file? No, wait... echo $(< README) is the special case I'm thinking of, the above is just a weird NOP.

The sun came up hours ago and it's getting hard to see my laptop screen. Texas sun is not compatible with working outside on electronic devices, but the pandemic doesn't offer indoor working spaces outside the home (under a cat).


May 7, 2021

I just don't have the energy for politics this week. (There's been some good news, and bad news, and sadly facebook still exists... but post-vaccine I am TIRED right now.)

I need to get a toybox release out. The last release was in October, which means I should have gotten the next release out January 24 if I'm doing time based releases every 3 months. In reality, april 24 was SIX months from the last release, and may 24 makes seven, and that's too long.

Of course I've been hip deep in adding function and job control support to toysh, and I'm sort of reasonably there on both now, but there's still a lot of work to do on each. In functions there's still a failing test with $* expanding function arguments, I really need to teach pl2str how to marshall functions to nommu subshells (which is sort of related to recursively parsing case statements inside "$()")... Over on job control more is missing: I haven't implemented 'fg' and 'bg' yet, $(()) isn't setting $!, I need to write the default ctrl-Z trap handler and the "trap" command...

Any release is just gonna be a snapshot, but at some point I need to take said snapshot, test, and publish it. And get all the mkroot targets working with the current kernel release, which is v5.12 at the moment.


May 6, 2021

Back at the table! Potential for productivity! Except probably not actual productivity because yesterday I was back to like 60% and today I'm maybe 80% and likely to introduce bugs and design glitches if I get in too deep. (The fingers on my right hand are stiff and achy. This whole experience seems like a preview of what feeling 20 years older is probably like on a daily basis. Wheee.)

But I can at least debug stuff. I'm always up for root causing bugs, that's just a matter of being vindictively persitent running a sort of design level bisection search (for a definition of "design" that includes all the OS/hardware/compiler dependencies) for where the behavior of the running code deviates from the expected behavior. At some point, a variable or function/system call argument has a different value than you expect from a code walkthrough, and enough printf() statements will lepidoptrically pinpoint the moment of deviation to a specific assembly instruction and clock cycle if necessary.

Keep threads out of it and it's just about deterministic; any problem you can reliably reproduce you can debug. The only real creativity is in A) modeling potential system interactions to GUESS the answer faster than it takes to tediously grind to it, B) figuring out how to instrument each new situation to get data out. Which can involve building dependency packages from source, including the kernel and C library. Sticking a printf into glibc or the kernel doesn't mean the problem was IN the C library or the kernel, that's just where the deviation from expected behavior occurred. The CAUSE is often earlier, and once you've seen the test deep in the kernel that's going off model you go "oh, I need to set this extra bit in the flags option of the system call to send it down the branch I want, no wait I _did_ that, why did libc mask it out... because it wrapped the system call in a "smart" way and wants to force me to use this other API, great, use syscall() instead of their wrapper..." (In extreme cases you may need a high-end oscilloscope to get visibility into something that heisenbugs when you instrument it, although reproducing under a VM is much easier. Most of the time strace and ltrace and printf cover it.)

Alright, where DID I leave off with all this stuff? Sadly my laptop has developed a fault where it powers off when carried in my backpack for any length of time (battery's probably slightly loose, software suspend needs to keep the memory powered up) which means I lose my open windows every day. It's moderately annoying, but this IS one of those extra-big batteries that sticks way the heck out from the back of the laptop, as was all the rage circa 2015.

So much back email. Spam that made it through gmail's feral filter included one from a random gmail account with no subject line, the body of which is the disclaimer section of a BSD license. I ALMOST replied "Um... what?" to that one on the theory they might have been trying to raise an issue about 0BSD... except comparing the disclaimer text with 0BSD it was the disclaimer section from a DIFFERENT license. (It covered all the same points, in the same order, using different wording.)

That whole 0BSD license disclaimer section is ballast anyway. It bulks up the license so the deviation from the existing license looks smaller (it means that half-sentence I removed was 14 words out of 111, leaving 97, instead of 14 words out of 34, leaving 20), and is full of chewy legalese to make lawyers feel comfortable, but the real reason such disclaimers ever existed in the first place was that a $50 million mainframe depreciating 50% every 18 months lost almost fifty thousand dollars of value per day, which made even a short service disruption was worth suing over. Plus the kind of organization that can afford to spend tens of millions of dollars on computers annually is likely to have an in-house legal team on staff (or at least on retainer) so it doesn't necessarily cost them anything to sue. Which meant all the bespoke big iron software development contracts of the 1960s and 70s included huge CYA "do not sue me" clauses in case they caused the client a service interruption, which were copied by the early 1980s shrinkwrap software guys to look like the big boys. (This is a computer, this is software development, obviously this is what you DO. The fact one was a multi-million dollar bespoke development contract and the other was a $50 retail boxed software copyright license was carefully ignored by white male twentysomethings in their parents' silicon valley garages cosplaying as Fortune 500 executives performing "fake it till you make it" style affinity fraud.)

Keep in mind capitalists started whining about microcomputer licensing in 1976 but copyright wasn't extended to cover binaries until 1983 and then shrinkwrap software licenses (license text inside the box so you can't see it until after the purchase) weren't enforceable until the DMCA changed the law again 24 years later. Any actual license text was marketing bluster for decades; it didn't matter what it said back when none of it was enforceable. Huge disclaimers being a thing everybody does dates back to that period, and as with the /usr/bin split it's another case of grandma's roasting pan. (Grace Hopper basically promised to haunt people who said "but we've always done it that way".)

These days the disclaimers are retained for the same reason the White Knight in Through the Looking Glass had anti-shark anklets on his horse: obviously they worked, do you see any sharks on this mountain? Imagine if we DIDN'T have them. Of course half the software on github has NO license specified, and thus no disclaimers, but nobody's been sued over it yet. Very little of the javascript in web pages comes with license terms, and it runs on your computer and some of it mines bitcoin or performs rowhammer attacks amidst a continuing lack of lawsuits.

I'm sure I wrote a better and more detailed explanation of all that license disclaimer stuff years ago but can't find it via google, possibly it's in the missing second half of the 2015 or 2016 blog pages? I should really dig what I wrote off the relevant backup drives and edit them for posting. Or it could be one of the holes in the mailing list archives from dreamhost's repeated faceplants. (And yes, six years later the "temporarily disabled" message is still there, because dreamhost.)

Oh hey, I figured out why the fingers in my right hand hurt as if they're cold: because they ARE much colder than the fingers on my left hand. My upper arm is still swolen from the injection enough to compromise my circulation. :P


May 5, 2021

Day 3 post-vaccine. "Better" is a relative statement.

I walked to HEB early this morning! (They open at 6am and the day's clearance is marked by around 7.) Walked home (2 blocks, carrying about 5 pounds of stuff), and collapsed in exhaustion until the handyman showed up to frown at the washing machine. (But yesterday walking to the kitchen was an ordeal, I'll take it.) The problem of course wouldn't reproduce in front of him; I figured out later that it's _draining_ fine but the spin cycle isn't spinning (so works great when there's no laundry in it, but the wet laundry is too soaked for the dryer to handle and if it sits for a few minutes it leaves an inch of water behind in the washer despite having drained fully at the time).

I actually had a few hours of feeling reasonably coherent after that, then took a 4 hour nap until the alarm for $DAYJOB's weekly engineering group call, which I attended but was not particularly coherent for. Followed that by doing dumb things all evening like pouring myself a glass of tea with milk, taking a sip, setting it down in front of me on the kitchen table, and NOT defending it from peejee who knocked it over 10 seconds later (onto me) and happily drank milk tea off the table while I toweled myself off. (She's a very experienced Elder Kitten, who recognizes an attack of opportunity when she sees it.)

After another couple hours of nap I finally headed back to the table shortly after midnight (technically the 6th now). It's a 2 mile walk, but between generous use of caffeine (after 3 days of just heavily milked tea for caffeine), taking it slow, and the whole "sit down at the end" part, it seemed worth a try. I expect to have SO much email to shovel through...

Called the fire department on the way to the table when I tracked down the strong smell of gasoline (cut right through my mask) to a motorcycle dripping into a puddle underneath it, parked next to the sidewalk. (Well, I called the 311 austin non-emergency line to ask if this was a thing they cared about, and they forwarded me to the fire department who were indeed interested.)

The time of the past few entries is weird: I wrote about solar+LN2 the morning before getting my shot, then didn't turn my laptop ON for 3 days and am backfilling entries. It's currently 4am on the 6th and I'm at the table downloading All The Email. Then again whenever I'm in Japan I'm never sure whether an entry should be the Japan date or the USA date 11 hours later, and my preferred nocturnal pandemic schedule raises similar issues. The even/odd day topic sorting thing I settled on after Twitter took away my political venting space (because they consider billionaires a protected minority) means I mostly shove stuff into whichever adjacent day handles that topic, but I haven't been keeping up with world events this week and am conflicted about covering that stuff anyway. (I'm torn between "this is not my area, I should leave it to others and focus on what I actually do" and "even germany's Nazi party wasn't LITERALLY TRYING TO END HUMAN CIVILIZATION FOR PROFIT". I really should fiddle with the python script that makes the rss feed for this blog to teach it to make a separate feed for each <span> tag's contents. It's on the todo list...)


May 4, 2021

Had my J&J covid 19 vaccine injection yesterday morning. I'd scheduled it at the UT HEB pharmacy so I could just stay at the table a couple hours after sunrise and then walk a few blocks to the pharmacy. It took me an extra half hour to actually take the injection because of my needle phobia (I apologized repeatedly for running outside to hyperventilate, they were very nice about it), and then I got a lyft home instead of walking because AAAAAHHHH NEEEDLE!!! and took a nap to sleep off the adrenaline aftereffects.

The downside of receiving an effective vaccine for a disease you've already HAD is your immune system is prepared to strike HARD, and a large part of covid's effects aren't due to the disease itself but the immune response to it. Fuzzy caught covid from me back when I got it at jury duty last year, and her J&J shot on friday left her sick all weekend.

By this metric, my experience is at the high end of typical: I feel like I've been punched in the arm, exhausted, joint aches, muscle aches, headache, and my EYELIDS somehow hurt. And while I don't feel cold I _really_ want to stay under thick blankets, and am sweating and constantly dehydrated. I've gone through most of a gallon of tea and a large can of coconut water just _today_. I haven't left the house in two days, and either slept or lay on the couch the entire time. Spoke to Jeff on the phone a little, but I wasn't particularly coherent or able to concentrate. My achievements in the past 48 hours include making 1 pot of macaroni and cheese from a box mix, and taking a shower. Each was an exhausting challenge.

Jeff seems to have had covid _twice_ (he caught it in canada and then a second strain in Japan; his lung function has been below average for years so it was quite noticeable both times), and his first Astrazenica shot left him sick in bed for 3 days, but didn't interfere with his breathing, so that's nice. He hasn't had his second shot yet because Canada's ring-wing loons sold Canada's domestic vaccine production capacity to capitalists who and dismantled it and moved what was left overseas a decade or so back, although the current government is trying to pretend this all happened 50 years ago rather than recently enough politicians still in office could be blamed for it. What covid-19 vaccine Canada has managed to obtain was purchased from India which is now regretting selling it and unlikely to provide more any time soon. Hence Jeff only getting one dose.

The USA appears to be on the downswing of its vaccination bell curve: the people willing to come to the vaccine are getting it, leaving the people the vaccine has to come to which is slower. (This isn't "hesitancy": I myself waited until I could get vaccine without driving to it, and for the one-dose version instead of a 2 dose version. The vaccine came to me, I didn't go to it, and this is normal.) This already means we're producing vaccine at a faster rate than the population is absorbing it, and we should be able to politically ADMIT this and be able to start exporting some... by the end of the month maybe?


May 3, 2021

So here's an interesting trend, solar panel manufacturing in 2021 is at trying to at least LOOK like it's moving away from china.

I just watched a "best solar panels to buy in 2021" roundup du jour, and the first two solar panels it recommends are korean (one in partnership with germany). Then the next one is from a Norwegian company (which moved its manufacturing to china in 2012 because it was cheaper, but can presumably move it back out again if necessary). Then the fourth is korea again, and the last one is a silicon valley douchebro-run company that just _recently_ spun off its manufacturing and now seems to be regretting it, but even they tout "manufacturing in france, malaysia, mexico, and the philipines" in that first link, and mention manufacturing moving from china to malasia in the second link.

The solar industry is most likely trying to get out ahead of the obvious coming trade war with china caused by the dictator-for-life's "wolf warrior diplomacy", territorial ambitions, and consolidation of power (eating Hong Kong and Jack Ma and so on). Taiwan and Korea building new high-end fabs in Arizona and Austin is probably also related to this: moving infratructure physically far away from China.

China's escalation against Taiwan seems partly due to the dictator taking personal insult from Foxconn's new CEO... for a definition of "new" applied to a 65 year old man replacing a 70 year old. China's Chairman Xi is 67, Putin is 68... Lots of stuff has to come to a head over the next decade just because the people pulling the strings are expiring.

Yes, Foxconn is a taiwanese company, not chinese. Another reason china is insecure is their education system brainwashes kids to instill obedience to the communist party in a way that (intentionally!) destroys all creativity. You can't make "huh, that's funny" discoveries when saying "there are four lights" gets you renditioned to a death camp. Shenzen was BUILT because it was a suburb of (then british-controlled) Hong Kong where creative people could be borrowed from, and Taiwan provided the rest of china's new technology designs. China's obedient citizens are very good at copying and grinding through established procedures (which can mechanically improve the efficiency of existing designs), but anyone capable of doing anything new inevitably winds up in trouble with China's government. China MUST copy all their designs from somewhere else (or import creative workers from overseas). This is why China is great at manufacturing silicon solar panels based on the same World War II era Bell Labs "Aha!" research that gave us the transistor, which NASA poured money into during the space race and the Carter administration doubled down on during the 1970s OPEC oil embargo, then Germany grabbed the baton in 1991 and led the world for a couple decades until China started trying to recover from the national embarassment of Beijing's terrible air quality at the 2008 olympics. China is successful manufacturing solar cells because the basic technology is most of a century old, it's just more of the same with higher tolerances. There's very little creativity in what china does with solar panels, just precision, economies of scale, willingness to employ slave labor and poison their environment, and throwing money at the problem. Plus it's the training wheels version of the silicon wafer tech done for semiconductor fab: same big crystals minus the need for purity and clean rooms and putting anything ON them, and even the big crystals part is optional.

Interestingly, 78 year old Biden did NOT cancel 74 year old Trump's two stacked tariffs (30% plus 25% totaling over 50%) on importing chinese solar panels into the USA, instead he's keeping and enforcing them. The dorito taxed them to protect fossil fuels from competition (he failed), but as long as the political cost to put the tariffs in place was already paid Biden is using them to build domestic solar panel manufacturing capacity and wean the USA off of dependence on china. Extending the investment tax credit to install panels while taxing china's panels is a subsidy for domestic manufacturers: it allows panels made outside of china to be cheaper than panels made IN china, at least to US consumers.

There's a lot of weaning to do: china has thrown a LOT of money and people at solar panel manufacturing since 2008, on an exponential growth curve. In February 2021 the global solar manufacturing percentages were:

China  : 71%
"other": 9%
Malasia: 6%
Korea  : 6%
USA    : 3%
EU     : 2%
Japan  : 1%
Taiwan : 1%
India  : 1%

But those numbers are really volatile because there was a 43% increase in solar panel installs from 2019 to 2020. It's hard to compare that "19.2 gigawatts of new capacity" (so ~45 gigawatts of total capacity?) to the USA's total generation capacity, because those figures are peak output rate and the EIA gives cumulative energy produced, but it's interesting to note that 1% of the USA's electricity now comes from rooftop solar.

The main thing China is producing is raw silica: assembling cells into panels can be and is being done elsewhere. Silica mining is like rare earth mining in that it's not scarce or hard to scale up (silica is just sand/gravel refined in electric arc furnaces vaguely like how aluminum and steel are made today), the problem is both the mining and the refining are an environmental disaster that poisons people (although not as bad as fracking and oil pipelines). There's some time/investment scaling up to replace that elsewhere, but it's not _hard_. The main issue is political: figuring out who/where to poison, which is why the west NIMBYd this to China in the first place. But as the fossil fuel industry has repeatedly demonstrated, poisoning people at home is merely a political cost not a hard roadblock.

China has been dumping this toxic process in Uighur areas (and bussing in people from the concentration camps to work on it). As with rare earth mining the USA was until recently happy to pay someone else to poison their people (and lie about it), but with china making an ass of itself diplomatically such considerations resurface and help tilt the scale back against them.

Meanwhile, the recent Los Angeles Times article about California's electrical grid hitting 95% renewable energy needs a giant asterisk: it's only a "record" because the california electrical grid operators have been DESPERATELY TRYING TO AVOID IT. California's crazy state laws make "wasting" electricity illegal, and that includes curtailment of solar and wind farms that are producing more power than the grid can currently use, which means they wind up paying other states to take the extra electricity because simply unplugging the panels (which doesn't hurt them) is NOT ALLOWED. That is a stupid law, and it PREVENTS california from installing enough (ever-cheaper) solar and wind capacity that their peak generation would ever even momentarily go above 100% of what the grid is using. Of course having renewable generation at or near 100% any significant amount of time means it goes OVER 100% some of the time, and their crazy laws force them to PAY to dispose of the extra electricity, and they can't afford to let that happen. Yes they could install twice as much solar, no the cost of panels isn't a big deal and it's easy enough to find space and wire them up, but it would bankrupt them legally DISPOSE of that much electricty in the middle of a sunny day. Once it exists, you can't WASTE it. A sort of electrical grid anti-abortion position: it's somehow morally ok to prevent it entirely up front, but once you CAN create it you MUST follow through and find a home for it. This is a california problem, it is entirely self-inflicted, and it's REALLY STUPID.

So the LA Times is reporting "we had a sunny day, power went to 95% of capacity" as an achievement, and the grid operators are probably panicing and looking for any excuse to permanently decommission enough solar and wind farms that they NEVER GO OVER 100% because doing so would cost them MONEY thanks to stupid laws. Just UNPLUGGING some of the panels/turbines is forbidden by law, therefore they must forever use less solar and burn more coal and gas instead because that never gives them EXTRA power they'd have to PAY SOMEONE ELSE TO TAKE to avoid "wasting" it. (Idiots.)

Another interesting side note: an alternative to curtailment is to use the extra electricity to make liquid nitrogen from air using existing off the shelf technology (the process is over 100 years old and been in mass production since the 1940s), and recent advances let you get the energy back out with over 70% efficiency (and about the same weight-to-power ratio from liquid nitrogen as current electric car batteries, with a WAY faster fill up time). So an alternative to curtailment is using extra energy can run compressors to liquify air (which is 4/5 nitrogen and 1/5 oxygen, relatively easily separated out when liquifying them; there's also 1-4% water you generally want to condense out earlier in the process, 1% argon, 0.04% CO2, 0.002% neon, and the rest is a rounding error), and sell the oxygen (and other gasses if you like) and store the (chemically inert) liquid nitrogen in big tanks (commercially available in million liter sizes; this is well-established technology). Then you can turn it back into electricity as needed on-site (after the sun goes down), or transport it by pipe/truck/train. All that infrastructure being used for liquified natural gas applies to liquid nitrogen just as easily (liquid CH3 is -162 C, liquid N2 is -196 C) except THIS stuff is easier to make, less dangerous (yeah yeah, modulo oxygen condensing on it), and doesn't pollute.

I have some experience with liquid nitrogen, which people think is scary because it's unfamiliar. But lots of things are dangerous, and gasoline, boiling water, and liquid natural gas are all generally considered MORE dangerous than LN2 by people familiar with LN2. It's entirely possible to get hurt by it, but this interview explains the difference between the bond villain theatrically frozen to death by LN2 (which has a lower specific heat than water even WITHOUT the leidenfrost effect) and the actual mild scalp burn the actor got when some of the liquid nitrogen they indeed dumped over him while filming got caught in his "hold still so we can replace you with a statue after the cut" harness and he wasn't allowed to move to shake it off. And no, he didn't suffocate either.

LN2 is safe enough that it's a common thing to let children play with (under adult supervision) when trying to impress them about science, which is not something normally said about gasoline. Nitrogen is a liquid at room temperature when pressurized to 3000 psi. In a tank that keeps it at that pressure, it lasts literally forever with no loss, but 3000 PSI is rather a lot of pressure and those tanks tend to be expensive and not get transported much. At the other end of the scale, a common thing to do is get an insulated but unpressurized dewar: the 30 liter one we used to borrow from UT had a missing lid so they stuck a styrofoam cup into the top and it was still over half full after 2 days when we got it filled on Friday and used it to make ice cream on Sunday. In between, you can have an insulated and pressurized tank that keeps SOME pressure (22 PSI is common), but a valve releases pressure above that, so the liquid inside stays cold (due to the evaporation and gas release), but not FULLY cold, and stays pressurized but not FULLY pressurized. Those containers keep their contents longer than a dewar but are much cheaper than the "lasts forever at room temperature" ones and if they get damaged venting 20 PSI isn't that big a deal. I think the big 220 liter cylinders we rented from Airgas for Penguicon and Linucon were that sort (it's been a while).

At sea level air pressure, nitrogen is a liquid at -196 C, and what happens when you open those big pressurized 220 liter tanks is that enough nitrogen boils off to get the rest DOWN to "stay liquid" temperature (which is loud, squirty, and accompanied by a lot of fog: they make a little metal sponge you screw onto the end of your long metal hose to manage the pressure differential) but only a very small part of the liquid (fraction of a percent) actually boils off when you do this, the rest just gets really cold. You have to wait for the remaining liquid to heat up to get it to boil off and turn into a gas: at Linucon and Penguicon we poured LN2 into normal steel kitchen bowls and carried them with kitchen potholders. Yes it was boiling (rapidly at first as the bowl cooled down, then slower as it constantly picked up heat from the floor under it), but just like a pot of water can boil for 20 minutes and still be nearly full there was still plenty of LN2 in the bowl for quite a while. (And it actually went from "full boil" to "simmer" in like half a minute as the metal bowl cooled down.) In the video linked above I was holding such a bowl with a towel wrapped around it, and the reason I was in a hurry was the edge of the towel had dipped INTO the LN2 and was wicking some up into contact with my hands, which stung a bit. Not enought to leave a mark, but it was uncomfortable. Yes the nitrogen expands about 700 times going from liquid to gas, yes you can make a bomb out of that if you try (same goes for boiling water, which expands 1600 times); this expansion is why it's capable of storing energy. (A bigger concern is that the "condensation" exposed liquid nitrogen picks up is liquid OXYGEN condensed out of the air; oxygen condenses at a few degrees warmer than nitrogen does. Generally it's tiny amounts dripping off the bottom of the steel bowl onto the carpet and evaporating immediately, but still: good to know. Only really happened on the outside of the bowl: the constant positive pressure from evaporating nitrogen prevents much oxygen from coming into contact with the actual liquid.)

Lots of people have been proposing using "compressed air" energy storage (in old salt mines and such) for decades, which is slightly more dangerous than nitrogen but again fairly common and mostly a known risk. The reason liquid nitrogen is safer than liquid air is nitrogen is inert: if the oxygen and nitrogen AREN'T separated, at high pressures partial pressure of oxygen goes over 100% which makes fires tricksy. (You know how blowing on tinder/coals can make them flare up? Pressurizing the air around them does that too.) Also, at LOWER pressures you don't have that "it wants to be a liquid" happy medium option where you naturally trade pressure for temperature when vented, which means if something DOES happen without that phase transition ALL the gas is trying to leave containment at once, rather than just enough to get the rest down to temperature. This is why given a CHOICE, liquid nitrogen is cool. (Yes I know, and I typed it anyway.)

Anyway, there's lots of domain expertise to be had here and I'm happy to see people working on it. I did my usual jack-of-all-trades wander through this way back when so I know where to look stuff up and find domain experts, but wouldn't try to do it myself unsupervized. Not my area. (I did a reserach writeup with sources and numbers for the penguicon mailing list back when I was first proposing bringing liquid nitrogen ice cream to... year 3 I think? But you can tell I'm no longer involved with Penguicon, they don't preserve their history in an obviously accessable way and that web archive went down. I remember looking up partial pressure of oxygen mountain climbers experience before needing supplemental oxygen to perform heavy labor, and trying to work out how much nitrogen would have to displace how much oxygen in the room to match that, and how many liters of liquid that would translate to given X cubic feet of room space; tl/dr the carbon dioxide exhaled by the people in the room was a way bigger health risk...)


May 2, 2021

Covid injection tomorrow. Not exactly looking forward to it (thanks to a childhood trauma about needles I used to be able to make my gums bleed by thinking too hard about them; haven't replicated the experiment in some time because I'm better at NOT thinking about stuff these days), but I walked to the pharmacy the appointment's at on the way back from the table this morning, to make sure I know how to find it.

There are a number of authors who... if I give them money will they write faster? The amount of money I'm current capable of giving them is not going to be enough to move the needle much, but I feel I should show the flag anyway? Of course, there's like 37 other authors I should ALSO support. I have a patreon with several donors contributing to my toybox work, which is amazingly cool, but unfortunately I can't contribute to other creators directly FROM that money. Instead I have to give patreon my credit card info so they can charge a credit card each time in order to send money OUT to anybody else. (Incoming money can be paid out via direct deposit, which is different bank information. But incoming money pools in patreon until I log in and hit a button, and I can't donate OUT from that pool because patreon won't let me.)

I mean either way it's my credit union account and not the main household account, but still. I am VERY BAD at online financial anything because I know too much about how the sausage is made to trust it. (Fade and Fuzzy do all the online financial stuff for the household. That doesn't make it any more secure, but then it isn't ME doing it. Yes irrational trauma-based behavior is the theme of today's blog entry.)


May 1, 2021

So many thunderstorms trying to walk to the table at the geology building at night. (And asian tiger mosquitoes, although mosquito repellent works on them too so far.)

The washing machine is leaving a couple inches of water left in the bottom when it's finished washing. Putting sopping wet laundry into the dryer turns out to have been bad for THAT, although it made it about half an hour before it went... um... let's just say it doesn't normally have that many lights lit up while running. The scorched smell isn't too bad (the laundry itself is fine, albeit still pretty dam), and it stopped buzzing when I unplugged it. (It wasn't _loud_, but it doesn't normally doesn't continue to make noise once stopped?) I left the door open and am hoping the thing is less unhappy once it dries out a bit. (You're not supposed to get a dryer wet: who knew?) I now have as much laundry hanging up to dry in texas as I did in the Tokyo apartment, which is new. We should probably call someone to frown expensively at both things, but we're TRYING to pay taxes and after _that_ our non-elderly cat needs a cardiologist appointment.

GOP loons are still trying to retroactively steal the 2020 election, censor their critics, and dismantle free speech. I'm not a fan of biden but he could be worse. Restarting prosecutions helps a lot, although as usual the Biden administration is half-assing it.

Here is an excellent thread on why we should defund the police rather than "reform" them. Law enforcement doesn't have to be done by police. And a reminder that the police brutality mega-thread is still going, although he doesn't bother add every single new instance to it now that realization of how big a problem it is has become more widespread. (If there's one saving grace, it's that the police tend to be really stupid.)

One strong reason to speed up self-driving is that "tail light policing" is one of the main revenue sources of most police departments. (Of course the rest of it is a grift too.)

You know how Disney is primarily responsible for copyright terms being infinitely extended? Turns out they do lots of other evil too.

Oh hey, remember the hairshirt problem the left has? It's back, or more accurately never went away. (And yes, the recent "biden banning red meat" thing is the exact same idiocy from PETA that even AOC falls for which leaves us vulnerable to exactly this sort of nonsense.)

A good thread about how bringing back the "fairness doctrine" would most likely make things worse, which links to an earlier thread making a strong case that everything I wrote back in 2017 about the topic was... naieve at best. (People have been gaming the system as long as there's been a system.)

International pursuit of money laundering needs to be a top priority. I mean, they're doing some but need to do more.

Christianity remains deeply problematic (and republican). Indigenous people make much more efficient use of resources (not that it's hard to beat out massively subsidized white landed gentry failsons), but of course white people freak out when forced to follow their own laws.

The military is profoundly misogynist and will not protect women who join it from their fellow soldiers. (Semper fi is gendered.)

SO many reasons I do not have a Faceboot account. (I still miss twitter the same way I miss livejournal, but have zero interest in ever joining Faceboot.)

Guillotine the billionaires. Not any _specific_ billionaire: all of them. Being a billionaire should be a federal capital offense, and not JUST because of the pun.

Remember how terrible Nestle is? They've been bottling water from US national parks under a permit that expired in 1988, and continued right through the big california drought because capitalism.


April 30, 2021

I got a covid vaccine appointment! J&J monday morning at the HEB pharmacy at UT (a bit southwest of MLK and Red River).

The weather forecast continues to say "all the thunderstorms" today, and tomorrow, and the day after. (Austin has a monsoon season now, which is why my house needed tens of thousands of dollars of landscaping after tens of thousands of dollars of flood remediation. I miss having savings, but imagine if I HADN'T been able ot throw money at the problem? I don't have to: two houses on my block got condemned due to black mold and were sold, torn down, and replaced with 3 story mini-apartment complexes.)

There was a forecasted hour long break in the weather with no lightning OR rain which I used to walk to the table. It's coming up on 3am and the rain has just started back up (oh girl has it) and the loud once-per-second snapping sound from the roof has just started again. (Whatever's periodically shorting out up there does NOT like getting wet. I've emailed facilities about it more than once, but they don't seem to care? Oh well, the Norman Hackerman building hasn't burned down yet...)

Playing mkroot regression whack-a-mole is always tedious. The armv7l target hasn't got a network card, but the aarrcchh6644 target does, and they're the EXACT SAME THING in 32 and 64 bit versions! It's virtio all the way through, and it's a virtio network card that's failing to show up in 32 bits (but works fine in 64 bits). I can't upgrade qemu to current until I upgrade devuan to current because the qemu git repo moved its python 3 prerequisite version to something newer than Devuan 2.0 packages so it refuses to build from source. (I suppose I could build python3 from source to build a more current qemu from source, but this turns into a dependency cascade REALLY quickly, which is what reproducing the LFS build under mkroot is for, which comes AFTER promoting toysh.)

Speaking of which, I want to set up a wireguard test server for $DAYJOB in a kvm instance, and I poked our sysadmin wale for instructions, and he sent me a link to a page that is exactly the kind of thing I DIDN'T want. ("Install this package, which installs 37 prerequisite packages in a cascade, and then use this fully automated mechanism so you don't understand anything that actually happened.)

In toybox development I hit an ISSUE in "make test_sh":

[: missing argument after ‘=’
FAIL: sh $! = jobs -p

Yes sh is behaving wrong, but the more SUBTLE problem is that this error message has “smart❝ 〝quotes‟ which means it's not toybox code producing that error. And it's not bash code either:

$ [ x = ]
bash: [: x: unary operator expected

What it is, is:

$ /usr/bin/[ x = ]
/usr/bin/[: missing argument after ‘=’

And THAT is a problem with the test suite, and how "sh" is special cased as the only standalone command that needs the multiplexer. Under certain circumstances (mostly having to do with nommu in pipelines but apparently triggering here, I should track down why) toybox won't run MAYFORK commands directly, but will instead fork and exec them. And we're not providing toybox versions of those MAYFORK commands in the $PATH, so it's calling them out of the host $PATH. And debian has TWO implementations of test, one as a bash builtin and one in /usr/bin, which behave DIFFERENTLY because gnu/FSF/dammit.

So I need to A) upgrade the test suite to provide wrapped versions of the mayfork commands when building the shell, B) figure out why a toybox with fork() support isn't calling this mayfork as a builtin, C) finish implementing the "jobs" command and $! for background tasks.

Someday, I should cycle back around to writing about computer history stuff. Here's a fascinating article about an early macintosh adopter in February 1984, who explained that you could only write Mac software by buying an apple Lisa (its predecessor system) until Microsoft Basic and then C compilers (first Softworks, then Megamax, then Lightspeed) were ported to the Mac. This is exactly the problem I'm trying to address with Android: lack of native development environment. This system is 14 years old and still isn't self-hosting. That's inexcusable.


April 29, 2021

Walked partway to the table under an IMPRESSIVE amount of lightning, lost my nerve about 2/3 of the way there, and then checked the weather huddling in an apartment's covered parking area (thunderstorms for the next 12 hours, this is not a "wait for it to clear up" situation) and got a lyft back home. Alas, no programming session today.

Biden gave his own State of the Union address last night, which apparently got half the TV viewership of The Trainwreck because everybody trusts THIS guy to just get on with it without needing to scrutinize his every move for travesty du jour we need to defend ourselves against. The newsdrones are sure this is a bad thing, because we're not watching newsdrones. Ok then.

I'm all for pervasive encryption, but I have yet to see a use of the "signal" app that wasn't hilariously insecure. It's not just that it points a giant neon sign at you saying "I have something to hide", the bigger problem is the user interface of software created by crypto people always immediately turns the things into a footgun. The classic tradeoff between usability and security means the most secure possible system is one that's been crushed and burned to ashes which were scattered at sea: nobody's getting data off of that! And nobody can use it to accomplish anything, either.

Not only is correlation not causation, but it's really easy to invert cause and effect.

This is why Intellectual Property law must be destroyed instead of "reformed". Intellectual property law is an all-or-nothing principle that strives to fail universally for everything simultanously. (Absolutists often destroy the thing they defend, because they give its opponents no alternative but to burn it out root and branch.)

Good thread from a member of the precariat.

The "leveraged buyout" remains a scourge. (Guillotine the billionaires, and defund the police.)


April 28, 2021

Hah, bumped into an old busybox post I made (while looking for something else) that shows the roots of how the designs of busybox and toybox diverged, back before I even started toybox.

Ok, now that I have shell functions sort of basically working (just fixed a premature free issue with function command line arguments getting the lifetime wrong)... it turns out I have more design work to do. The question is does a function() call need a struct sh_process instance to represent it, in addition to the struct sh_fcall added to the TT.ff stack. Because run_command() is returning one right now, with pl->pid set to 0. (Which means "ran as builtin", except we added an entry to TT.ff so execution FROM HERE continues on into the new function. All the other builtins have already FINISHED when they return pid 0.)

From a flow control perspective, a function call is sort of a goto (jump into a different chunk of parsed code), and also a bit like a "source" command. But "source" is implemented as a shell builtin (a NOFORK calling through toy_list) which means it's recursing on the C stack (thus I made a hard limit on the number of recursive "source" calls it can make, which shouldn't be a big deal because source doesn't generally nest very deep and the limit is 50 for nommu and 250 when you have an mmu and thus a growable stack). While I _can_ make "function" a shell builtin as well, A) that means it would also recurse eating stack space, B) it's naturally a flow control statement and none of the other flow control statements are shell builtin functions... no wait, that's confusing the "function" keyword DEFINING functions with calling them (which is the current design rough edge). I am NOT adding arbitrary function names to toy_list, no way.

But a function call can be in the middle of a pipeline, in which case it needs to run in a background process. That WOULD need an sh_process to represent the pipeline stage, but that's because there would be a PID of another shell running the function. Right now a shell function isn't backgrounded: it runs inline like a NOFORK process. I can't JUST stick a fork() in random places because we support nommu, and although I have plumbing to handle "echo hello | { cat; } | cat" marshalling compound statements (that middle part parses as "{" "cat;" "}" to three pipeline segments: a type 1 start-new-block, a type 0 execute-statement, and a type 3 end-block), I haven't taught the pl2str() plumbing to marshall function data to a nommu subshell yet (it doesn't know about type 'F' pipeline segments). Bash has a syntax to export functions to child shells as specially formatted environment variables, but what it documents and what it actually DOES don't match and I'm not sure how much compatibility matters here? Plus for nommu subshells I'm passing child data through a pipe instead of the child process' environ[]. Plus I don't want to accidentally reproduce the shellshock bug. :P

The other issue is I still need to implement the "return" statement, which SORT of isn't hard except that right now the function call is advancing pp = pp->next (because my first attempt was looping endlessly, returning back to the same function statement and calling it again), but that needs to be mediated by && and friends. You don't JUST advance, you return and figure out if you SHOULD advance (or end block).

I actually glued a NOP type 0 statement onto the start of each function definition because when I set pl in run_command() and return, it advances past it before running the next thing (because it thinks it just ran the current statement, so needs to pl = pl->next before looping). On return it would make sense for pl to point to the function() call, except any && on the end of the } for the function needs to be transplated to the 'F' record rather than the 3 record at the end of the function->pipeline list. I think I'm already doing this during parsing? (So why did it loop?)

I need to add tests for ALL fo this...

This cartoon is related to Neil Gaiman's talk, and Ira Glass had a good related talk. It's not just easy but NORMAL to get discouraged partway through doing something because what you've got so far is inferior to what you intended to create. And my father used to say "eventually you have to shoot the engineers and go into production" (a saying he picked up working at NASA before I was born) because what you're working on can always be improved. Deadlines can be highly motivational.


April 27, 2021

At my second tax preparation appointment yesterday I paid an accountant $300 to confirm that I need to pay the government another $5600 on top of that. There was some witholding, but not enough. Fade's and my most recent stimulus payment was earmarked for this, but doesn't quite cover it. We have until June 15th to save up the rest.

The downside of working for a company that doesn't have a US legal presence (and thus leaves me with Schedule C self employment to explain wire transfers from singapore) includes figuring out what portion of my electric bill being stuck at home most of 2020 allows me to deduct as an office expense.

I like my job, and like most creative people am not strongly motivated by money (but AM highly distracted and stressed out by a _lack_ of money), but I admit loss aversion and the prospect of retirement are making me wince a bit. I earned four times as much when I spent a year (2018) at another employer while this job reshuffled their financing (reincorporating and "cleaning their cap table") after finding out one of their original investors was the lawyer for a canadian oil company who had been ACTIVELY SABOTAGING "Smart Energy Instruments" attempts to technologically wean electrical grids off oil coal, oil, and gas. (Conflict of interest, anyone?) Jeff made his saving throw and I'm back doing the "interesting rather than lucrative" work, but there's still no 401k (let alone contribution matching), my health insurance is through my wife's college (as husband of a grad student)...

Yeah yeah, if our startup strikes gold I get stock, but I have never in my entire career had employer stock options trigger even once. I've had an employee stock purchase plan at a Fortune 500 turn into stock (only slightly more than I could have bought myself through a broker, but it saved commissions and there was matching similar to a 401k plan without the tax penalties for not having inherited it from a dead relative)... but options aren't real. I like that I get to publish open source on company time, my schedule is flexible, I (remotely) work with really smart people I learn all sorts of things from, I'm just about able to pay the mortgage, and when the stars align I spend months at a time in Tokyo (which is lovely, despite my continued failure to absorb useful amounts of the language). Those are the benefits of this job. But according to my new tax appraisal, the equity in my house increased almost as much as I got paid this year (which means nothing if I live there instead of selling it, except that my tax bill gets even higher next year, and the 2017 GOP tax thing means mortgage interest is no longer deductible).

Speaking of taxes, Biden's proposal to give more money to the IRS is another half measure: guillotines would accomplish this and so much more. Sure it's worth doing (outright obvious in fact) but it's the merest tip of the iceberg. Alas, half-assing it is what Biden is there for. Allow just enough change to let off a little steam, while keeping the boat unrocked until the baby boomers have died. The solid year of protests in the streets (from both sides) have died down since the inauguration. That is Biden's role, a heat sink to delay the engine burning up while the people who drained all the oil out of it cover their tracks.

The Onion is back to merely documenting reality. This doesn't mean The Onion is bad at its job: they're very good at it. Baldly stating truths powerful people dance around for a laugh was one of the standard jokes of medieval jesters. Professional comedian Hannah Gadsby's netflix special "Nanette" (a meta-comedy that among other things explicitly breaks down and explains the rules of comedy) has a section about managing "tension" in comedy, and "thing everybody knows but nobody can say" is a huge source of tension. (Avoiding being an asshole, and punching up instead of punching down, is an important part of doing this right.)

Republicans continue to serve plutocracy, but the result is a death cult. We need to zero out all current police budgets, there are much better ways do policing. Intellectual property law only serves corporations. Individual creators get screwed.

On the bright side, Elon Musk's upcoming kessler cascade should mostly clear itself in about 90 years. (Everything that man touches is problematic at best.)

Sexism thread du jour. (White guys need constant reminding of what the world is like for other people, on a daily basis because everyone else experiences it on a daily basis.)


April 26, 2021

I'm closing in on getting toysh function() definitions working, but this command has now passed 4000 lines of C. I have failed. (The sad part is it's all DOING stuff. Bash is tricksy and complicated.)

I can't get the order of operations to quite match. My function performs redirects and variable expansions at the same time. I had a hack so "abc={a?b} > potato" wouldn't create "potato" but had to undo it again to make function calls work right, because "x() { echo hello; }; ABC=x; xyz=42 $ABC" needs to resolve variables before knowing it's calling a function, and I want to use the same function context to hold the variables that xyz=42 is already creating, since the lifetime is the same. But resolving $ABC before assigning xyz=42 also creates the file "potato" before resolving abc=${a?error message} and thus aborting further processing the command, where bash errors out before creating the file. I shuffled it around multiple times, but the way I implemented it the variable evailuations and redirects on the command line are atomic (or at least handled by the same expand_redir() C function), and in bash it's gratuitously two passes. Bash does a LOT of extra passes on stuff, over and over again, and... I dowanna?

Bash has implementation details like this visible at the surface ALL OVER THE PLACE. I haven't looked at bash source code in ten years, and yet I wind up knowing how they did things because IT SHOWS AT RUNTIME. Sometimes I would very much like a little MORE ambiguity because it means the implementation is flexible, rather than overdetermined.

Meanwhile, did you know you can pipe the output of a function _definition_? Of course you can. Which means I gotta rip the union back out of struct sh_pipeline so strcmp(arg.v[arg.c], "&&") and friends can work on "x() { echo hello; } && echo also". What does the && mean there? Can a function definition FAIL? I mean, an invalid name can fail but that's a syntax error aborting the whole compound statement... Ah wait, no it isn't:

$ a\b () { echo hello; } || echo toast
bash: `a\b': not a valid identifier
toast

Bash? You are REALLY WEIRD.

$ function one two || echo toast
bash: syntax error near unexpected token `two'

THAT's the syntax error. (Why? Why is "function one echo 'hello world';" not a valid function definition? It's obvious what it DOES.) Right. THROW IT ON THE TODO HEAP, I already WROTE this section of the code and would like to get it to work before tearing it apart again.

Anyway, getting "a() { true; } && echo" to work means when I'm transplanting the pipeline block right after the function definition INTO the function structure during parsing, I need to transplant the terminator from the trailing type 3 segment (the "}" in this case) into the function definition segment (making it logically "function a $MAGIC &&" where $MAGIC is a pointer to a struct rather than a string argument because FUNCTIONS).

If you wonder why I've been quiet on the mailing list, this is what working on toysh is like. I don't expect this to make sense to anybody else. I fling it into my blog on even numbered days, but otherwise...

$ x() { echo hello; } | tr e x
$ x
bash: x: command not found

Bravo, bash. Just... sigh. The function definition occurs in a background process, just like variable assignments there would, and thus does not persist in the parent process's context. Trailing redirects attach and become part of the function each time it's run, but pipes and && and such stay in the initial context. Right.

Elliott sent a patch which made me say "ow, no, ow ow, no" and so on several times out loud. I mean I still applied it, and it was easy to fix, but it's kind of impressive how such a small change can be wrong in so many DIFFERENT ways. Here's the offending line (in main.c):

-  if (!(which->flags & TOYFLAG_NOFORK)) {
+  if (strcmp(which->name, "toybox") && !(which->flags & TOYFLAG_NOFORK)) {

Which is... let me count the ways:

  1. Repeating the string "toybox" violates Single Point of Truth: the strstart() in toyfind already looks for "toybox"
  2. Adds an extra string compare in a global fast path that's performance critical enough I actually bothered to implement a binary search (which I haven't even done in the _shell_ yet)
  3. This is a different test than other "are we the multiplexer" checks use, so potential behavior divergence if code changes around it
  4. The name "toybox" works (uniquely!) as a prefix (hence the strstart in toyfind();), this does not

The reason toybox works as a prefix is because WAAAAAAY back in the busybox days my solution to this complaint (where somebody wanted the suid commands in a different file from the non-suid commands but to still be able to use the multiplexer to call each set, meaning it needed two names if both were in the $PATH) was this patch making the multiplexer name work as a prefix, and when I wrote the toybox multiplexer a year later I made it do that too. Since then other people have found more uses for it. For example, distro package install plumbing can provide "alternatives", which means they wanted a busybox-coreutils that replaced the coreutils parts without installing E.G. ifconfig; to me it's a question of what symlinks you do/don't install but some people like to micromanage? I added "make change" to build EVERYTHING standalone if you really want to, but this is another way to do it. There's also toybox-static vs toybox-dynamic, toybox-musl vs toybox-glibc, and so on. It's a generic mechanism, it can do various things. I don't want ANY unknown name to call the multiplexer because that becomes a security issue, upgrade to a verson that doesn't have an old command but leave the symlink lying around and suddenly it's 'catv rm -rf *' time in some cgi-bin or something. (And THEN I taught toybox to follow one layer of symlinks to find a name it can understand, which would be another way to implement this instead of the prefixes, but some people are already using the old mechanism, so...)

To be honest SPOT says that strstart() shouldn't say "toybox", it should use toy_list->name which already says "toybox". (Because the first entry in generated/newtoys.h says toybox, because scripts/make.sh has an echo explicitly writing the first line into the file.) I totally need to do a youtube video with a walkthrough of the plumbing. Probably for the 1.0 release.

Anyway, I changed the offending line to:

if (!(CFG_TOYBOX && which == toy_list) && !(which->flags & TOYFLAG_NOFORK)) {

Half of which drops out at compile time.


April 25, 2021

It's easy to call the Boomers terrible parents, but the reality is many of them just DIDN'T parent: "Latchkey kids were a Generation X phenomenon. Of course being ignored by the Boomers was probably the best thing they could have done for us, given how profoundly incompetent they turned out to be at everything they valued enough to focus on. The Boomers inherited the postwar prosperity built by FDR's New Deal and the Greatest Generation's efforts in World War II and after (turning the infrastructure and training built for the war to eliminating Malaria and landing on the moon), and like so many trust fund kids they squandered their inheritance (as described so well by Spike Trotman).

I still really really hope the end of the Boomers breaks the fever of big oil, the 99%, financialized consumerism redefining "citizens" as "consumers", and so on so that we can start FIXING stuff. I look forward to a post-Boomer world as pretty much the main thing giving me hope. They CAN'T last much longer.

When people vote, the GOP loses. That's why they've turned every resource they have left exclusively to stopping it.

Didn't peleton do the horrible ad that Ryan Reynolds parodied? Why are they still being taken seriously?

Demilitarize the police.


April 24, 2021

Here at the table outside the UT geology building, I get net by associating with my phone via wireless tether, because the USB tether keeps disconnecting. (The question of whether USB-C cables become flaky and disconnect when jostled is easily answered: yeah, takes a month or two longer than the previous generation did, then it's flake city when you breathe on it.) I still plug the phone in to my laptop so it can charge, but it's not reliable delivery of data (and the transciever toggle hangs up existing connections, thanks Linux). Except the problem with a wifi tether is that there are multiple dozens of access points within range of my laptop (courtyard of a multi-story university building, facing two more multi-story university buildings), and every half hour or so the wifi disconnects and refuses to show any access points despite multiple rescans, and if I run "iwlist wlan0 scanning" from the command line it exits with "Failed to read scan data: Argument list too long." (The devuan wifi thingy seems to be a wrapper around the various command line tools.) The sad part is it drops the EXISTING connection when this happens, presumably because the access point is no longer in the list... even though it's still connected to it? Grumble. (I wasted SO much time blaming the driver before figuring that out, switching wifi off and on, suspending and resuming my laptop to try to jostle it back into working... I should make a toybox iwlist command. Throw it on the todo heap.)

So, about that toysh order of operations issue...

$ x() { echo hello; }; Y=x; $X $Y $Z
hello

I need to resolve the command line arguments in order to know whether this command is a shell function, and the new variable context created for prefix assignments could easily be reused as the function's variable context but only if we DIDN'T assign those variables into existing context (I.E. a bare assignment that's not before a command). Meaning "we are about to run a function" is a useful thing to know before performing variable assignment...

Oh, hang on:

$ abc=def $Z
$ echo $abc
def $ abc=123 > potato $ echo $abc 123

Right, we MUST peform resolution first in order to know IF it's a local variable context, because "arguments are left over" is not a sufficient indicator for whether or not variable assignments are persistent. But the order in which these things happen in bash...

$ abc=xyz > /not/found bash: /not/found: No such file or directory $ echo $abc xyz $ abc=def ${a?b} bash: a: b $ echo $abc xyz

My code really isn't designed to split these hairs exactly where bash does. Yes, this is all order of operations IN ERROR PATHS, and nobody but me seems to test error paths, but still. I was trying to get this RIGHT. Grrr.

$ x() { potato 123; }; alias potato="echo"; x
bash: potato: command not found

Well at least THAT'S sane. (Parser HAS to convert alias at parse time, not at runtime. Otherwise you can't work out line continuations.) But this isn't:

$ x() { echo $_ hello; }; true; x; echo $_ true hello x

The function being run calls into the other context, so the last thing run was the "echo hello" not the x. The x executing is a CALL into the function context, my code would print "x hello\nhello" and it's hard to see how NOT to make it do that without consuming an unlimited amount of stack space for deep function call stacks (bad on NOMMU systems). I made the function call stack a linked list for a REASON...


April 23, 2021

Of course Biden's proposal to return tax rates to where they were in 2018 is half-assed: they need to go back to where they were in 1963. The point isn't to raise revenue (or even control inflation), it's to keep billionaires from dominating all political and economic discourse. And lifetime appointments to the supreme court remain a real problem, but the Boomercrats will never impeach any of them, nor do what FDR did and dilute them.

Remember that thread about emergent properties of group decisionmaking leading to the most boring possible decisions? This thread calls it the ice cream problem.

Sometimes you don't know a horrible thing was happening until there's a proposed fix. Always mixed feelings about those: yay it's being addressed, outrage that it was ever the case...

Following John Rogers (co-creator of Leverage) you find out about so many scams, and if you start thinking about Bernie Madoff and Fox News and the rise of spam email, it's easy to see how the Boomers let the economy turn into a giant mirage. Then again their lead poisoning left them extra-vulnerable to scams on a massive scale, even reaching out to distant lands DEMANDING to be scammed, such as the Foxconn Wisconsin debacle.

You know the old phrase "great artists steal"? It applies to financially comfortable white male artists. The first issue of Batman was literally traced from a Tarzan comic, the setting was fanfic of a film noir detective movie, and Bob Kane outsourced the new creative parts and hogged all the credit. Just imagine a black woman trying to do even half that "just reach out and take success" schtick without already being comfortably atop the dominant cultural hierarchy. It's not just a "white male european" thing, Koji Kondo's music for Nintendo was, ahem, "strongly inspired" to existing songs. Imagine what would happen to a zainichi korean composer doing that...

The fact the criminal justice system "would implode" if every trial went the way of the Chauvin trial is an excellent reason to defund the police, who don't know what to be afraid of.

Billionaires have cornered the market on lumber as part of preventing construction from undoing billionaires' cornering the market on residential housing. Yes that is why rent is going up: billionaires are driving the price up so the 99% has to pay them ever-more money, constantly, forever until the guillotines come out. People are trying to push back, but I am not expecting the end of the Boomers to be without a full-on Damnatio Memoriae dismantling of everything they ever touched. "Rent reform" is not the same thing as returning the stolen money, punishing the guilty, and making a sufficient example of the perpetrators to dissuade many generations to come.

Meanwhile, all this "just-in-time delivery" nonsense has advanced until supply chains for everything are incredibly brittle, leading to shortages and price spices, making market cornering faster and easier. It's the classic efficiency vs resiliency tradeoff (like security vs usability). I actually rooted for the early stages decades ago writing for the motley fool, back when it was still an optimization (and I was more naieve about the downsides). During the recent texas blizzard it hurt my community. Over the years the old saying "premature optimization is the root of all evil" has gradually been turning into "over-optimization is the root of all evil": specialization sacrifices flexibility. In the case of modern supply chains, this has gone way too far in a lot of places and needs unwinding. (Part of the ongoing chip shortage is people realizing just in time delivery ISN'T reliable and trying to amass inventories. Simultaneously. Which turned into the digital version of toilet paper hoarding, which became ticket scalping because capitalism. The fix is suppliers flooding the zone, which takes a while.)

Credentialism is just one more filter billionaires use to lock out the 99%. Unpaid internships, "presentation" in hundreds of dollars of clothing changed daily, buying up all the housing near the jobs, destroying public transit, and finally cracking down on homeless tent camps (and then wondering why they can't hire anybody to cook, clean, or stock shelves in their city anymore). Austin tries to swim upstream against this (and we have the "rich parents paying to send their kids to school, who work part time jobs" labor pool hack of a large university), but the market-cornering strip-miners always come in and screw it up for profit.

As usual, the question seems to be how long holding actions delay mass deployment of guillotines. Taxing the aristocracy into submission isn't how previous monarchies fell, and rich people can afford to game the system full-time. The current strategies for gaming tax code enforcement are already quite elaborate, and intellectual property law is weaponized to suppress criticism. Here's a good thread on the thesis "every billionaire is a policy failure".

Putting cops in schools gets students killed. Lightly paraphrasing: Cop's gun misfires into officer's leg, they blame a 17 year old student and kill him, then call it a "mass shooting," lie to media and refuse to release the body camera footage for days.

Faceboot remains especially terrible, they track hate groups on their platform and intentionally leave them online because that's its business model.


April 22, 2021

I just regression tested mkroot with linux 5.12-rc8 (in part to make sure my recent toysh changes hadn't broken anything obvious in the init script). The two "known broken" architectures are armv7m and microblaze, but a lot more aren't working: armv7l has no net, armv4l doesn't build, m68k hangs, mips64 doesn't build, powerpc64le exited immediately (unable to open initial console), and s390x didn't build. Sigh, I need to reestablish a baseline (under what kernel version did they last all work?) and bisect to see what commit broke each one. (Half the time it's a config change, but I still need to bisect to see WHAT new config symbol is suddenly required. Ah, I left myself a note, last release I tested them all with the 5.9 kernel.)

Poking around I discovered that modern mount understands -o offset= and -o sizelimit= for loop devices, which toybox mount does not. It's very useful to have, and was the main reason I've called losetup directly over the years, so I'd like to support it. But toybox autodetects loop mounts, and does so by the first attempt to mount failing with ENOTBLK and trying again. But the command line options are parsed before then, and we need to peel out the options that WON'T be understood by the filesystem driver (because otherwise they get confused), which means peeling out offset= and sizelimit= BEFORE we know if this is a loopback mount. Unfortunately, the old crufty "autofs" driver has "offset" as one of the options it understands, so if I snip it out unconditionally (whether or not we're doing a loop device mount) that's at least one driver that would be inconvenienced by that.

I should do a FAQ on how to use NFS and SMBFS with toybox mount. I mean I had a patch to make it much cleaner which of course never went upstream because the kernel clique circled the wagons, and in my experience they never really pay attention anymore except for bikeshedding unless you put in the persistent schmoozing to become a member of their clique in good enough social standing to be worth listening to, which I just don't have time for. I don't have the "social capital" with them to have my technical issues listened to. But hey, they got rid of the "code of conflict" so I guess everything's fine now.

Anyway, if you "mount -o offset=$((2048*512)) file.img dir" it should work on a loop device. I can't find any filesystems currently using "sizelimit" except loop.c, and autofs checks "offset" not "offset=" so if I only grab ones assigning a value it shouldn't conflict with that? It can always break in future, but we can burn that bridge when we come to it.


April 21, 2021

That Los Angeles Basic Income pilot seems a lot less praiseworthy when you realize they want to spend $3 billion next year on police. That's a $1000/month basic income for 250,000 people.

A surprising amount of Silicon Valley's ideas aren't new, they're just ways to dodge well-known legal liability and regulation. Just as blockchain automated the function of a Notary Public (minus any sort of "Garbage in Garbage Out" filter), NFTs reinvent pedigree papers... again, with the exact same GIGO problem. People have a bridge to sell you, and have drawn up the FANCIEST documents on full color glossy paper to claim onwership of said bridge. I await the lawsuits.

Nancy Pelosi is 80 years old, and it really shows. Alexandria Occasio-Cortez is profoundly more clueful.

I'm not surprised netflix is stumbling, I uninstalled their Android app after they broke it last month. In theory I could still watch it through the praystation (we haven't cancelled the subscription because Fade still uses it), but I don't. It's a pity, they've got stuff I want to watch, but when I click on an entry in the app I want it to show me what I clicked on with a play button, not give me a status bar at the bottom with no play button. (Double click. Triple clock. Long press. Nothing: no way to get the old fullscreen page for the entry back.) I asked their tech support how to downgrade the app to the version BEFORE they broke it (I did not consent to the change), they said that was impossible, so I uninstalled it. It's been a month, don't really miss it that much? The time I used to spend watching netflix is split between crunchycrunch, hulu, tubetube, tiny bit of prime (most things I want to watch there that I haven't _already_ watched sticks ads in it: I am _never_ going to pay to watch ads), and... just plain watching fewer videos.

Michigan is currently having a covid wave that's filled the hospitals to 100% capacity (and filled up a bunch of "overflow beds" on top), spread by racist GOP loons.

Of course that "Q" nonsense is a russian op. I mean, we knew this, right?

The GOP is flipping out about granting DC statehood, but wyoming has far fewer residents and they're fine keeping that. (They want land to vote, not people. Then rich people buy land and their votes count more.)

Religion remains a wholly owned subsidiary of the GOP, shrinking down to their 27% "crazification factor" core. Almost half of 30 year olds say they have no religion, and 20% of 70 year olds. Pascal's Wager has a pretty obvious answer these days (bowing to the golden idol puts evil old white men in charge, plus Homer Simpson's "What if we chose the wrong religion? Every week we just make god madder and madder").

Today I learned the word "fracklog", which is the count of oil wells that have started drilling but are as yet uncompleted, and thus not producing oil. This represents money oil companies sunk into mining without producing any results yet. The acronym DUC for "Drilling UnCompleted" has also lead to "Dead DUC", for a well that won't be finished because the business case for it went away. Meanwhile, all those oil pipelines everyone was rushing to build are sitting empty, and thus missing debt payments on the financing the companies took on to build them. As one financial analyst said, "It has created some skepticism on the investor base about the sustainability of the sector". And of course oil prices going back up brings US shale pumping back online which lowers prices again, the oil industry is in a no-win scenario these days. The OPEC cartel no longer functions (partly because it's now led by a murderous clown).

The reason black people seldom call the police is when they do the police REGULARLY show up and murder the person who called them. We still need to defund the police. I don't feel like coming up with a long sentence of exactly the right length and linking every word of it (and worrying about whether "a" and "of" should be their own link or grouped with an adjacent word) today, so: link link link link link link link link link link link link link link link link link link link link link link link link link link link link link link link link link link link link link. And no, "we gave you a crumb, grovel before our mercy and leave us alone forevermore or we shall smite your uppity ingratitude" is not the appropriate response here: a murderer went to jail after his institution lied to protect him. This only happened because of a solid year of protest that included setting the police station on fire. Derek Male Chauvanist Pig was one of literally thousands of perpetrators, and new murders by police happen daily. Police who murder civilians listing themselves as the real victim on the incident report is an old police trick. And "murdering people" isn't REMOTELY the only bad thing police do to the populace they subjugate, it's just the most obvious. Well, that and the civil forfeiture.

An example of how downticket races matter.

A good article on the thesis that Capitalism is broken.


April 20, 2021

The nearest vaccine appointment at HEB is now 9 miles away instead of 80, which is progress, but I'm still waiting for J&J at the one near me. Try again next week... Ooh, Los Angeles is proposing a Basic Income Pilot, $1000/month for 2000 families for a year. And another part of Los Angeles is doing a 500 family pilot program with money diverted from the police budget. Meanwhile, the scottish greens are proposing universal basic income. And Arthur C. Clarke said "The goal of the future is full unemployment, so we can play" back in 1969. Speaking of diverting money from police budgets, the cop who killed George Floyd was found guilty on all counts (nature is healing). Meanwhile, the scottish greens are proposing universal basic income. And Arthur C. Clarke said "The goal of the future is full unemployment, so we can play" back in 1969.)

Elliott just sent me a large patch to toybox hexedit that A) improves several things, B) makes the display significantly uglier. I've applied it, but am unhappy with it for bikeshedding reasons.

Hmmm, I've got a fairly obvious missing design thingy in toybox, and should probably figure out how to deal with it: struct sh_arg has a pointer array and a count, and there's functions to add entries to that which realloc() the array part (with a stride of 32 entries) and keep it NULL terminated each time, I.E. "arg->v[arg->c] = 0;". It's not hard to do but it's convenient to have the function that does it, and means I'm not repeating the check for 32 in multiple places (if things disagree about the size of the stride it would potentially write off the end of the allocated space).

But the thing is, the sh_arg stuff works with char * as the data type, and other stuff doesn't necessarily. The variable plumbing borrows the sh_arg plumbing (making temporary sh_arg structs to manipulate them) but otherwise stores the char ** and the long len separately. And now I've got the function array, which I want to have as an array (faster to search than a linked list, maybe even sort it and binary search it) but it's NOT an array of char *, it's an array of struct sh_function *. And while I _can_ abuse sh_arg again and typecast... it's gratuitously ugly?

There's a similar problem with the doubly linked list plumbing. The struct for that has the payload as a char *, because I first wrote it for patch.c which needed that. But lots of other stuff wants a different payload, an I've made dlist_add_nomalloc() and typecast to void * a lot, and I keep thinking I should do a pass making dlist_add() be the nomalloc one and have a different name for the one that mallocs a struct dlist? Also, if struct dlist is _just_ the next and prev pointers, then you could EMBED it in other structs as the first member, and the types get potentially less awkward all around? (Pointer to first element of a struct is equal to the pointer to the struct, guaranteed to work in C99.)

Sigh: problem at hand. Do I genericize sh_arg to use void *, or do I do another wrapper pass like I did for variables? It's a question of what's less ugly, which is REALLY a question of what the common case is. And "string" is a pretty common case...


April 19, 2021

Biden keeps comparing himself to FDR, but FDR said "I welcome their hatred" and Biden keeps begging for republican approval he is never going to get. If he actually committed to progressive policies, they turn out to get widespread support from unexpected places. Also, what "every accusation a confession" really means is people believe their opponents are willing to do what they themselves are willing to do.

Austin had a mass shooting yesterday, in the Arboretum (about 7 miles away). The police identified a black man as the suspect, and I did not believe them, until I heard he was a former sheriff's detective and I went "oh, a cop did it, that sounds plausible". I would appear to be developing some distinct biases in this area...

Tesla continues to set back the cause of self driving, but Musk is also bad at other stuff too.

Please stop connecting random things to the internet. It does not help.


April 18, 2021

Whaddaya know, when the police don't show up, peaceful protest is peaceful.

As of today, 50% of US adults has gotten vaccinated (at least the first dose). The percent saying they would get vaccinated was 67% in january, and is 75% now. (Given that 27% of the population is crazy, that's digging 2% _into_ the wingnuts who think drinking water is communist.)

Early voting opens tomorrow in Austin; they took away the voting place in Fiesta so the closest place to vote is a mile away now. The Austin boomercrats texted me to that they only care about the first three propositions (Prop B is GOP nimbyism targeting the homeless so of course everybody who isn't outright evil is against it; the Boomercrats care about A and C which I had no strong opinion on, and didn't mention E because they care more about keeping the job more than doing the job. Nuts to their white mice.)

I think the cpio thing is resolved now. There's more I could do, but it's not strictly required. (Got the Android build unblocked, moving on...)

Dear bash, what counts as a valid function name? And what processing is done on that name?

$ function ab=cd if true; then echo hello; fi
$ "ab=cd"
hello
$ function ab^cd if true; then echo hello; fi
$ ab^cd
hello
$ function ab$cd if true; then echo hello; fi
bash: `ab$cd': not a valid identifier
$ function "abcd" if true; then echo hello; fi
bash: `"abcd"': not a valid identifier
$ function function if true; then echo hello; fi
$ "function"
hello
$ abc=def function
hello
$ function ab*cd if true; then echo hello; fi
$ "ab*cd"
hello
$ function ab!cd if true; then echo hello; fi
function abcd www if true; then echo hello; fi
bash: syntax error near unexpected token `www'
$ function ab\!cd if true; then echo hello; fi
bash: `ab\!cd': not a valid identifier
$ function ~landley if true; then echo hello; fi
$ "~landley"
hello
$ function a>b if true; then echo hello; fi
bash: syntax error near unexpected token `>'

Seriously? The man page DOES NOT DOCUMENT THESE RULES. (Wildcards don't execute but the !history thing does?) At least this:

$ function one if true; then echo hello; fi > potato
$ ls potato
ls: cannot access 'potato': No such file or directory
$ one
$ ls potato
potato

Is documented in the man page. Of course the same section of man page says that if you use the function keyword without parentheses then the { braces } are required which is CLEARLY NOT THE CASE...

I need to add so many tests to the test suite. Ok, a function name can't have a $, backslash, single or double quotes in it... Um:

$ function `echo hello` if true; the echo hello; fi
bash: syntax error near unexpected token `fi'
$ function `echo hello` if true; then echo hello; fi
bash: ``echo hello`': not a valid identifier

I do not understand bash's parsing order of operations here. Why would you check for a valid function name AFTER syntax checking the compound statement?

Hmmm, trailing redirects cling to the function, but leading variable definitions don't (specifically, they're not allowed):

$ ab=cde function hello if true; then echo $ab; fi
bash: syntax error near unexpected token `then'

This does _not_ smell like a design, it smells like an ad-hoc accumulation over a number of years. Which is the worst kind of thing to try to be compatible with: when the implementation IS the spec every weird behavioral hiccup is "part of the spec", and I have to figure out what subset I care about reproducing and testing.


April 17, 2021

I'm not the first to point out how capitalism is putting all the sites that post facts behind paywalls, but the propaganda sites are all free. Capitalism is no longer the solution, it has become the problem.

Russia's GOP is in full throated party of NO mode in the House right now, essentially reinventing the fillibuster by slowing every bill as much as possible forcing full procedure for each vote to rename a post office. And yet we still can't turn the Senate fillibuster back into a talking fillibuster (where you have to physically BE there to block it) because Joe Manchin is a republican.

Raising the top federal tax rate back above 90% like it was in 1963 might be sufficient to get us through the end of the Boomers, but I still lobby for federal guillotines for the capital offense of being a billionaire. Mackenzie Scott is the only billionaire with a soul, and the way you can tell is how hard she's working to STOP being a billionaire (giving away a billion a month). Remember, the only reason Dolly Parton isn't a billionaire is she keeps about 0.8 billion and gives the extra away on a regular basis.

For all the police posturing, they're less likely to die on the job than garbage collectors, bartenders, taxi drivers, roofers, electricians, landscapers, mechanics, fishermen, miners, or loggers. Police are not even in the top ten most dangerous civilian professions. Most police in twenty countries don't even carry guns, and it turns out when they don't bring them they don't NEED them.

Another reason to defund the police (apart from the constant lying) is they're so insistent on funding themselves. The amount the USA spends on police would make it the third largest military in the world. (The UK's entire military budget is 40% of what the USA spends on police, and THEY get aircraft carriers and nuclear weapons for it.) Of course old white men want full fascism, and progress is only likely to happen in the usual way. This is why the proper police budget is "zero". The racist geezers want it to be "infinite". If you lobby for half-measures, your position will be eroded to meaninglessness. (And once again, The Onion is on it.)


April 16, 2021

Good news: the chance of a noticeable covid infection among the fully vaccinated is slightly under one in ten thousand. (That's "person has any symptoms of illness", not "we drew blood and took a PCR test and yes there's some virus there" which is where the 60-ish precent efficacy figures from the clinical trials come in: enough virus to be detectable in a laboratory setting with specialized equipment. Which is NOT the same as getting sick or having any real chance of spreading it.) Meanwhile, Pfizer's CEO announced his desire to keep selling vaccine endlessly, customers should take a third dose and then a fourth, kaching. (It probably should become part of the standard flu shot regime, but the Pfizer CEO is 100% saying it because money.)

Oh look, mailing everybody in the country $1400 each boosted the economy, who'da thunk? (Now imagine what would happen if you sent out $1000 _every_ month, which is easy enough to pay for at the federal level.)

On toybox, got distracted fixing a cpio issue the android guys hit where the kernel lets you concatenate multiple cpio files and the gnu/dammit cpio doesn't, and they had a workaround with a shell for loop that didn't work with any other cpio implementation except the gnu/dammit one. Longish ongoing discussion with them to figure out what constitutes a proper fix. (Not hard to implement, hard to figure out what TO implement.)

Now I'm back to squinting at the toysh code to figure out how/where to add function definition support. In order to make the lifetime work I need to translate the pipeline chunk out of line into its own reference counted structure during parsing. I think I know what the data structure should look like but the parsing code is a bit awkward. Much re-reading of my own stuff to get it properly loaded back into my head. (Why did I do that bit again?)

I just got stopped by the university police. I got up from the table and paced the length of the porch of the geology building a couple times while trying to work out the design for the shell function lifetime stuff, and a couple minutes later two police cars pulled up and three uniformed officers (with, of course, guns) got out to ask questions. Somebody inside the building (at 3am) thought I might be trying to "get inside" when I'd just read a couple signs about social distancing on the window while trying to figure out the pipeline transplant lifetime rules handing off data between the parse-time structure, the runtime call stack, and the list of defined functions (which should probably be a sorted array of functions instead of a linked list).

Of course as a middle class white male it wasn't a problem for me: about 8 minutes of being polite and compliant to roving bureaucrats (and yes, handing over my driver's license and waiting for them to "run" it) and they left me alone again. They didn't even complain I'm using electricity from a university outlet, which would have been a legitimate gripe. Alumni or not, I do consider myself a guest here...

But I'm pretty sure if I was black or female, there's no WAY I could get away with being in a public place late at night in the USA. The culture here is amazingly toxic. Tokyo has advantages and disadvantages compared to the USA, but travel certainly points out the "wow, that's very different; different is a thing that can be" blind spots. There I am Gaijin. Here I'm Good Ole Boy. I want to dismantle a system I clearly benefit from.

(Defund the police doesn't mean you stop spending the money. If groundskeepers had pulled up to ask me questions, it's a different vibe than guys with guns. I've emailed facilities here multiple times about the lights that are still out, and the snapping noise whatever circuit that's shorting out makes every time it rains, and the fact the timer the lights are on doesn't switch them on until midnight and hasn't for YEARS. This table has had the same leaves under it for 6 months now, it's NEVER swept. THOSE guys are understaffed, but we've got multiple guys with guns paid to drive around all night? Reallocate that budget please. Hire the same people even, I'm sure they can sweep.)

Anyway, kinda killed the mood. Headed home about half an hour later.


April 15, 2021

A reminder that every year Intuint and H&R block spend millions keeping taxes hard to file, because they make money off of you confirming what the government already knows.

Japan very briefly had a mascot to promote its decision to release radioactive water from fukushima into the ocean. I have questions.

Boomercrats gonna boom, just like Evangelicals gonna evil. (We have junior Boomercrats in training, the dogpile brigades, but 27% of any population is crazy. Sadly, they're not all on the other side.)

Richard Stallman's supporters remain at about the same level as always But then, so does microsoft.

Another day, another example of how AI is constructed entirely out of biases.

Defund the police. Here's another sentence to consume a bunch more links on that topic. Even dinky little university police departments get pulled in and contaminated. (My wife, who sent me that last link and is getting a doctorate at the University of Minnesota, said of it "I'm thinking grimly of World War 1. It made sense to sign a treaty at the time...") Also, the saying is "one bad apple spoils the barrel", yet they keep talking about "bad apples" as an EXCUSE. (P.S. Du Jour.)

And yes it's "defund", not training. There is no productive way to pour sugar on a fire ant's nest, it will only EVER make the problem worse. The daily show had an excellent interview with the black woman who popularized the phrase "defund the police" last year.

Training on protecting yourself from police should be part of elementary school curriculums going forward. Of course the LRAD was developed for the military circa 2000 and then used by republicans against protestors at the 2004 GOP convention, against dakota access pipeline protestors, and against black lives matter protestors. The GOP are fascists ruling by force and treachery, the giant "defense" budget weaponized against US citizens by channels such as the 1033 program.

Taxes are a weak alternative to guillotines, and sure -- do both, but the fundamental problem is that capitalism has run its course and we need a new civic religion to replace it. (The pyramids weren't built by capitalism. The USA didn't go to the moon via capitalism. The great wall of china was not built by capitalism. Winning World War II involved a _suspension_ of capitalism. It's just _one_ way to organize human activity.)

For years I've said "dying business models explode into a cloud of intellectual property litigation." On a small scale, you get Oratroll (which lost the API copyright case against Google, if not as decisively as the rest of us would have liked, and oh boy is it a sore loser). When the dot-com boom disrupted the entertainment industry a quarter century ago, the dinosaurs threatened by streaming went for regulatory capture by passing the digital millennium copyright act with its anti-circumvention provisions. The fossil fuel industry undergoing the same sort of disruption from solar/wind/batteries went for regulatory capture in 2016 by making the CEO of Exxon Trump's first secretary of state (and making their first act in office an attempt to push through the keystone oil pipeline), but it's also got state governments too, being amazingly stupid. (Basically the whole GOP is a collection of drowning dinosaurs climbing on top of each other.)

The backpedaling in the "vaccines and clots!" thing has begun, because well duh.


April 14, 2021

Today's quote: "We beat polio with a vaccine with lower efficacy than J&J."

One of the other engineers lost patience with my bootloader flailing and already upgraded the old codebase to add the new features. (Sigh: "don't ask questions, post errors" still works. Except I was using it as a learning experience and excuse to write documentation, and might still do so but it's off the critical path for now and I'm on to the next thing at $DAYJOB because somebody else did the todo items motivating it. No, I don't know when/if the github repository might be updated with the new code, not my area.) So I guess I'm back to posting about toybox.

The toysh test program runs to completion on bash, but hasn't run to completion on toysh in a while because lots of the tests use features that toysh hasn't implemented yet. The biggest being shell functions, without which a lot of things are hard to test.

I've been going through and commenting out tests that don't pass because of missing features, and finding both regressions and stuff that NEVER worked, but which I thought did. One such thing is the $IFS corner cases with collating runs of whitespace. (It gets leading whitespace right but doesn't get trailing whitespace right.) I went through bisecting to try to find where I'd introduced this regression (I thought I had it working!) and it turns out... no, it's been broken basically forever. Huh. The fix for it is small, although tracking down where to put it and wrapping my head back around that code was time/energy consuming.

And now I'm wondering how much more of the test suite to try to chase, vs going back and implementing more of the missing stuff. I'm pretty close to having functions in, except that the next thing I need to do is actual function declaration/definition, which means I have to work out what the lifetime rules are supposed to be. (It's a design issue; the parsed pipeline data gets handed off, but still lives its original context, and two references to the same thing means reference counting. I should break down and just implement that...)


April 13, 2021

Sigh. Talk about transparent excuses: 6.8 million J&J doses were administered, and they had 6 cases of alien abduction, so they're pausing vaccine rollout. In reality, they had to discard ~15 million doses so there's a shortage of J&J vaccine for the next 2 weeks, and they're getting yelled at, so they went "no, we're INTENTIONALLY not giving it to you because... um, reasons!" Seriously, blood clots are a thing that happen, and even if this _is_ causing more it's VANISHINGLY RARE. 1 in 500,000 people are struck by lightning each year so you expect 14 LIGHTNING STRIKES in a population of 7 million. Ok, 3 months is 1/4 of a year, so 7 million times 2 because "per half million", then divided by 4 for the 1/4 year, and then halved again if you assume a smooth slope from zero at new year's to 7 million now (area under a right triangle), so it's like 2 lighting strikes in that population over that period. But still, is that a vaccine side effect? Answer, yes it officially is. (It happened during the clinical trials, so they had to list it!) Seriously, stop blaming one of the most common EXISTING causes of death on "and they were wearing SOCKS when it happened, blame the socks".

Prince Philip, who is dead, was a terrible person. Sarah Taber did another fascinating thread about the politics of wealthy landowners. The construction of the interstate highway system was racist in multiple ways. A reminder that nuclear reactors are not the answer to fossil fuels. They're just another kind of fossil fuel. There are sooo many reasons I don't have a faceboot account. Guillotine the billionaires, who got rich by stealing from everybody else.

Minnesota is declaring war against its own citizens, which would be hilarious keystone-cop incompetence if it wasn't simultaneously terrifying and very, very sad. But this is just one more of the never ending reasons why we need to defund the police. So many reasons big and small.

The GOP's popular vote is ever-shrinking, but their voter suppression game is ever-expanding. My rule of thumb is "the side the GOP is on is the wrong side", because they're never NOT lying anymore, but sometimes you need a long analysis thread to unwrap the spin and figure out what exactly they're lying about. Plus of course the endless racism , and claiming victimization even while dogpiling.


April 12, 2021

I am continually impressed by how WELL the steak-umm twitter feed has been doing at... being the steak-umm twitter feed. This is not a task I believed COULD be done well, it's not one I'm inherently interested in seeing done... but they're just so GOOD at it. (Specifically, Nathan Allebach is good at it.) Meanwhile, I remain deeply unimpressed by the constant stream of marketing emails from people who want to "add a resource to" my website, and then give a URL to my blog page from 2008 (which is now 13 years ago).

Alas, Austin did not get any J&J doses this week, just Moderna and Pfizer. (I have a problem with needles stemming from childhood trauma, so the one dose version is VASTLY preferable to the two dose version.) But then due to the manufacturing mixup that discarded 10+ million doses, the J&J vaccine supply is constrained everywhere for the next couple weeks. Starting on the 19th, HEB is supposed to start participating in vaccine distribution a lot more (hopefully including the pharmacy 2 blocks from me), and if the J&J supply picks up again the week of May 2nd that's probably when I can expect it?

I'm still banging on the j-core bootloader. We've already got a working bootloader but it's a bit of a mess (too many cooks over the years), its configuration mechanism is an #ifdef staircase, and it's brittle and hard to improve and it's basically gotten to the point where writing a new one from scratch is probably easier. (This isn't a secret, we published it as part of the bitstream build.)

I wasn't poking at it before because I strongly believe building a bitstream should be able to use the same toolchain we build the linux kernel with, but the boot rom we have now needs the ELF toolchain instead. Meanwhile Jeff says that bare metal guys who don't do Linux want an arduino-style bare metal ELF toolchain, which can't require a "-no-fdpic" argument and doesn't add underscores to symbol names (meaning it has an incompatible libgcc.a). I just don't want to have TWO toolchains, one of which is currently ONLY used to build the bootloader and nothing else.

We were at an impasse on this for a while, but over the weekend I had a phone call with Jeff where we establishd that if I can make the new one build with BOTH toolchains (the bare metal ELF toolchain and the fdpic one that builds the Linux kernel), that would be acceptable and he might merge the result.

Jeff is also concerned that if I post to the j-core mailing list about my learning curve coming up to speed on "turning the hello world kernel into a boot ROM", it would make the company look bad to investors. (We collectively know this stuff, we can't write about NOT knowing this stuff!) Except I personally do NOT know this stuff, and the people who DO know this stuff are so busy with other things that "write a better bootloader" has been a vague todo item for a year and a half now but nobody's DONE it. (We already have a bootloader that works, for a certain definition of "works", so they're working on higher priority parts of the todo list.)

Me, I've never been afraid to look stupid. It's sort of a constant, really. The background radiation of my life. I'm _persistent_, not necessarily smart or talented. Jack of all trades who has established some deep domain expertise in various weird niches that don't necessarily connect up, but mostly grinds away at stuff and does a lot of looking things up and head scratching while the real experts are busy elsewhere. Yes, I am reinventing a wheel and reverse engineering our own code, but I never claimed to be a domain expert here.

Anyway, my compromise is to blog about it on landley.net, but not post it to the mailing list on j-core.org.

So: the hello world kernel depends on the bootloader having already done LOTS OF STUFF for us. For one thing, DRAM init: it's mapped at 0x10000000 and we can't use that memory until we initialize the DRAM controller (you have to switch them on and tell them what types of chips they're refreshing). The j2 SOC has 32k of SRAM mapped at 0x00000000 and a bootloader needs to use that instead.

Second problem: a boot rom is not ELF loaded with relocations, we need to come out of power on into the ROM and call our start address. The j-core power on stuff is compatible with sh2, and that says in section 2.2.4 "initial values of registers" that at power on VBR is zeroed (the Vector Base Register, I.E. memory address of the start of the interrupt table), PC and R15 (the stack pointer) are loaded from VBR, and SR (the status register) set to 0xf (sort of, the bottom 4 bits are 1 and lots of the others are zeroed but the unused ones are "undefined" so the COULD be one, but we don't care; it's a future expansion trick that if we add bits that should start at 1, they can start at 1 without violating this spec). The rest of the registers are undefined, and interrupts start disabled.

The vector table is an array of 32 bit pointers, with entry 0 being the power on interrupt (so where to start executing code), entry 1 is what to set the stack pointer to when calling that interrupt (but stack grows DOWN so it's stack+sizeof(stack)-4), and then entry 2 is warm start address and entry 3 is warm start's stack. Higher entries shouldn't matter while interrupts are disabled, and we can move VBR somewhere else before enabling them.

Warm start isn't entirely implemented in the FPGA version of j2 because we haven't got a ROM in the FPGA (too expensive, it would eat thousands of LUTs). Instead xilinx FPGA bitstream format has a way of initializing SRAM to known values, so loading our bitstream initializes that 32k of SRAM starting at address zero with our boot ROM contents. The problem is that SRAM gets reused for other stuff when Linux comes up, so when you do a warm start the boot rom isn't there anymore (and xilinx doesn't give us a way to re-load it without wasting a lot of LUTs; it comes up once when the bitstream loads and that's it). In ASIC we'd have a real ROM, but in FPGA it's not worth the LUT budget to implement our own initialization machinery.

So I PROBABLY only need 2 entries in this vector table: starting the ROM with 0x00000008 and 0x00007ffc (code entry point right after the 2-entry vector table, and stack starting at the end of the SRAM; keep in mind it pushes and pops 32 bit registers so moves with 4 byte granularity, and stack grows DOWN so starts pointing to the last usable slot). But the old boot ROM had 4 entries (warm start as well as cold start), and wasting 8 bytes of 32k isn't a huge deal... maybe there was a reason for it? (Does the boot process call warm start at some point? Ah: I asked and it was so the same code could work in actual ASIC, where the ROM stays mapped and thus warm boot jumps back into it. None of this is designed JUST to work in FPGA, it's always silicon-ready when we have the budget to make a chip.)

Getting those 8 (or 16) bytes at the start requires a little linker magic. The text, rodata, data, and bss segments naturally flow in that order (in static binaries anyway), which is why the hello world kernel's compiler command line just has to set the starting address of "text". This needs a segment before "text", and linker script magic to stuff it in the right spot. Linux is doing similar linker magic when it sticks _init annotations on things, which are defined in include/linux/init.h as:

#define __initdata      __section(".init.data")
#define __initconst     __section(".init.rodata")
#define __exitdata      __section(".exit.data")

And __section() is defined in include/linux/compiler_attributes.h as "__attribute__((__section__(section)))". So in THEORY what I need to do is something like:

void *vt[] __attribute__((__section__(".vbr"))) = {_start, (void *)0x7ffc};

And some linker script to tell it to stick that section first in the binary. The problem is, the gcc command line argument "-Wl,-Ttext-segment=0" passes -Ttext-segment=0 to ld which moves .text, but if I change that in any way suddenly ld thinks the -T argument is a FILE it has to load, instead of using the data fed in on the command line AS the linker script. And this of course appears totally undocumented because gnu... (I really don't want to have to read the ld source code to figure out what command line options it understands. Gnu source code is horrific.)

Ah. I can't find it in the CURRENT documentation, but I can find it in old documentation, and it's that -T understands the special magic names "bss", "data", and "text" (but not rodata?). And I guess appending -section is ignored because it's matching them as prefixes or something? No idea. But in any case, if I strip the section indicator back OFF and put the data segment at the start, this lets me compile it:

sh2eb-linux-muslfdpic-gcc -Os -nostartfiles -nostdlib -mno-fdpic -Wl,-Tdata=0 -Wl,-Ttext=0x10 hello.c -o vmlinux

And I guess an asic-friendly bootloader would define both cold and warm start vectors, looking like:

void *vbt[] = {_start, (void *)0x7ffc, _start, (void *)0x7ffc};

It's curently the only thing in the data segment so has to come first... and now the memory contents are correct but the FILE has bloated by 64k because it's decided it needs a load alignment of 0x10000 which it DIDN'T NEED LAST TIME and it just INVENTED and I really dislike this tool. (Seriously? 64k? Everything uses 4k pages, where did you get jumbo pages from here? Why did the Linux developers use ANYTHING from the gnu project? Tecnical debt is what that is. They weaned themselves off the minix filesystem but not off the gnu compiler, and were crazy enough to let Ulrich Drepper switch them from their own libc5 to glibc because he'd sprayed it down with thread locking back when Java fundamentally could not run without threads because Sun had invented threads to overcome their terrible process switching performance and were SO PROUD OF IT that they never added poll/select bindings to Java... Sigh.)

And unfortunately if I do "-Wl,T<(echo thing thing thing)" as the argument (which doesn't work in toysh because <() is processed as a redirect, not a variable expansion; I should fix that now that I have an instance of /dev/fd/3 expanding into the MIDDLE of something actually being useful), the echo gets really long because there's all sorts of MEMORY boilerplate that suddenly has to be specified. Hmmm. Ugly.


April 11, 2021

How about a day of mostly good news: Solar is eating oil's lunch but Wind is eating its dessert. even Japan (with a power strategy of all methane all the time) is getting in on it. Sarah Taber is still doing excellent threads about random agriculture, environmental, and economic topics.

Even before robo-taxis become commonplace (app-summonable self driving car subscription services, where the Google Maps button adds "go" next to "directions" and when pressed you get a countdown in seconds until vehicle arrives at your GPS location to take you to the destination, for a flat rate monthly fee), Japan is having success with car subscription services. (As fossil fuel cars get more expensive, even the old the old "car2go" model is making more sense every month.)

This is a great article about BS jobs but walks right past the obvious observation that the "sense of worth" BS jobs erode is basically cultivating "impostor syndrome". If you have a BS job, you ARE an impostor -- that's the job -- and the feeling that you're just faking it and not really doing anything (because you aren't: that's the job) inevitably builds up into full blown impostor syndrome over time. Some people are better at coping with that than others, but you can't escape it when your job IS meaningless and your work DOESN'T matter, and there is no way to do it "right" because there's nothing to do right. (It's still possible to have impostor syndrome while doing real meaningful work, but when "how am I getting paid for this" is an inescapable question, it's hard NOT to have it.) Another reason BS jobs are so stressful is they follow you home: how do you know when you're DONE doing nothing? If you accomplished nothing today, how do you justify going home? Not that putting in overtime helps: it shows dedication, but never accomplishment if there's nothing to accomplish. It's a performative hairshirt to keep anxiety at bay, you've never done ENOUGH but can at least say you "worked" SO MUCH and tried SO HARD you weren't exactly slacking. Floundering, yes...

Austin's upcoming election gives us the opportunity to vote AGAINST republican nimbyism (Proposition B criminalizes sitting down), and to vote FOR ranked choice voting (Prop E). The others seem less important or mixed bags. Prop D lining up the mayoral election to capture presidential election voter turnout... more turnout is good but they're clearly doing it to trim 2 years off the current (term limited) mayor's term. Prop H is nice if likely irrelevant(?)? The "strong mayor" Prop F thing smells like a trap. And is Prop A proposed by the firefighters or by the city? (Does the union WANT it, or is it an anti-union thing? Not enough info.)

The story of Inga and Robert Smallbones didn't get a movie like Schindler's List, but good people rose to the occasion.

Huh. The texas department of transportation has a plan to screw up I-35 by digging a deep trench that can fill with floodwater every time it rains. Have they NOT noticed Austin has a monsoon season now? Also, the overpass on 43rd street (between HEB and Fiesta) has a bat colony living under the bridge, aren't they protected? (WHY do they want to tear the elevated section down? You already went and built the thing, it's not like the new plan provides a significatly different AMOUNT of road space, you're just changing where you put it.)

The Onion appears to have its groove back.


April 10, 2021

Updated the title of the blog page to say 2021. Only 4 months into the year.

I don't blog about $DAYJOB as much as I do about toybox because I'm not always sure what I'm allowed to publicly say. Even when we're releasing everything as open source, they want to control WHEN it happens. Jeff has a strict policy of making sure nobody can contribute to anything we're doing, because they only see it when it's killed and dried and pressed and polished into something nobody would want to change in any way, and is thus completely uninteresting for anything but rehydrate-and-eat deployment. Otherwise he thinks we look bad (unprofessional?). This may not be a fair assessment of the policy, but when I get told not to do stuff a couple times without understanding what was wrong, I back off to the next continent. If I dunno what I did wrong but it's important I not do it again, I stop doing it.

But my current banging is between two bits of open source, so it's probably ok to talk about? (It's not product stuff, it's infrastructure stuff which we _already_ open sourced.)

The reason Rich says he isn't using my mkroot script is it doesn't do incremental builds. The initramfs image doesn't take that long to build, but the kernel build takes a long time and you have to rebuild the kernel every time you update a static initramfs. The problem with leaving half-built kernel source lying around is you need a copy for every single architecture you're building (mkroot targets a bunch). To avoid using 3 gigabytes of space each time (and writing and deleting 3 gigabytes of bandwidth to the ssd each build) mkroot uses the cp -s trick, but if "git update" ran on the kernel source since last time the cp -s needs to be redone. (I suppose I could do a find for broken symlinks and then cp -ns to create new symlinks but leave existing ones alone. Does make use the timestamp on the _symlink_ or the timestamp on the file it points to? Hmmm...) But the easy way to fix it is to NOT have to rebuild the kernel, and the easiest way to that is to not statically link the cpio into the kernel.

So the first thing to try is getting the j-core bootloader to load an external cpio.gz from the FAT filesystem where the vmlinux currently lives. Our boot ROM has plumbing to load as many files as we like (and can already load a replacement device tree and plug it into the kernel), but how do I tell an arch/sh kernel where to find the external initramfs image? Let's dig into the code...

In arch/sh/kernel/setup.c function check_for_initrd() wants LOADER_TYPE, INITRD_START, and INITRD_SIZE to be nonzero, and INITRD_START to be page aligned. If so, it loads the external initrd pointed to by start/size. The units of both start and size are bytes, but INITRD_START is a byte offset from MEMORY_START, which configs/j2_defconfig sets to "CONFIG_MEMORY_START=0x10000000".

Those macros come from arch/sh/include/asm/setup.h which has:

#define PARAM   ((unsigned char *)empty_zero_page)
#define LOADER_TYPE (*(unsigned long *) (PARAM+0x00c))
#define INITRD_START (*(unsigned long *) (PARAM+0x010))
#define INITRD_SIZE (*(unsigned long *) (PARAM+0x014))

And that (somewhat inappropriately named) table comes from arch/sh/kernel/head_32.S:

  .section        .empty_zero_page, "aw"
ENTRY(empty_zero_page)
  .long   1             /* MOUNT_ROOT_RDONLY */
  .long   0             /* RAMDISK_FLAGS */
  .long   0x0200        /* ORIG_ROOT_DEV */
  .long   1             /* LOADER_TYPE */
  .long   0x00000000    /* INITRD_START */
  .long   0x00000000    /* INITRD_SIZE */

So in theory the boot ROM just needs to find the ELF section empty_zero_page and set "empty_zero_page[4] = offset;" and "empty_zero_page[5] = length;"

The complication is that our stuff is using device tree, and I dunno if this codepath still applies or if we have to patch an external initrd location into device tree? So I asked Rich (who is both the arch/sh maintainer and the developer who added device tree support), and he said he didn't modify this mechanism and it should still work: the initramfs load is layered and looks like it has at least THREE places it tries to find it. Rich says:

> init/initramfs.c:populate_rootfs calls unpack_to_rootfs
> for both the (builtin) __initramfs_start and the (param) initrd_start.
> So you should be able to test just adding an external parameter one
>l that extracts a file into / to see that it worked.

So device tree uses the command line parameter path. (Dunno if it replaces it or is just an alternate way to fill it out? Either way, irrelevant here. If the mechanism gets triggered, the init/initramfs.c plumbing is generic between archtectures. Just needs a size and a length. And, inexplicably, for CONFIG_BLK_DEV_RAM to be enabled on a kernel that might not otherwise have the block layer compiled in because initramfs doesn't need it.)

The next question is how to modify the existing boot ROM to load a second file from fat into memory somewhere and set the start/length here to point to it: the ROM code we've got wants the magic ELF toolchain, and I need to rebuild the bitstream which takes forever and I'm not 100% sure the tools are still set up right on my laptop. (I can ssh into a build machine to do it, but really prefer not to?)

I suppose I can build a "hello world" kernel to act as a stage 2 bootloader, loading the real kernel with initramfs. I just haven't built the elm-chan fatfs and our elf loader myself yet, nor gotten it to talk to the sd card without a driver. (Lots of stuff to rip out of the other bootloader to make this work. Probably worth doing anyway, but if I start down that road I'm _going_ to make a full replacement ROM with interrupt vector table setup and DRAM init and everything, and that's a political fight with Jeff I don't want to have right now.)

This is already its own ELF section in the vmlinux:

[Nr] Name              Type        Addr     Off    Size   ES Flg Lk Inf Al
[ 1] .empty_zero_page  PROGBITS    10001000 001000 001000 00  WA  0   0  4

Our ELF loader needs to load the cpio.gz into memory, then:

unsigned *rd = &empty_zero_page;
rd[4] = start_offset; // in bytes, physical address minus 0x10000000
rd[5] = len;          // in bytes

And in theory it should just work?

Another approach is that since our bootloader is loading an ELF vmlinux (not a flat binary bzImage), maybe I could replace the cpio.gz with objcopy? I.E. replace the static initramfs THAT way and avoid rebuilding the kernel each time? I dug into trying to replace the static initramfs in a bzImage back in 2006 and all the addresses had already been resolved, but the point of ELF is they haven't yet. (Not all of them, anyway.)

Digging into that initramfs loader path, init/initramfs.c is doing:

extern char __initramfs_start[];
extern unsigned long __initramfs_size;
...
static void __init populate_initrd_image(char *err)
{
...
        unpack_to_rootfs(__initramfs_start, __initramfs_size);

Which comes from usr/initramfs_data.S resulting in the ELF entries (via readelf -a):

Symbol table '.symtab' contains 22833 entries:
  Num:    Value  Size Type    Bind   Vis      Ndx Name
  185: 00000000     0 FILE    LOCAL  DEFAULT  ABS usr/initramfs_data.o
  186: 104416dc     0 NOTYPE  LOCAL  DEFAULT   11 __irf_start
  187: 104c5e74     0 NOTYPE  LOCAL  DEFAULT   11 __irf_end
12370: 104416dc     0 NOTYPE  GLOBAL DEFAULT   11 __initramfs_start
19234: 104c5e78     0 NOTYPE  GLOBAL DEFAULT   11 __initramfs_size

But none of those have a size, so I'm not entirely sure how to strip them out of the binary with objcopy and replace them? (How do I chop out NOTYPE ranges with objcopy?) It SAYS there's a section init.ramfs but it's not showing up in readelf?

The problem is that initramfs_data.S uses .incbin which I am not familiar with. The assembly file contains the useless explanatory comment "Using .incbin has the advantage over ld that the correct flags are set in the ELF header, as required by certain architectures." WHICH flags? WHICH architectures? What was the symptom you saw that prompted this change? Crickets chirp...

I tried grepping for other occurrences of 104416dc but in addition to the above 2 it only brought up:

12913: 104416dc     0 NOTYPE  GLOBAL DEFAULT   11 __initcall_end
17063: 104416dc     0 NOTYPE  GLOBAL DEFAULT   11 __con_initcall_start
18857: 104416dc     0 NOTYPE  GLOBAL DEFAULT   11 __con_initcall_end

None of them have a size either. I guess I can read the 4 byte value at _initramfs_size and use that as the size of _initramfs_start but the thing is the _section_ is one big blob:

[11] .init.data     PROGBITS   1043e240 43e240 087c3c 00  WA  0   0  4
[12] .machvec.init  PROGBITS   104c5e7c 4c5e7c 000020 00  WA  0   0  4

Can I patch in a size for NOTYPE? Or change NOTYPE to a different type that's allowed to have a size? (My knowledge of ELF is hitting its edges here.) Or it's the end of the .init.data section, and I could _depend_ on it being the end?

Another option is I could build the kernel with the tiny default initramfs (couple hundred bytes, it's the /dev and /root dirs, and the /dev/console node) and then objcopy in a _new_ ELF section, but the problem is I'm not sure how the initdata allocation/freeing would work there. (Would the kernel's early boot code know not to stomp it and when it can safely free it like it does with the _init stuff? According to include/linux/init.h the _initdata annotations are just grouping symbols into sections:

#define __init          __section(".init.text") \
  __cold  __latent_entropy __noinitretpoline
#define __initdata      __section(".init.data")
#define __initconst     __section(".init.rodata")
#define __exitdata      __section(".exit.data")
#define __exit_call     __used __section(".exitcall.exit")

We never use .init.rodata because we don't ARCH_HAS_STRICT_KERNEL_RWX in our j-core Kconfig. (Maybe we should?) But what I really want is ".init.ramfs" to be a section, and the rest of the plumbing to handle it properly.

Jeff also pointed out constants like the initramfs length can get resolved at compile time, but we should be able to do some horrible start = *(volatile char *)&thingy; typecast to work around that. I can tweak the build to produce a slightly different vmlinux (possibly even using an arch header), I just don't entirely understand why it's using this .incbin thing in the first place...

Another thing I can do is let the build use the default trivial initramfs image, objcopy in a new ELF section at the END of what's loaded in, and patch the zero page entries to load the builtin initramfs as an external initramfs. I have to read through the ELF loaders to see what sections they load. (Does the initdata go at the end of the ELF load? If not, how would it free it? I expect a linker script already has to specify that somewhere...)

More digging.


April 9, 2021

So far the evidence seems to indicate somewhere between 0.5% and 1.5% of humanity is trans (which would be 5-15 individuals in any group of 1000, so yeah you're gonna bump into them when they get to express themselves). As with other such minority populations (such as left handed people) this percentage seems basically constant over time with the big question being how accurately we've measured or suppressed what's there (I.E. how closeted they are), not whether anything's somehow increasing the percentage over time (left handed people don't recruit). Similarly, something like 1/3 of the population may be bisexual (or at least not all the way at one end of the kinsey scale). This seems more commonly expressed in women than men in western cultures, perhaps because the white male patriarchy's message of "women = sexy" is not contradicted by the concept of "a threesome" (which of course has its own enormous downsides). But so far there's no strong evidence to indicate the natural occurrence of bisexuality differs between men and women, just that men are far more reluctant to admit it in the aftermath of Queen Victoria's puritan cultural condemnation (unlike ancient Rome and Greece, where male bisexuality is common and unremarkable in surviving texts from the period). Of course there's still way too much cultural jamming on all this stuff to get an accurate reading on any of this yet, and reality is complicated (kinsey's scale didn't include asexuals back in 1948, and if anybody's come up with a kinsey scale for gender identity yet I haven't run into it despite the inherent contradiction of treating "being nonbinary" as "either you are or you aren't, pick one"), but the point is "creating" and "revealing" are not the same thing. (See also this thread about socially sanctioned risks; what we allow people to do and to acknowledge isn't rational, it's historical baggage.)

The birth control pill causes 3000 times more clot issues than the Astrazeneca vaccine. If that wasn't a crisis, this isn't a crisis. Meanwhile covid itself has killed half a million people just in the USA so your chance of bad things happening to you from the vaccine vs the chance of bad things happening to you from NOT getting the vaccine is multiple orders of magnitude different. The freakout is politically motivated by capitalists mad that a drug company DARED to waive patent royalties, and preventing that from setting a precedent at all costs.

H&R block's business model is to return to you some of your own money. In theory, the amount of taxes you owe and the amount of taxes you've paid are both fixed, so the refund you're owed (if any) is a constant. You shouldn't need to pay hundreds of dollars to gatekeepers to access your own money, and the only reason you do is they lobby to prevent the IRS from being as transparent as it is in most other countries. A uniquely american problem, caused by Late Stage Capitalism creating friction in what shouldn't even register as a transaction in order to insert gratuitous middlemen to act as parasites sucking cash out of people who don't want to be "customers". This is a form of Bullshit Job.

Here's a lovely explanation of how Late Stage capitalism is failing even at a theoretical level. "Believing you can buy your way out of anything leaves you unprepared to do the work." Late Stage Capitalism continues to eat its own tail, and gets into everything. What "standardized testing" really tests for is wealth and social class of the parents.

Another day, another long detailed article in a major news publication telling the story of a woman driven out of google by sexual harassment. (Well, technically that's the day before yesterday's article, this would be today's article.) The culture in general seems to slowly be becoming more aware of sexism, but "this space is populated primarily by white men" is only EVER the case because the white men drove everyone else out. Here's a primer on how "omitted variable bias" can teach an algoritm racism.

I keep condemning Boomers so hard because in a gerontocracy "policies track the desires of the pensioner class". The current increase in racism corresponds with advancing Boomer senility (hopefully as an extinction burst). Of course course Boomers supporting a theocracy helps the gerontocracy along, via a religion full of sexism and racism. White evangelicals are refusing vaccinations en masse, prolonging the pandemic, and are otherwise generally terrible.

The point of riot police is to create riots. We need to completely defund the police starting with their unions. (Which still aren't real unions.) The GOP is still pure evil, and everyone else's #1 legislative priority should still be to change the law to guillotine all the billionaires. Nine of the 10 wealthiest people in the world live in the united states, and those 9 collectively own over a trillion dollars.

The gun industry may go the way of the tobacco industry, not regulated away but litigated. (*shrug* Whatever works...)


April 8, 2021

After multiple days of being too depressed by the OSI mess to get any programming done, I am intentionally ignoring it and focusing on real work.

Fixed the $IFS thing (cache value needs to move into the function structure) and the bare assignments not persisting thing (wrong test: old pout variable's "unused" value was -1, new pipe variable's "unused" value is 0: switched variable name but not what I was testing for).

And now I've got... memory corruption! Which is always tedious to track down. But in this case it was just that the new variable assignment logic was blanking the VAR_NOFREE flag so when it temporarily inserted the "abc=def" argument string into the function variable context without making a copy, it would free it when popping the function context, and then the same string would get freed again as a command line argument in the exit path becuse it was still in the arg.v[] array.

That order of operations issue is back: either redirects are done first, or leading assignments are done first, and my code as-is really isn't designed to split them. I need the command line expanded with the OLD variable context so "abc=def; abc=ghi echo $abc" shows def not ghi, but if the echo was instead "env | grep ^abc=" it needs to show ghi...

I have tests where I force an error with ${a?b} to see what it has and hasn't done yet, and my test for "did redirections create files yet" is failing now...

Oh, I have disgusting solution. Ow that's ugly. I can create the new function (variable) context first, pop the function context off the stack but retain it, resolve the command line options, then put the context BACK where it was. For no other reason than to match bash's order of operations. (Ew. But reasonably small, done, and checked in.)

The main downside of not having an active twitter account is I can't favorite this.


April 7, 2021

So OSI has reversed itself AGAIN, and now insists that a memorial to its old mistake must remain in perpetuity or else the world won't know OSI had made a mistake. And the reason their 0BSD web page had a regression is OSI bureaucrats cycled out with no continuity of experience between them, and the new one tried to be ignorantly Helpful. (OSI is not only clueless about the history of the licenses it claims to manage, it also regularly forgets its OWN history. Bravo.) Said helpful new bureaucrat is, of course, tone policing me. I was spending a lot of effort attempting to be polite (and then just shut up when their discussion became 100% bikeshedding again). I am no longer attempting to be polite, but instead be bluntly truthful... except I see no benefit in further communication with them on their list until the NEXT time they screw this up again (every 3 years, like clockwork).

All I want OSI to do is stop. All I've EVER wanted them to do is just STOP. I've been very up front about this from day 1. I didn't submit 0BSD to OSI because OSI was irrelevant (after the falling out between Eric Raymond and Bruce Perens, then the disastrous handoff to Rick Moen, and then their announcement they were retiring from the license approval business). But sadly, it was just remission not a cure: as with the FSF they still have the ability to mislead, spread misinformation, do damage, insert themselves as a roadblock into other people's productive flow, and take credit for stuff they didn't do. (Completely unrelated, here's an interesting walkthrough of the mechanism by which committees filter out anything good leaving only the blandest and least interesting mediocrity, "an emergent property of group decisionmaking" which will "crop up whenever it's not compensated for in some way".)

It seems to me that I need to update my toybox license page with the history of the 0BSD license, and then point people at that timeline (and its links to primary sources) to update the Wikipedia page. Which is luckily all easily documented with primary sources with dates attached. (Kirk McKusick wasn't just a speaker at Ohio LinuxFest 2013, he was in the front row of the audience for my Rise and Fall of Copyleft talk, which is how I met him right afterwards to ask him about calling the toybox license 0BSD. That talk was me explaining the context in which I felt the need to come up with a new license. My talk made more sense if you could see the dozens of browser tabs I'd queued up in lieu of slides, which I didn't record because they pointed a video camera at me during the talk... and then published audio only a month later. Oh well, still better than Flourish in Chicago managed either time I spoke there.)


April 6, 2021

Right, license-review isn't a read-only announcement list, and it _is_ where the whole "please stop misnaming 0BSD" discussion was last time. But they've had some "trolling problems" and moderated all new users to both lists, which my resubscribe counted as. I didn't get bounce messages from license-discuss because it counted the license-review bounce message as my one (daily?) notification.

Anyway, I got email from the moderator early monday morning that he'd let my first message to each list through (so my fifth and sixth editing passes to make it sound less frustrated, respectively), and it's there now. Since then I got a couple responses, and have done my usual Pascal's Apology essay-style reply to both. (Here's the first, and here's the second.) Once again my bandwidth was taken up with Remaining Calm Despite Everything And Now THIS (for the THIRD TIME), which was... difficult. (I don't even want them to do anything, exactly, I just want them to stop. Which they'd previously agreed to do, but it didn't stick.)

In the course of replying I did basic research to answer the question "how many repositories on github are currently licensed 0BSD", and the answer (excluding forks) is currently twenty five thousand, one hundred ninety eight. The results are sorted by star count, with toybox coming in sixth, and the seventh being from Microsoft. I was not prepared for this answer. Um... yay? (So... so why am _I_ the only one speaking up in its defense on the OSI mailing list? Everybody keeps thinking this stuff Just Happens, and it doesn't Just Happen, and I would LOVE if it Just Happened so I didn't have to do it. David Graeber's observation that you make a cup once but wash it a thousand times remains true. So much janitorial work.)

Meanwhile, Lawrence Rosen said that Google just won against Oratroll in the supreme court, and can presumably go back to using its own Java implementation. (Two replies pointed out it's not a clean win, but it's 2021: take the win. Accept yes for an answer.)

Tried to get some toybox work done but there was a more immediate demand on my time. And my "edit this to not sound like I'm blaming the recipient" facility is a bit threadbare by this point. (It's a personal failing, I know. Maintainers need endless patience, and the ability to guide enthusiastic contributors into productive community members. I mostly just like to crouch in my corner and make stuff, which is not what I _should_ be doing.)

Alright, I moved TT.ifs to TT.ff->ifs and it still doesn't work and the reason is "IFS=123" is actling like it's in a pipeline when it's not (creating a temporary function context and discarding it again immediately), which the new cache plumbing I just made is dilligently mirroring. Great.

Alas, the night's over and the sun's coming up, someone's sat down at the table 20 feet away so I put my mask back on and my glasses are fogging up. Once again I walk home resolving to work some more on it from under a cat in the kitchen, but I hardly ever do...


April 5, 2021

The campaign against Astrazeneca has now leveraged J&J's manufacturing problems to kick them out of their US factory. And it's the one of the four that still hasn't been approved for use in the USA, despite our stockpile of it. Seriously? Capitalism is THAT pissed that they were going to waive their patent for the third world during a humanitarian crisis (until Bill Gates convinced them not to)?

Covid spreads by aerosol transmission. It does not noticeably spread by surface contact, which makes hand washing, surface cleaning, and "quarrantining" items irrelevant. We've got a LOT of good science on this now, which makes the early advice against masks even more tragic.

Christianity has disappeared into the GOP, which is still all-in on voter suppression as its only remaining option.

I have never had a Faceboot account, and do not intend to get one, and there are so many reasons for this. (I would happily come back to twitter, but will not give them a phone number and will not stop posting "Guillotine the Billionaries" as my comment on most links Janet Yellen is pushing for a Global Minimum Tax to fight against tax havens, but I still think inheritance taxes and legislating the hoarding of a billion dollars to be a capital offence are the best way for the government to get the money.)

As fossil fuel companies cling on by their fingernails, the "think tanks" that went seamlessly from leaded gasoline to tobacco to big oil are coming up with a constant stream of new talking points. It's a holding action they know they'll lose, but a global energy industry earning $1.4 trillion per year means every extra DAY they can hold out is worth around forty billion dollars. With a B.


April 4, 2021

Oh goddess, not again. The "Free Free All Hail Stallman Public 1.0.0" license misnaming of 0BSD is back. And it's because the OSI page has changed, which is NOT what it looked like back when they fixed the name (which was a decision to CHANGE not ADD ANOTHER with the explicit rationale that multiple conflicting names for the same thing was BAD).

Ok, that last link to the email announcing the name change was from license-review. Resubscribed to that list, wrote an email... Rewrite it 4 times to be less... frustrated. (I probably shouldn't title it "Please stop deadnaming 0BSD", among other things I doubt anybody there is young enough to know that word. Eh, maybe they have kids.) Sent it. Held in moderation because the list is moderated? (Probably by the dude responsible for the problem, who has not exactly shown himself to perform a Sam Vimes style "yes I will arrest my friends when necessary" impartial job to the best of his ability even when he doesn't like the outcome. At least not when being closely watched. (As much as I've disagreed with Bruce Perens over the years, _he_ turned out to have professionalism.)

Ok, that's an ANNOUNCEMENT list. Right, subscribe to license-discuss, cut and paste email into a new composer window, do yet ANOTHER editing pass to remove THE REST OF THE YELLING, sent email there, and... 40 minutes later there's still no April entry in the web archive? Are they running mailman as a cron job instead of an incoming message trigger, or did the message not go through, or...? I didn't get a bounce message...

Sigh. I WANTED to spend tonight on toysh development insead but wasted hours trying to figure out how much damage OSI's done to 0BSD again and how to mitigate it. (What is this strange fixation? Seriously nobody else has ever called it that. Nobody else CARES about this issue, or wouldn't if they didn't keep bringing it up and causing a problem.) Yes, maintaining a license involves surprisingly regular effort but this is just gratuitous.

Ahem. Ok, trying to get a LITTLE real work done: The NEXT toysh test failing is assigning to $IFS (Irritating Field Separator) and the assignment isn't changing the word separation rules. And THAT is probably because the variable list has layers of local variables now, but the TT.ifs cache (so we're not looking up a variable every character to see if this splits a word) is a single global instance? Hmmm. Except that implies the assignment would stick when it shouldn't, and instead it's being ignored. Gotta spray the code down with printfs to understand the behavior, bog standard debugging session but the sun's already coming up...


April 3, 2021

In a traditional sign of spring, half a billion Faceboot users just got their personal data stolen yet again, with the traditional terrible response from the relevant billionaires' mouthpieces. (Aren't we all happy about Faceboot's real name policy?) Meanwhile, other billionaires continue to suck. (The reason Nasa does launches over water from coastal cities like Houston and Cape Canaveral is so bits falling down don't hit anybody. How is this NOT OBVIOUS to certain rich white guys named after a strong smell).

Defunding the police is widely popular, but people who can't stop this one with means testing insist it isn't, even though reality undercuts them on a daily basis. (Oddly enough "male chauvinism" was NOT named after the minneapolis policeman on trial for the murder of George Floyd. You'd think, but no. Just a coincidence apparently.) The ex-british colonies continue to create the majority of their own problems. Georgia voter suppression is just one symptom of GOP hypocrisy, but then Jim Crow was always about plausible deniability. During the blizzard Texas oil and gas regulators were lying about renewable energy in realtime.

Boomers are a problem everywhere. Even Good Cop sucks at any issue Boomers care about, because they cower before Boomers intead of opposing them (hence running a 78 year old geezer to seem "adult" to 74 year old Boomers). Intellectual propertly law needs to die with them.

Christianity is now a wholly owned subsidiary of capitalist fascism, which keeps buying sock puppets to burn through established credibility: wall street journal, forbes, newsweek... now Rolling Stone has succumbed.

Of course capitalism always tries to do that with the output of creatives, owning and profiting off stuff it didn't create. Paul Simon just sold his catalogue, like the Beatles, and Michael Jackson did. The music industry is especially bad at this: Prince changed his name to a symbol and wrote "slave" on his face in public but ultimately admitted defeat Taylor Swift is re-recording all the songs she lost control of, Keisha lost in court against the producer she caimed raped her, Britney Spears has been her father's legal property for over a decade (at least Gary Coleman got away when he turned 18)... the classic Courtney Love Does the Math is a good intro to that sort of thing...)

But the music industry is by no means unique here. The Muppets belong to Disney, who fired Jim Henson's successor for trying to exert creative control. At least Neil Gaiman could walk away from the producer who wanted to insert a Giant Mechanical Spider into every movie he touched. As Neil explained in that interview:

And the other thing is Hollywood executives really love the smell of their own urine and what they really like doing is urinating on things. And then going, "Hmm, now this smells really good" and being really puzzled when the rest of the world goes "No, actually it smells like pee." A gorgeous example of that, Ted Elliot and Terry Rossio, who wrote "Pirates of the Caribbean" and "Shrek" and some lovely movies, were brought in by Jon Peters to write the first draft of the Sandman movie. He hadn't actually read any "Sandman" because he had people to do that kind of stuff for him, but he had figured out that what the movie needed to be successful was a giant mechanical spider. He wanted a giant mechanical spider because that would make any film a hit. Elliot and Rossio, who had read "Sandman," who went in with their pitch and looking forward to it and going, "But there's no room for a giant mechanical spider."

I was thrilled on going to see "Wild Wild West" to see that he had finally put this giant mechanical spider that I'd been hearing about from Elliot and Rossio for five years into a film with no ideas of any kind. I really think a lot of it is [executives] are wedded to their giant mechanical spiders and they're also convinced they know best, because obviously they're Hollywood executives.

Of course corporate "creativity" is generally laughably obvious, such as Amazon's anti-union astroturf campaign.

Oh look, another thing Trump did as part of his official duties as president was a fundraising scam stealing money from his supporters. (This is an instance of a common class of scam mostly targeting elderly boomers, what distinguishes this one is scale. At its peak over 1% of ALL credit card fraud complaints in the USA were Trump donors disputing auto-enrolled recurring payments, and they refunded an average of over $700,000 per _day_ in december.) And of course this scam has become standard practice across GOP fundraising now, because they're desperate, rapacious, utterly shameless, and out of ideas.

Dear Pfizer and Moderna investors: stop FUD-ing Astrazeneca please? They waived their patent rights so anyone anywhere can manufacture their vaccine royalty free, and capitalism CANNOT allow this to be seen to succeed so has launched an organized campaign to discredit them, and it's just SAD. Whipping up a panic about blood clots when the obvious question is how many people died of the exact same thing in the control group? If 150k people die each day on a planet with 8 billion people, that's roughly .002% of the population dying each day, and way MORE when your sample skews elderly and pre-existing-condition (because that's why the vaccinate first) but even ignoring that, you can EXPECT 20 people per million dying each day. So if you vaccinate a million people, yes some of them are going to immediately die, because THEY WOULD HAVE ANYWAY. Seriously, heart attacks and strokes are two of the leading causes of death, and THAT'S BLOOD CLOTS. The birth control pill is WAY more dangerous than any of the current batch of vaccines, and nobody minds because doctors consistently ignore women's symptoms.


April 2, 2021

Google Voice just transcribed "zero clothes BSD" and I can't blame it for trying. (July 14th, Skynet.)

I am getting sooooooo many robots emailing me that I mentioned some old website (always linking to the history mirror) and wondering if I'd link to THEIR website. Or else saying they "love my blog and want to write guest articles" for it, which... what? Yes, there's an rss feed containing the word "blog", thanks for noticing, automated web spider emailing with the name of someone whose twitter account last posted in 2017 and obviously stock photo profile picture. I'm 95% certain this is a google rank thing where spiders are trying to create links to pages that then get replaced a week later with... I dunno, phishing sites? Clickbait ads? There's a scam going on here (ahem: "trendy capitalist business model") but I don't know what it is, and am not hugely interested in finding out...

I'm overdue for a toybox release again, and trying to get toysh passing all of its tests (at least the ones that aren't gated by unimplemented features, like the $((1+2)) stuff) before cutting a release. Whether or not I finish implementing function support first is as of yet undecided. (It's close, but not quite there yet. Declaring functions involves lifetime rules where I'm taking a parsed pipeline _out_ of the source lifetime context and into a separate list where it lasts as long as the function name is live, except the source context ALSO has to still have that data because:

$ for i in 1 2 3; do a() { echo one $i; }; a; a() { echo two $i; }; a; done
one 1
two 1
one 2
two 2
one 3
two 3

Which means pipelines need to be reference counted, but right now each pipeline is just a linked list of identical structures and I don't want to reference each member; it's eash to stick the reference count in the function structure but input parsing isn't attached to a function structure, when I run stuff from the command line I'm not in a function, it discards each thingy after it's executed (thingy = contiguous set of line continuations parsed as a group until it goes back to promting "$" instead of prompting ">") and it's IMPORTANT that this freeing happens or just typing at a command prompt would leak memory. The same logic goes for shell scripts, which are basically "bash < <(zcat filename.gz)" and CANNOT require the file to be seekable.

My main blocker for starting to implement toysh for so many years is I very much WANTED to mmap the shell script and have the string data only exist ONCE, which meant MAP_PRIVATE and inserting null terminators into the file, and the lifetime tracking just didn't work. The speculative design always wound up reference counting individual WORDS once you dug deep enough, and a 4 or 8 byte pointer to the start of each individual word string wasn't actually saving noticeable space when the words were "for", "if", and "ls", but using 16 bit offsets made everything unreadable and introduced arbitrary limitations. And anyway, it didn't work for the command line where I'm reading from a filehandle I can't mmap so I'd need two codepaths anyway...

I started making progress when I gave up on that and just implemented a conventional "I'm copying this data multiple times" approach. Which I REALLY don't want to do AGAIN for function pipelines. Which is why I have the "run function" plumbing just about implemented, but the "declare function" plumbing consists of a TODO statement on a printf.


April 1, 2021

I refuse to do news compilations on April Intentional Lying For Some Reason Day. (Is it supposed to be funny? It never has been, but they keep doing it for some reason.)

Instead of doing development work today, I wound up editing blog entries for posting. I did the 17th to the 22nd and I took me 4 hours, which I did not expect. That's about half a day of editing effort per week of blogging: there's a reason I keep falling behind, and made keeping up a patreon goal.

I'd _like_ to get to the point where that effort went into editing essays like my old computer history threads, or renewables technology, or how GPS works, or the impact of china's 5 year plans on the finances of the energy industry...

I'm aware blog entries are not the best format for this. Long and long ago I wrote Motley Fool columns because it was an outlet that had a publisher. I've been offered writing positions in various startup websites over the years, but never access to a wider audience than just posting it to mailing lists (where things I write tend to go randomly viral anyway).

I keep saying I should do youtube videos but those are even MORE editing work, of a type I dunno how to do yet. I can just about poke at Audacity, and have a video editor on my phone that actually works, because android doesn't have the LINK UI problem that Linux does... but it's still a tiny fiddly screen on a device I have to import huge files into and out of. Still, I should sit down and give it a go sometime, except that's the same kind of energy that goes into carefully stepping through japanese text and so on. "Ah yes, when I have spare focus I should do THIS" has no shortage of consumers.


March 31, 2021

Fascinating article on how churches have changed:

"Gone are the days of a choir, suited up pastor and random people sitting in velvet chairs onstage... Now it’s a U2 incarnate worship band, perfectly placed LED wash lights and a pastor... motivating, edgy and might even let a cuss word slip if you’re lucky."

In his book, Kirby writes that these pastors who have enormous social media followings aren’t simply pastors anymore, he writes. Often they are motivational speakers, corporate coaches and leadership consultants. Kirby said he has heard of churches where a volunteer was designated solely for the purpose of carrying the pastor’s Bible. Often, he writes, these pastors have private entrances, reserved parking spaces, security details and a gaggle of personal assistants or handlers.

Plus, of course, $10,000 outfits, and "selling merch" in the name of the guy who was literally violently against selling merch in church.

And of course churches are tax-free, but Boomer Biden will not tax the billionaires. This is why I lobby for guillotines, not taxes: hoarding a billion dollars is self-evidently a capital offense, and should be legally classified as such. The "winners" of capitalism never voluntarily compensate the "losers" (but will happily pay professionals to lie to you about it). But no billionaire ever cares about "externalities" (which is a technical term for anything they can sweep under the rug). If they cared about anyone but themselves even a LITTLE, they would be a billionaire.

Following through on the math, if sending $1000/month to each of 330 million US residents multiplies out to just under $4 trillion/year, and the government is already spending $61 trillion over the next 10 years, it would have $21 trillion left in its EXISTING budget without raising taxes to cover more spending. We've already got $1 trillion/year going to social security, and if it's "that or basic income" then this is only _half_ the existing federal budget. We spend at least twice what we need to on defense (our largest make-work program, paying corporations to create stuff we then blow up so they can make a new one), and paying "interest" to ourselves to disguise printing money is silly (and mostly goes to billionaires and corporations that _have_ large pools of money that should have been taxed away decades ago), which is at least another $10 trillion that could be "retired" if we wanted, bringing the "extra taxes" down to $2 trillion/year we'd need to guillotine out of billionaires and corporations. That's entirely doable once the Boomers die.

Sigh. The point of the bitcoin money laundering protocol is to steal money. That's what it's for, that's what it does. I dunno why somebody would blame Apple for their own choice to put their life savings in bitcoin.

The Boomer extinction burst has gone full Queen Victoria pearl clutch. I look forward to the end of crazy things like homeowners associations, and take comfort that there are demonstrably fewer Boomers now than there were during the George W Bush administration. (They're crazier, but smaller in number.)

The black woman elected to the georgia state legislature who was arrested for knocking on the closed door behind which the Georgia voter suppression bill she'd voted against was being signed has been charged with a felony for said knock.

Remember how the moral of all those Tony Seba solar/batteries talks was that humans suck at emotionally understanding exponential curves? (You can explain it all you like, they won't _believe_ it.) That problem is hitting home again during the pandemic as lockdowns end too fast before enough of the population is vaccinated, and hospitals are collapsing again. Remember, the hospital system getting knocked out means an allergic reaction or broken collarbone can be fatal, let alone heart attack, appendicitis, needing a blood transfusion... You don't necessarily die of covid, you die of an infected kidney stone or a fairly minor car crash because the hospital can't take you.

To slightly paraphrase Gandhi, American democracy "would be a good idea".

Defund the police.


March 30, 2021

Stallman's destroying the FSF. Given that I've considered the FSF a net negative for 15-20 years now, I'm ok with this.

There's a reason I never pull from github into projects I uploaded there, and that was true before the Law Offices of Small and Limp esq merged it with Linkedin. (When I apply a pull request from github I copy and paste the URL to wget, manually adding ".patch" to the end, and then examine the resulting text file. On more than one occasion I've edited them slightly, although mostly to Elliott's patches because he knows me and it saves a cleanup commit. :)

Oh hey, Austin's getting a chance to do ranked choice voting. I need to go vote for that when early voting opens up.

In theory Austin allows everyone over 16 to get vaccinated now, in practice nobody's got J&J yet and the closest HEB pharmacy with vaccine slots (pfizer) is 80 miles away.

Still grinding away debugging my latest changes to toysh. Redo infrastructure, fix regressions, rinse repeat. I'm well into the part of the project where I'm spending more time reverse engineering my own code ("What does this bit do? Why did I do that?") than writing new stuff, but that happens in big projects. It's one of the main scalability limits. You've gotta work out how to modularize it to chop it into "I only have to understand what's going on between data coming into this bit and data going back out again through these interfaces, and then maybe audit the users of those interfaces". Which I mostly have but changing the infrastructure changes the data representation and interfaces, and the _sequencing_ is the tricky bit...

I keep writing chunks of code like:

void xfdump()
{
  int x = 0, fd = open("/proc/self/fd", O_RDONLY);
  DIR *X = fdopendir(fd);
  struct dirent *DE;
  char *s, *ss = 0, buf[4096], *sss = buf;

  for (; (DE = readdir(X));) {
    if (atoi(DE->d_name) == fd) continue;
    s = xreadlink(ss = xmprintf("/proc/self/fd/%s", DE->d_name));
    if (s && *s != '.')
      sss += sprintf(sss, ", %s=%s"+2*!x++, DE->d_name, s);
    free(s); free(ss);
  }
  *sss = 0;
  dprintf(2, "%d fd:%s\n", getpid(), buf);
  closedir(X);
}

And then discarding them again. (That shows all the filehandles a process currently has open, and what they point to.) On the one hand, there's nothing as USELESS as other people's debug code, checking that in only ever helps the author of the code. On the other hand, this is still in pending and I keep having to debug it so having a few stategic debug readouts is nice... but they really shouldn't be checked in... Grrr. I waffle on this one.)


March 29, 2021

A good article on how "Noble Lies" (such as Fauci denying the effectiveness of cloth masks early in the pandemic when he knew they helped but wanted to prevent a run on N95 masks to reserve as many as possible for healthcare workers) are the worst kinds of lies, doing the most long-term damage.

Hands up everybody who's surprised that the J&J vaccine is preferred by people with any choice in the matter? They're producing 11 million doses per week and the country currently has 331 million people, which 1/30th of the population each week. But we've already vaccinated some, there are 2 other vaccines (3 if oxford is ever approved), and the rate of production is increasing...

Speaking of which, the USA has millions of doses of the oxford vaccine sitting in warehouses, without regulatory approval to use them, and we're exporting zero doses of vaccine to our allies. India, China, and the EU are all exporting at 1/3 to 1/2 of what they produce, but the USA and Brexit are still hoarding it all for themselves, EVEN THE STUFF THEY CAN'T USE, and won't even send it to places like canada. (In response to universal "wow, that's stupid" coverage they announced plans to eventually export vaccine, but so far it's just lip service and they still aren't actually doing it yet.)

Speaking of "wow, that's stupid", transportation secretary Buttigieg is being amazingly stupid by trying to neutralize any advantage of electric cars with punitive taxes. The gas tax is to DISCOURAGE BEHAVIOR, not to pay for stuff. You pay for infrastructure the same way you pay for defense spending. When is the last time we couldn't 'afford' a war? FDR did the New Deal in the middle of the Great Depression. This idiot white male's proposal would also prevent app summonable self-driving cars from offering "all you can eat" plans with flat monthly rates no matter how far you go. The COST of putting extra miles on a vehicle that goes one million miles in its lifetime and is recharged by solar power is just "rotating the tires and cleaning the interior", but if you add a per-mile tax you make sure every OTHER country in the world does that but NOT us because SOME IDIOT dunning-krugered up an 'idea'.

Chevron was ordered to pay $10 billion in damages for polluting the amazon, and the company seems to have responded by getting the US lawyer who beat them disbarred and placed under house arrest in manhattan for the past 2 years.

You can sing "Britain is falling to fascism" to "my bonnie lies over the ocean".

Turns out a lot of crime is created by enforcement actions. (Just like when our army goes to a foreign country and opens fire into a crowd, suddly there's a lot more people on the opposing side who want to kill us).

Good analysis of a capitalist PR psy-op.

Fascists dogpile. It's one of their primary tactics, and why punching the condensation nuclei is so effective. (They're cowards individually, merciless and pitiless in large numbers.)

I still advocate for guillotines rather than taxes. There are less than 1000 billionaires. We outlawed slavery, we can change the law to make hoarding a billion dollars a capital offence. But we're all waiting for the Boomers to die first.


March 28, 2021

Big Boat Still Stuck. You can put those four words in any order and they adequately describe the situation.

I am disappointed by execveat because I want to add an option to chroot to run a binary from OUTSIDE the chroot, and it seems like execveat with a CLOEXEC dirfd would do the trick nicely... but it's ignored for absolute paths. If I "int fd=open("/", O_RDONLY|O_CLOEXEC)", then chroot(), then execveat(fd, "/bin/ls") I want it to run the /bin/ls OUTSIDE the chroot, not inside it. (Yeah, I can chop off just the filename and open the path part myself, but DUDE. Why did the syscall designers not already think of this?)

The bigger problem is this has to be a static binary: even exporting LD_BIND_NOW doesn't help the dynamic linker find its libraries _after_ we've chrooted. While I could LD_PRELOAD a stub intercepting the _start symbol and _then_ calling chroot, A) toybox is one executable and this would require shipping a second file, B) that would be the old chroot() syscall; the new one doesn't help there, C) how do I then find the real _start out of the executable to hand off to? (What, borrow the pending/readelf.c code to walk the ELF tables? Bit more intrusive than I'm looking for here and I worry about different targets with different link syntax with RELA and such. I'm not using a dlmopen() gnu/dammit extension, and it would be EASIER to walk the elf tables myself than understand that thing's arguments. I'd hoped dlmopen() was like fmemopen() and I could maybe find/load the libraries that way, but no...)


March 27, 2021

Since 2021 is _less_ of a trash fire than 2020 was (not an endorsement), I kinda of want to do "three technical days, one political day". But stuff just keeps coming. I suppose I could break down and keep two blogs, but... there's just one of me?

I very much want the world to go back to a point where I have the luxury of ignoring politics. But first I'd have to stop feeling like I'm living in 1930s Germany. (Yes, we're in the "hitler went to jail and is writing Mein Kampf" stage. That... wasn't actually a permanent solution to the problem last time around? We had surgery without chemotherapy. The far-white billionaires behind Fox News have purchased the Wall Street Journal, Newsweek, Forbes... literally buying credibility until they burn out each new sock puppet, while they build new propaganda networks.)

Not the sort of thing you just ignore and hope it goes away.


March 26, 2021

Sigh, why is j-core.org down? Poked Wale and Jeff about it but it's not quite yet 5am on a saturday, may take a while. Yes, I'm writing this entry early in the morning on the 27th, backfilling what happened on the 26th because even day = technical stuff, to make it easier on followers who just want the computer geekery and not Boomerdammerung (the "prophesied war among various beings and gods that ultimately results in the burning, immersion in water, and renewal of the world"). But at least we can all rally behind the simple clarity of Big Boat Stuck. It's the news version of a palette cleanser. It's big. it's a boat. it's stuck. It's probably gonna be there a while. (Now available in "chibi", and it's a pity Clarke and Dawe can't cover it.)

Instead of working on toysh, I spent the evening cleaning up chsh.c, which I had an open window for from yesterday, plus a little analysis of somebody's mkroot problem. I _was_ also planning to continue down the "turtle board help desk" rabbit hole, but I haven't gotten any reply email to yesterday's threads, which implies the j-core.org lists's mail server is down as well as the websites. (Wheee.)

I gave in and started redoing toysh to always have a block in the block list at each function level, fixing the off-by-one push/cache design to just have TT.ff-*gt;blk->pout and TT.ff->blk->urd always be current.

That urd entry is a bit odd because pp->urd has the undo list for each command's redirects. The blk urd is for undoing pipe redirects and the redirects after a block ala "{ echo; } > potato". And it's still SLIGHTLY off by one because when you hit something like that the redirect undo list should be BEFORE this block, so that the | lifetime and and > lifetime match and get undone in the same unredirect() call operating on the same urd list.

And THAT means that the first block's redirect list is in the "zero block" that just got added, so you unredirect() _after_ you pop. And when you have "echo | tar | gzip | ssh" all at the same level, you save the pipe into the current block's redirect list (which should be empty) and then undo (clearing the list) before running the next command, because you've overwritten stdout (and maybe stderr) for _this_ command, and may have inherited a pout that overwrote stdin, but as soon as the command is run we undo all that. The only thing that remains is the pout which the NEXT command will replace its stdin with, which is not in the unredirect list yet because it hasn't displaced anything.

It's a fiddly design to keep track of. We're juggling filehandles and at least one of them has to remain airborne between each command. I got this right last year, and THEN added functions. I keep WANTING to have the pipe unredirect list be a local variable, but it has to be at the block level because block unredirects happen AFTER pipes into and out of the block, so they stack on top of it for the unredirect logic. The < and > get moved back where they were first, THEN the filehandle the pipe displaced gets moved back, so the pipe unredirect has to be retained LONGER than the others. We traverse the urd list in reverse order when we undo it, so the pipe entry has to be added first. Not hard to understand, it makes SENSE, it's just something I have to keep reminding myself of because every time I walk away for a day or two and then come back, I keep trying to collapse it down to the next design level and that's the crossing that says it has to go at THAT level.

Hopefully now that I've written it down, I'll remember it. I should totally add a comment, but have to get the code working first to know where to put it.


March 25, 2021

China is trying hard to become the new North Korea. This is a bit concerning because at $DAYJOB all our electronics manufacturing supply chains run through Shenzen, and they're REALLY trying to get themselves sprayed down with punitive tariffs. (Some sort of ego-driven chest beating exercise as far as I can tell? I hope it's not Hitler's "we need breathing room" (as quoted in Star Trek 6: the Undiscovered Money).)

Over the past 30 years manufacturing, especially rare earth metal mining, was outsourced to China because they were willing to poison their citizens and run slave labor camps for money. But the environmental "advantages" are tailing off and the slave labor isn't plausibly deniable anymore, so the REASONS for shipping everything to the other side of the planet no longer hold true and the supply chains are largely held in place via inertia. Even China's state media admits their school system completely kills creativity, which is why they needed Hong Kong and Taiwan to provide all their inventors for the robots to slavishly implement/duplicate. But they've already killed the Hong Kong that laid the golden eggs (Shenzen was just a suburb of Hong Kong, it turned into a tech hub entirely because of its proximity to the british protectorate), and are eyeing Taiwan...

This is the manufacturing version of the 1980-2010 fad of outsourcing all your IT work to India, where their college students would intern for 18 months at an outsourcing firm as training, and then once US firms had paid to train them they'd go do REAL work at one of the firms servicing customers in places like Korea and Vietnam for 3 times the money. The companies that did this got deliveries of mediocre code from junior programmers, and then any follow up was done by different people with no continuity of institutional knowledge because the people your contracts had trained, who had learned everything you had to teach them, were now working for your competitors. (Or at least precluding your expansion into those markets.) Having China manufacture your products is exactly like having India write your code. Except China's government regularly pulls crap like Tianamen Square and the occupation of Tibet, is run by a dictator for life, is built on censorship (the "great firewall"), disappears people to concentration camps, and those statements aren't even particularly in DISPUTE.

P.S. Yeah yeah the GOP continues to suck but it also continues to be fundamentally a financial scam on its own base (scroll up, that's an informative thread) and there's other stuff to pay attention to (such as how terrible facebook is, or how terrible amazon is, or how terrible the boomers were, or police everywhere, or guns, or religion, or plutocracy, or real estate hoarding or this thread where a retired Navy veteran reacts bemusedly to the ship blocking the Suez canal).

Meanwhile, the pandemic isn't over yet. You know how we have a new flu strain every year? Well it's been a year and we're getting new covid strains because when it thrives and mutates in a worldwide population that's what happens.


March 24, 2021

Sigh. Gmail's spam filter going feral is a regular occurrence, I need to check it every few days and fish the not-spam out or it spirals into "this is similar to other spam" and becomes 90% false positives. I forgot to do it for 3 weeks and one of the FIRST false positives it got was the j-core thread about the boards I sent out asking me follow-up questions about them. (I only found out when I emailed THEM to make sure they'd arrived, and got pointed at the unanswered thread. Oops. Jeff probably didn't reply because he expected me to.)

Bit more traffic on the list now about turtle boards. I've sent out 3 turtle boards to people outside $DAYJOB, and have addresses to send out 2 more (which leaves me with 2, and I kinda need those), and if they post about what they're doing with it (and I collect the "here's how you do that" bits I'm writing up and stick them on the the web page), that's reasonable momentum to try again at the Crowd Supply stuff.

The main hiccup for me with Turtle is that Jeff Garzik, one of our larger investors and on the board of directors, absolutely hates the name "turtle" and has wanted us to call it everything from "arrow" to "jx" instead. So if I make a j-core.org/turtle page I invite trouble. As with rewriting the bootloader, which would NOT use the ELF toolchain if I did it but instead be based on the hello world kernel built with the Linux toolchain (which Jeff 100% will not merge into the project because it's more important to him that it use that toolchain than have any specific feature set), the objection is enough to keep me from starting the work. There's always other things to do instead.

Toysh: the way bash segfaults when you "echo source input > input; source input" (stack overflow) is less alarming than "meep() { meep; }; meep" being a cpu-eating loop that not only ignores ctrl-C but ignores closing the tab it's in (keeps going until "kill -9" of the PID). Again, behavior I do NOT intend to reproduce in my version. I suspect I should add another counter check and error_msg("tilt") to my code...

Anyway, working through what function contexts mean for pipe lifetimes. Each function() body is a compound command which must contain at least one executable statement (with ((math)) being sort of an edge case there but manageable for this) which means my pipe handoff logic is guaranteed to have a statement to consume pout, so "echo blah | func" can't leak the "pout" file descriptor if I move it from TT.ff->pout back to TT.pout? (I moved it into function context when adding function support, but it just bridges a filehandle between one executable statement and the next.)

The thing is the filehandles created by pipe() need to be closed, but "pout" is the filehandle that BECOMES stdin of the next process. I can't make it stdin earlier because redirects override pipes ("echo hello > file | cat <(echo potato)" writes hello to file and "potato" to stdout) so the pipe has to replace stdout before processing the first command's redirects, and then replace stdin AFTER the first command runs but before launching the second command's redirects. Sequence is important, so it has to be a high filehandle for a bit we can dup() down later. We use the existing save_redirect() and unredirect() logic because we're displacing stdin/stdout (and stderr for |&) which need to be restored later, and that needs an int *urd to save the unredirect information into.

MOST of this stuff is based on flow control blocks, if I "echo | if true; then echo | cat; fi" I have nested pipes and redirects. But there isn't a "block zero" the way there is for function calls. I made TT.ff never be empty so I can always just dereference it for things like TT.ff->arg, but I didn't do that for TT.blk (now TT.ff->blk) where empty means we're not in a block, which is sometimes nice to know. (It's nice to know for functions too but I just check TT.ff->prev == TT.ff there; circular list.). This "blk can be null" decision means stuff like blk->pout and blk->urd need somewhere to live when we're not in a block, and what I did is just have that top level copy ALWAYS be the one that got used, and had block entry/exit swap the contents in/out of the most recent blk version.

Outside of flow control blocks, a pipe is only ever from the stdout of one process to the stdin of the NEXT process, and things like function calls MUST have a command in them (can't be empty) so that does get consumed. so I just need the one and TT.pout gets consumed when set and then unredirect() cleans up later. The fiddly bit is:

$ echo -e 'one\ntwo\nthree' | if read i; then cat; fi
two
three

The "replace stdin" has to happen BEFORE block entry, and then that pipe becomes the default input of every command in the block. I _think_ I'm getting that right? That's what the switch from blk->pout and TT.pout is doing.

This still leaves "alias" being weird, but:

$ alias potato=;
$ potato
$ echo hello | potato
> ^C
$ alias potato=";"
$ potato
bash: syntax error near unexpected token `;'

Alias expansion happens at _parse_ time (BEFORE line continuation), not runtime. Like #include in C, it's over and done with long before this part of the code runs...

No, that's wrong... when I pipe into "source" or into a function every command in that new context needs the piped data as its stdin and what it's writing going to a pipe if its stdout was piped. It's essentially a new flow control block, but I haven't ADDED an ff->blk to the one I just left. That's why I had ff->pout and ff->urd at the function level, because it's "block zero" for that function. The problem was I wasn't doing the block style handoff when calling the function, but the "handoff" is just "perform the action before calling and cache the data at the previous level".

Grrr. The blk->pout stuff is conceptually off by one (due to the missing zero blk). The reason TT.pout is a global is so when you pop_block() it can assign the one cached in exiting block to the "active" one, whereas if you always had a blk then blk->pout would always be active. And it has to close the old TT.pout rather than relying on it to already BE closed because things like "break" or ${a?b} can pop you back up multiple levels. (Break shouldn't be able to do so from a pipe, echo hello | break is essentially a NOP, but ${a?b} smashes back to the command prompt and shouldn't leak resources doing so.

Urgh, fiddly corner cases...


March 23, 2021

Walking out to the table tonight I got caught in a rainstorm and sat under an awning just south of HEB for 20 minutes while it worked its way thorough. There was a white-ish van parked in the middle of the road with its lights on, and a screaming argument coming from it loud enough to cut through my headphones, so when the rain let up a little I went over to the van (which was dented all along the left side, thought maybe they'd driven away from an accident) to ask if they were ok. The woman in the passenger seat said "no I am not", and the white dude got out through the driver's door and went around to the back of the vehicle. I held out my phone and asked if she needed to make a phone call and the man said "Are you calling the cops?" and the woman screamed "give me back my phone" at him, and then went "yes, call the cops".

I'm reluctant to get the police involved in anything, but 911 won't send out social workers, and he was a white dude and she wasn't black so they probably wouldn't shoot either of them without asking? (Between rain on my glasses, mask fog, and general poor lighting I couldn't see all that clearly, but she had long bleached blonde hair. English was clearly not her first language, either spanish or portugese? But she's the one who asked me to call, so...) I walked to the sidewalk past the front of the van noting the license plate, then stood on the sidewalk and called 911. The white dude got back in the van, turned off the headlights, and TORE out of there while I relayed the plate number and what I'd seen to the dispatcher. They headed east on 43rd street, ran the red light under I-35, and then turned off their tail lights.

I would give that action less than a 5% chance of actually having done any good. Austin PD is better than some but... (Yeah, I should have hidden somewhere and made the call without quite so obviously alerting the white dude, but I didn't want to forget the plate.)

Oh good grief, Stallman's back on the FSF board? Ah, he's tone-deaf and self-appointed as always, and is being opposed.

Global warming still a thing, doo dah doo dah. Remember those Australian guys rehabilitating land because british ranchers created a bunch of desert once they'd slaughtered the natives, and it's possible to UNDO the damage if you acknowledge the cause? Yeah, dead ground can't absorb water so it all runs off as floods. This is a manmade problem on the RECEIVING end as well as the "we heated up the atmosphere so it holds more water and dumps it in bigger lumps" end. Unfortunately Australia's government was recently taken over by a center-right party with a misleading name, and as with all right wing loons they turn out to be both horrible people and surprisingly incompetent. (Re: the name thing, the right wing is constantly trying to rebrand itself because policies that steal from the 99% to give to the 1% turn out to be profoundly unpopular, so when not trashing liberals plutocrats and fascists pretend to BE them, ala "neoliberal" and "libertarian".)

From 1889 to 1890 republicans had a scheme to pack the senate by adding six new states in nine months, which resulted in things like the battle of wounded knee to kill off the new territory's existing native occupants. They have not improved in the century and change since.

That's numberwang.: the "united" kingdom seems unlikely too remain so for long.

Defund the police, break up Amazon.


March 22, 2021

Went down a bit of a rathole making $() work in the same process (because $((echo hello) | tr) has a pipeline IN it so it seems like there's an extra fork in there?) until I realized that the REASON it has to be asynchronous is so the pipe buffer doesn't fill up and block. (Otherise the output of $() blocks before it returns to get read into a string.) Added a comment to that effect.

This is also why "echo hello | cat" needs the echo to be in its own process, not in the shell process. Even though it's a builtin and can run in shell context, the output pipe will fill up and block if _we_ are the consumer (or have not yet _started_ the consumer)... I suppose I could make it run in the shell process if I did it in two passes (launch child processes, then go back and do builtins) but the reason that won't work is "echo $BIGLONGTHING | read i" has a builtin talking to a builtin. Nope, needs to happen in separate processes asynchronously draining pipe buffers. (Ok, the rule could be that a builtin consuming the output of another builtin has to be a child process. I already made "abc=def | echo" fail to persist by another mechanism, but that was just performing the assignment into a temporary function context that immediately got discarded.)

The hang in the test case is because the tr process has its OUTPUT redirected, not its input, but the fiddly bit debugging it has been it's one of FOUR processes, which seems excessive. But the parent shell is a process, $() is a process because output pipe, (echo) is a process because subshell but the echo WITHIN that can run builtin because it's not (locally) piped, and tr is a process: that's the four. So figuring out where the redirect went off the rails is a little more awkward than it seems, and making them not exit and discard data (ls -l /proc/12345/fds saying no such file or directory) is crotchety. Not blocking debugging progress, but time consuming to work through it.

Ok, it's not INSTEAD, the tr process should have both input and output attached to pipes. There should be a pipe between the echo process and the tr process. And the problem is connecting the input uses TT.ff->pout not being -1 to indicate that the previous process piped data into us, but... it's not a per-function thing? It's a per flow control block thing. A function is KIND of like a flow control block but not exactly, so I have a list of flow control blocks within each list of functions, but right now each function starts with ff->pout = -1 (which is wrong). Hmmm. You can pipe output into a function, and you can pipe the output of "source filename.sh", so both of those need to inherit pipe context from their caller.


March 21, 2021

Saying the quiet part out loud, the GOP warns it has literally nothing left but voter suppression. Their entire remaining strategy is voter suppression. Of course voter suppression isn't Russia's only trick to help the GOP, they're innovating things like ghost candidates. And the GOP is leveraging deep strains of racism and sexism built into the whole country from its founding, even liberal california apologized in 2018 to the Latino women it forcibly sterilized, a practice finally outlawed in 1979, and an apology which was just lip service with no money or anything attached. And when that white asshole performed gun violence du jour in Atlanta, the husband of one of the victims was arrested and detained until his wife died because he was brown and thus a suspect rather than a victim. The british colonizers used racism to steal the natives' land, the confederate plantation owners used racism to become rich, the northern factory owners provoked everything from the homestead massacre to the triangle shirtwaist fire in the name of unbridled capitalism... We have some serious cleanup to do when the Boomers die, starting with teaching "humanities" again. But the GOP itself has decided the only way it has to retain power a little bit longer is to spend everything that's left on the holding action of voter suppression. That helps it ride down the Boomers, the rest of us need to plan for what to do AFTER the Boomers.

Dear clueless Boomer Media, the surging price of used cars isn't because people are buying them with stimulus checks, it's because of catalytic converters (as I blogged about last month). The surging price of the rare metals in catalytic converters has driven their price up over $2000 each, meaning you can fence a STOLEN catalytic converter for $1000, which has led to widespread theft (and not just in big cities). This adds $2000 to the price of every car because even used ones can be junked and this ONE PART sold for $2000 with proper title paperwork (and then it drives your car INSURANCE through the roof).

Meanwhile, electric cars don't have/need catalytic converters, which is not only a $2000 discount on the manufacturing/repair costs but means your car isn't an obvious theft target for any random yahoo with a hacksaw. (P.S. while walking to the table late at night, I've noticed a whole lot more REALLY LOUD cars driving by with essentially no muffler. The car still runs if a thief cut off the fuel exhaust system, it's just smelly and loud and can't pass even Texas' lax vehicle inspection...)

This is a very good thread about the asian-amercian experience, the downsides of being a "model minority", and how white people culturally appropriate at outright "vore fetish" levels. (I tend to link to twitter threads in the middle these days because the thread tends to stop with a tiny "click here to expand the second half" link that's easy to miss in the flood of reply tweets. When I link to the start people don't always notice half the thread, they think there's just a short little bit and then a bunch of replies. Twitter is bad at being twitter.) It's not just culture they appropriate, white gentry crave victimhood. What really scares them isn't mobs coming for them with torches and pitchforks, it's change happening without being forced, just because people learn better and decide to do better. They know, deep down, that they are obsolete people, and THAT scares them.


March 20, 2021

Darn it, I've been treating FD_CLOEXEC as if it closed file descriptors on fork(), which it does not. It closes them on exec(). Which means if you run a child shell which doesn't exec(), or run a builtin toybox command that doesn't exec either, the new PID is polluted with a bunch of leftover fds. And there doesn't seem an obvious trigger_cloexec() outside of the exec system call(s). Maintaining my own list instead of annotating with the fcntl raises lifetime issues for said list because there isn't just _one_ unredirect list, there's one in each flow control block level, and THOSE nest with function calls now; how do I track when one of the marked-for-death filehandles gets closed in the parent naturally, wrap close() and check my TT.clofork list? It's not just "go through and close all the fds that unredirect would close" either because unraveling 2>&1 cares about sequencing, because you're also MOVING file descriptors back into place, and sometimes you move-then-close when redirects get stacked... The cloexec annotations were a side channel to that which triggered in the child without needing to be cleaned up by the parent. Hmmm.

There's multiple ways I can make it work, it's just an intrusive pain. The current design's based on a slightly wrong assumption, and now I'm wondering if it matters enough to do big changes to clean up something that... maybe doesn't hugely matter? ACTUAL child processes aren't polluted, and parent processes do eventually close all the fds, and none of the builtins should _care_ about the extra fds, and filehandle exhaustion isn't a common problem... The systemwide fd limit is like a million, and I dunno if many dup() of the same kernel file struct really counts as multiple open files? I guess if it has its own file position indicator it would. (Does lseek() on one move the rest? I really don't want to have to care right now...)

Anyway, I'm trying to debug the sh -c 'echo ab$((echo hello) | tr e x)cd' test, ala "$(()) isn't ALWAYS math" (which the Defective Annoying SHell gets wrong, by the way). The test is doing $() as a subshell and then (echo hello) is another subshell, and then within the second subshell echo is a builtin, hence all those unclosed fds because it's two forks deep and still hasn't done an exec, and dumping out the filehandles to see why the pipe isn't lining up is where I noticed all the extras.

The problem I'm trying to fix is the fds aren't lining up: the output of echo isn't going into tr (thus it hangs), and echo exits basically immediately (which it's supposed to, it put data into the pipe buffer and exited), but if I throw a pause() in before its exit the pipeline doesn't continue to _launch_ the tr, which... either there's a vfork() missing or I'm putting the pause() in the wrong place?

Ah, there's another design issue: running echo as a shell builtin (because it's MAYFORK) is problematic because if the echo output blocks (pipe output longer than 64k, write to a FIFO...) the shell won't continue assembling the pipeline. Output to stdout is probably ok because | should stomp that even if it's redirected? Hmmm... no, it doesn't:

$ echo hello > potato | cat
$ cat potato
hello

The | redirects occur before > redirects (gotta add a test for that and make sure I've got that order right, I think I did) which means the echo can DEFINITELY be redirected to blocking output, and echo blocking should not prevent the rest of the pipeline from spawning (especially if the rest of the pipeline is reading from a FIFO that would unblock it).

So mayfork doesn't count in a pipeline, only nofork. Right...


March 19, 2021

You know how the coasts are getting pummeled by global warming and housing there is destroyed every couple years but they have federally subsidized insurance so they just keep rebuilding and getting big insurance payouts? (Last Week Tonight did a great piece on it a few years back.) Well that was scheduled to be fixed until Chuck "Boomer" Schumer derailed it. The GOP cannot disappoint me, but the Boomercrats INTENSELY disappoint me. (Yeah yeah, I know, they're Good Cop.) Can we give the septuagenarian senators a gold watch and a boot out the door already? Yes I'm aware this would disqualify Bernie and Warren but I'm happy to accept that collateral damage. This is not a new concept, it's a thing we ALREADY DO. If you can't be a senator YOUNGER than 30, you shouldn't be able to be one OLDER than 70.

Sigh, I guess the $300/month child credit is a START towards basic income. (The same way the $1400 tax credit could have been mailed out as $116/month over the course of the year and ALSO been a start towards basic income?) Raising children is basically a full time job, and expecting parents to work and raise kids means working multiple full-time jobs. (And then having to work two jobs because the first doesn't pay a living wage means it's THREE jobs.)

The Boomercrats can't imagine NOT means testing it, of course, even though it's SUCH an old and obvious idea that the guy Buckminster Fullerines are named after had lovely things to say about both basic income and bullshit jobs, and he died in 1983! Just give it to everybody already, and tax the rich. You get it back in taxes, not by forcing everyone to jump through hoops to prove worthiness for basic services. Means testing is just a way of NOT DOING it. When you call the fire department you don't have to spend half an hour confirming how worthy you are of assistance. Your kids get to go to school no matter who you are. When the rich refuse to be taxed, legislate guillotines until the objectors run out.

Not that funding UBI is the only reason to guillotine the billionaires. For reference, Mackenzie Scott is an excellent example of how to billionaire: "this is how fast someone with a soul can reasonably be expected to get rid of excess money". She's finding good homes for a billion dollars per month, at which rate she'll work through the $60 billion she got in her divorce in 5 years, and STILL have enough hundreds of millions of dollars left to live in ridiculous luxury for the rest of her life. 5% annual interest on $900 million is $45 million dollars per year, which is enough to provide a six figure income for an entourage of over 400 people working full time to make her happy. Heck, she could run a small college on that amount. There's a difference between "wealthy" and "obscene", and "Billionaire" is over it.

Late Stage capitalism really is the 99% vs a tiny fraction of 1%. People who SEEM like they're doing well, such as franchise owners, turn out to be micromanaged, deep in debt, and living from paycheck to paycheck just like everyone else. Most of the time your boss isn't the 1%, and neither is his boss. The whole precarious edifice is kept in place by having each exploited layer cling to its place in the hierachy and outsourcing the opporession. It's a giant Boomer scam. (Speaking of "follow the money", a thread about prosecuting Trump's money laundering. And speaking of specific Billionaire passion projects: Tesla continues to set self-driving back every year: they didn't invent anything, they're just buying competitors and badly copying things in a dangerous slipshod way. And twitter remains bad at being twitter.)

Still watching Boomers across the pond drag down the UK. Even europe's safety net is stretched thin these days. Of course the Boomers are literally starving students. Civilization in the hands of Boomers is terrible to everyone except their greedy selfish selves. Meanwhile, Esquire Magazine has written off the GOP as "white noise" with "nothing left to offer".

In britain and its ex-colonies "first they came for" starts with brown people (the designated scapegoats) and continues with sex workers, transsexuals, homeless.... The point is to establish precedents for "people can be treated like this" on the vulnerable, and then use that precedent elsewhere escalating until it covers everybody except your new kings. Racism is about systemic bias, brainwashing people to have knee-jerk reactions just greases the way for things like "civil forfeiture" and "qualified immunity". Defund the police.


March 18, 2021

I considered emailing Elliott to point him at this comment in case he felt like explaining, but decided against it. Arguing about the differences between public domain equivalent licenses is somehow META-useless. The whole reason to use them instead of public domain ADJACENT licenses like Apache is so they collapse together and you don't have to do exactly this sort of thing. (He says having posted to the thread twice, although in my defense I was asked to comment by another developer.)

That said, I noticed the recent Android license text change independently, and admit to curiosity about the three bugs mentioned in the linked commit, enough to follow my own advice and try to view said bugs on google's website. Ordinarily I don't bother because the link is a google account login page, but this time I broke down and logged into my work google account (which $DAYJOB pays for!) and got "access denied" instead. So that's nice.

Darn it, toysh has an order of operations issue vs bash. I have a test:

sh -c 'a=${a?b} > walrus'; ls walrus

Which is supposed to NOT find walrus because expanding the prefix assignments hits the ${a?b} which aborts the shell before performing the redirects, so it never creates the file. But I have ANOTHER test:

a=a${} b${}

Which complains about b${} not a${} proving it evaluates the body variables before the prefix assignment variables.

The problem is expand_redir() does both the variable expansions AND the redirects, because the granularity and liveness analysis are funky otherwise (<$X takes the FIRST chunk of $X if it expands into multiple words, but if $X expands to start with < it isn't special: <$X "<$X" and <"$X" mean 3 different things). That's CONCEPTUALLY hard to split up because my design deals with information as it's generated rather than encoding and preserving it for later passes to deal with. Not having multiple redundant passes makes it smaller and simpler... and means it conflicts with what bash is doing here, which wants to do stuff "between" two steps that are only one step in my implementation.

Of the two cases, I prefer to get "a=a${} b${}" wrong (barf because the prefix assignment had an error before barfing on the body) because that's just the error message and I've never promised to match those exactly. (It catches all the things that are wrong, the question is what it notices is wrong _first_.) And that's what the code WAS doing... until about a week ago. In the recent giant hairball I refactored run_command() rather a lot to make it work the other way (to match the SECOND test), and now I have to undo it again because it caused regressions in my existing tests. Grrr. It's always the error recovery paths that are fiddly to test and full of corner cases and sequencing issues:

$ readonly abc; abc=123 echo hello && echo ran=$_
bash: abc: readonly variable
hello
ran=hello
$ xyz=${} echo hello; echo nope
bash: ${}: bad substitution
$ echo ran=$_
ran=ran=hello

I still need to get all the REST of that right. (Which I mostly have, for prefix assignments we ignore errors from setvar but not expand, except ${} is a syntax error that aborts back to source context and ${a?b} aborts back to global context and I don't have a way to distinguish those yet. Working on it...)

P.S. Of course the test I've now decided not to try to pass is the one I added regex support to the expect implementation in the test suite for. That's good infrastructure and I expect to use it in future so it stays, but in the meantime it makes it infrastructure in search of a user, which is bad. My recent commit adding the first ~80% of shell function and local variable logic also reverted the only user of the zero prefix argument support and THAT I'm not as sure should stay. Yeah it works fine, but infrastructure in search of a user will bit rot before finding one. This got tested and _was_ load bearing, but is not currently being regression tested and code will change around it...


March 17, 2021

Oh good, enough people shouted at Biden until the old geezer finally acknowledged the fillibuster needs fixing (in this case to make it work like it did in "Mr. Smith Goes to Washington" again, a movie that came out 3 years before Biden was born). A big difference between this septuagenarian and the previous septuagenarian is this one's surrounded himself with less-terrible people to "remind" him of what he was in the middle of when he forgets. I still think that if you can have a minimum age of 35 to be president, you can have a rule that says you can't be on the ballot after you turn 65. (Serve out your term, but you can't RUN anymore.) This would have knocked out Biden, Trump, Reagan, William Henry Harrison, and James Buchanan, and would have denied Eisenhower and Andrew Jackson their second terms. Harrison died 31 days into office, Buchanan was a disaster mitigated only by how ineffective he was, Jackson was the most ignorant racist ever to be president until recently, Reagan dismantled half of FDR's New Deal, buried the country in debt, and got Altzheimers in office, and Eisenhower did ok but grew increasingly ineffective as time went on.

Solar got 90% cheaper over the past decade while nuclear got 30% more expensive. Meanwhile demolishing a nuclear reactor that HASN'T melted down costs a billion dollars each, and the decades of nuclear waste they create is currently still stored on site in each reactor building because it's too dangerous to transport. Please don't build more of them.

A good thread on how how hilariously bad this NFT thing is. Blockchain automates the functions of a notary public, except it's got a "garbage in garbage out" problem. NFT reinvents "pedigree papers" with the exact same garbage in garbage out problem. And both are based on wasting CPU cycles to prove your worthiness, in a collective dick measuring contest that constantly eats more electricity than most countries. (There are 195 countries and if bitcoin was a country it would rank 30th in energy consumption, between norway and argentina. Energy literally wasted because that's what the protocol is DESIGNED to do.)

Native americans are better people than europeans. This is nothing new, 300 years ago native culture was so attractive european settlers left en masse to "go native" (resulting in a lot of restrictive laws, posted guards, and military attacks on native settlements to drive them too far away for colonists to easily reach). European diseases were what destroyed native culture, we only "won" by being fundamentally filthier than the american natives. (Diseases very much plural: smallpox, malaria, tuberculosis, cholera, typhoid, rubella, scarlet fever, yellow fever, pertussis, measles, bubonic plague, anthrax, diptheria, polio, dengue, staph, strep, syphilis... this is not a complete list and even stuff like "chicken pox" and "influenza" were killer pandemics among people who'd never encountered them before, plus we introduced invasive earthworms, tetanus, and botulism to the soil and a chestnut blight that killed billions of nut-producing trees, slaughtered millions of buffalo and left them to rot in the fields...) These days those things would be considered obvious war crimes. Especially what the british did, who were nazis centuries before germany got there (and are currently returning to their roots).

I am deeply disturbed by our failure to teach "humanities" in schools anymore, and go "Stem Stem Uber Alles" instead so we can all be Werhrner von Braun. Those who don't know history are doomed to repeat it: our ancestors did things we need to unpack. The foundation of "conservatism" is denial. It's an IMAGINED past they wish to return to, and the insistance that everything they can't cope with since Mommy stopped cleaning their rooms and Daddy stopped paying all the bills must be a RECENT development meaning the whole world changed for the worse around them and nobody else noticed, because clearly there can't be anything wrong with THEM. American "conservative" prudishness has been standing astride history screaming "no" for a century. (I wonder which of those old films are available streaming?)

Here is an excellent article titled "how the childish masculinity of aging men took over America in 2018". And here's a thread about how the US Border Patrol engineered a fake crisis in 2000 to elect Bush, and then compared it to what they did in 2016, "intentionally slow-walking the process to create a backlog" making immigration look bigger when it was down in real terms.

As outrage mounted against the Sacklers, who made made billions by causing the Opiod crisis, they decalred bankruptcy to shield their assets from lawsuits. Now they've asked to be let off with a fine, gradually paying out some of the interest their billions accumulate each year so they get to stay rich and their victims get to stay dead. While admitting no wrongdoing and keeping control of their overseas subsidiary companies. Oh and only half the settlement is cash, the rest is discounts on the drugs they'd continue to sell. They first admitted illegally marketing opiods to addict people in a 2007 plea deal, and 14 years later they're still evading justice.

The vatican just confirmed it's still too backwards to accept gay marriage, despite New Pope. Plutocracy corrodes democracy and is built on greed. Boomers are trying to psych gen-x into doing what Boomers want them to. Seems profoundly unlikely to work: we wanted them dead _before_ it was cool.

The carceral state reaches its fullest expression in North Carolina, where state law allows it to press criminal charges against a 6 year old for picking one flower from a neighbor's yard (presumably as long as the child is brown).

Defund the police, UK edition today. Still plenty of reasons to defund them here in the states, of course, such as a skinhead sheriff talking about how understandable he finds the Atlanta shooter going on his murder rampage. Even the Onion has trouble parodying their profound incompetence and/or willful ignorance. Of COURSE that perpetrator is a white male christian described as "big into religion", which clearly helped drive him murderously crazy and full of racism and sexism. The fact they see this as a feature rather than a bug is why christianity is imploding.

Oh hey, the dust bowl's back, both in Austin and in China. You notice how the natives happily kept their land intact for tens of thousands of years, then european capitalism comes in and creates deserts within a few decades. Yes that applies to china too: Mao The Dong pushed out the original government of china, which fled to Taiwan, and did his "great leap forward" killing millions. (He did this in the wake of Britain selling Opium to china for years and filled his head with western education to fight back against it, did you think he'd independently invented "communism"?) The current guy is Mao's successor, ruling via arrests and censorship and concentration camps. The west has a nasty tendency to export fascism, but usually pretends it isn't. Calling fascism "communism" is just like the modern rebranding "neoliberal": nazis always pretend to be the exact opposite of what they really are (to blame their failures on their opponents), all the way back to right wing goose steppers spouting racism under the banner of "national socialism" when it was the exact _opposite_ of socialism. This technique is called "The Big Lie".

Tesla continues to set back the cause of self-driving cars. It's not enough that a thing exist, the rich white male manbaby must take credit for it. If he can't be seen to be solely responsible for its success, he will tear it down to delay it until such time as he can take credit.

Perpetually incompetent failsons are like middle school students making a show of rummaging in their backpack for homework they didn't do. These parasites hurt their own supporters the most, but see The Big Lie above. Fascism tends to interlock (the way hitler and mussolini supported each other's Big Lies), these days the GOP is propped up by Russian propaganda, and as always the trick is to follow the money.


March 16, 2021

And today I forgot to bring my charger cord to the table. I'm good! (Luckily, battery was more or less fully charged when I got here, so...)

The $PWD in pwd.c problem turned out to be a non-problem, it's exported by default and only gets to the other command when exported. Redid the run_command() logic to use a function context for prefix assignments.

But "$_" is... really annoying. It's getting set _twice_:

$ x() { local _; declare -p _;}; x; echo $_
declare -- _="_"
x
$ env | grep '^_='
_=/usr/bin/env

After a call's been made "$_" points to the name that was called, but the exported variable set to the child process has the full path of the resolved executable. BUT it turns out I already implemented the second part of that in sh_exec() and forgot, so I just need to have run_command handle the other part of it and we're good. (A lot of this is just becaue I've been away from parts of the code for long enough I have to re-familiarize myself with the near-fractal level of detail this stuff needs to match what bash is doing.)

I was asking Chet another question, and answered it for myself while typing it up:

> > But I've taken up way too much of your time already...
>
> I don't mind.

Thanks for your patience. In that case, could you explain why "${1: -1}" only SOMETIMES gives me the last character of "$1"?

If you clone the github.com/landley/toybox repo and add this patch to my test scripts (yes, I've implemented "expect" in bash):

diff --git a/scripts/runtest.sh b/scripts/runtest.sh
index 6aad9ff1..87ce44ad 100644
--- a/scripts/runtest.sh
+++ b/scripts/runtest.sh
@@ -215,6 +215,7 @@ txpect()
       [OE])
         [ $LEN == 0 ] && LARG="" || LARG="-rN $LEN"
         O=$OUT
+echo 1=$1 slice=${1: -1} and=$1
         [ ${1::1} == 'E' ] && O=$ERR
         A=
         read -t2 $LARG A <&$O

and then "TEST_HOST=1 make test_sh | grep '^1=' " the slice is empty unless $1 is one character long. It's not doing that from the command line, but it is from the middle of this script, and I do not understand why. (This is using devuan ascii's bash, 4.4.12, yes I need to upgrade...)

I hit this trying to add regex matches to scripts/sh.test. I have bunches of tests I need regex support for because my error message strings do not match yours exactly, but some tests are on stdout and stderr, which right now is E$'string' or O$'string' and I wanted to add RE$'regex' and RO$'regex'...

Which is the point at which I realized most of my test strings have \n at the end of the $'string' block which means the "last char of string" is giving me \n which is whitespace and looks like nothing if you're not paying attention. (Especially given shell variable resolution's tendency to strip trailing newlines from results, and yes I already implemented that.) I.E. the payload is still attached to the prefix so I'm getting the end of the PAYLOAD not the end of the PREFIX. Oops.


March 15, 2021

Didn't make it out to the table last night, did a fresh full backup instead, then got an hour call from Jeff, then talked to fuzzy and lost an hour to daylight savings time until I'd basically be heading right back when I got there (and we wanted to go to the farmer's market when it opened, it's open air and neither of us has been there since early last year due to the pandemic, but time to plant tomatoes again and they've got some nice varieties).

Today, I opened my laptop at the table to another dead battery. (It was fine when I left. It either failing to suspend, or waking up in my backpack and draining itself on the walk.) Didn't lose much this time (couple half-finished emails), but it's kind of annoying... huh, except the charging says the battery is near 100% shortly after being plugged in. Maybe the battery's loose in its socket? Hmmm... (Also, it's COLD tonight. Two days ago it was warm enough I needed bug spray for the mosquitoes, and today I need gloves which I didn't bring because it had been so warm. I'm told colorado is having another blizzard...)

If you mentioned "memphis" on twitter today, your account got banned. No really. Twitter remains REMARKABLY bad at being twitter, and I expect the streisand effect to kick in on whatever they were trying to hide.

And the first google result for companies like Cricut should be people complaining about them.


March 14, 2021

Plants have seeds for a reason. A million plants that are all cuttings from the same plant will all die from the same disease, generally all at once like the Gros Michel banana did (and cavendish is doing). When it's something like apples or avacadoes that don't breed true, you resign yourself to losing varieties. But when the plant DOES breed true from seed and commercial growers don't bother, that's a self-inflicted wound (well, capitalism-inflicted). Sometimes you get a disease that essentially wipes out a species, like north american chestnut blight or dutch elm disease, but giving it a billion identical plants to breed in first is just asking for trouble.

Sigh. My laptop had a dead battery when I opened it. Lost all my open windows, including rather a lot of shell tests I'd run on the command line but not turned into proper tests yet. (Command history in a tab.) Oh well, that makes upgrading to the next devuan release easier, but I should do a full USB backup first.

Speaking of "interesting vs lucrative", defining "interesting" is a can of worms. It's not _exactly_ "useful", because lots of things are useful in a busywork way. Carrying buckets of water from a stream was useful, inventing plumbing was interesting. Working as a telephone switchboard operator was useful, inventing rotary dialing was interesting (then touch-tone, then cell phones, then smartphones, and now it's all VOIP and Zoom). Working as a stevedore was useful, shipping containers were interesting. Driving a truck is highly useful today, self-driving vehicles integrated with rail/ship containerization on one end and delivery drones at the other is very interesting.

Treating symptoms vs curing a disease. Solving a problem means it's not a problem anymore: if somebody else has to do the job after me, then the job's not done. But this is antithetical to capitalism, which invents busywork, creates scarcity, and inserts middleman parasites with perpetual ongoing relationships where they don't belong (software as a service, for example). A system that defines "a shortage of work" as a CRISIS rather than letting people live in idle luxury and find their own meaning (such as tackling problems never previously addressed because we were too busy just surviving) is a broken system that has BECOME the problem and needs replacing.)

I've personally never been in danger of running out of things to do, quite the opposite in fact. I keep bumping into areas that are impossible at the time which get addressed years later but often just to the "it's black magic only a cabal can do", not "you can make your own from scratch as a middle school project". And even when I more or less beg people to steal my todo items, many remain undone a decade later.

C and Unix are still the basis of the modern world 50 years later because they were simple and correct: they basically solved a certain class of problem. Writing your own posix OS from scratch has been done by dozens of people, and is a common college project (and college course). Writing your own (non-optimizing) C compiler isn't that hard either (although fewer people do that these days because C++ has spread so much FUD about C over the years, and writing a C++ compiler is NOT a reasonably scoped student/hobboy project).

For years I've had my own corrollary to Moore's Law, that 50% of what you know is obsolete every 18 months, and the corrollary to THAT is "with Unix it's mostly the same 50% cycling out over and over", so it was manageable. Unfortunately there's maintenance work to defend that base from people who think systemd is a good idea, and there's a lot of adjacent "python 2 -> python 3 breaking all installed programs" nonsense that tries to intrude into the base (hence my perl removal patches to linux-kernel). "Mostly" doesn't mean the base is entirely static: there's some inevitable a.out -> ELF, 32 bit -> 64 bit churn over the yars. It's only MOSTLY the same 50% cycling out, we do add openat() and friends to the base, large file support, y2038 problem, SMP, utf8...

In theory defining that base would be Posix' job, if the Posix committee didn't suck at it. LSB tried but got eaten by the Linux Foundation. Linux From Scratch is a pragmatic implementation, but it's sadly full of GNU bloat.


March 13, 2021

Booyah. Maybe not a first choice, but all you need is an attourney general to make the machinery functional again and attack the rump of the successor to the whigs and federalists until it's time for party #4. (Or instant runoff voting so we're not forced into a 2-sizes-fit-none party system, but the Boomers have to die first.) All biden has to do is enforce the existing laws, but of course the GOP knows it's in a death spiral and is doing the wounded bear thing to prop up plutocracy just a little longer.

This analysis of the covid stimulus bill says less than 1/4 of it is those $1400 checks, meaning we _could_ have had $700 checks every month for the rest of the year but Boomercrats decided to do something else instead (and means test everything). Some of it they did as childcare checks, but "you're a citizen, you get basic income too, it just goes to your parents until you're emancipated" is not a complicated concept if you're not a Boomer? The easy way to deal with debt fearmongering is to repeal the Rump tax cut for billionaires. That's the obvious immediate response to every mention of that issue.

Remember the ten year gap between Hurricane Andrew pummeling Miami, Katrina flooding New Orleans, and Harvey flooding Houston? Tropical storm Beta flooded houston again last year (as Weird Al said, "Hurricanes past the letter Z"), the same year year Minnesota had its worst heat wave on record and a Derecho flattened houses from Cedar Rapids to Chicago. This year Texas was shut down by the blizzard, LA is getting thunderstorms, Hawaii is currently flooding, and it's only MARCH. The weather isn't just getting worse, the RATE the weather is getting worse is increasing.

Microsoft continues to suck. It punished its userbase for not using internet explorer, it punished them for not using msn.net, now it's punishing them for not sending all your documents to microsoft's cloud. (Alternate headline, "Using microsoft software kills 1500 people". That's how the #2 and #6 richest billionaires in the USA made their money. The #3 richest billionaire made his money from Faceboot, here's a good article about how it's so broken the people who did it say it can't be fixed (fundamentally the same problem as Boomer Media, except entrenched in both the tech infrastructure and business model).

Boomer Media sucks even more than you'd expect, its "both sides matter" reflex is outright pathological.

Disney literally just assigned two white men named bob to head its diversity initiatives. (Of course both are Boomers, why do you ask?)

Every accusation a confession: snowflake edition. The GOP serves plutocrats and ONLY plutocrats. Of COURSE the GOP's pandemic loans from a year ago funded the Capitol rioters, often disguised as " charities". Their racist misogynist culture scrapes together enough votes for each decade's Billionaire Bailout.) The Squad opposes this but the Boomercrats... also serve plutocracy, and are thus conflicted. Good Cop is on the same side as Bad Cop, only their methods differ. As the GOP collapses in a cloud of voter suppression, the Boomercrats yearn for a more plausible Good Cop to stand next to in service of plutocracy.

Plutocracy bleeds people dry under penalty of death. Plutocracy is the inevitable result of capitalism, hence the "late stage" part. Capitalism recreates feudalism with corporations as kingdoms and employees as serfs, the divine right of billionaires. Of course the largest billionaires profited the most from the pandemic, highlighting the need for guillotines. And as oil companies unravel all SORTS of stuff is coming to light.

Defund the profoundly useless police, here and in the UK.

Christianity is fascist, which is why they've merged with the GOP to form Voltron Captain Planet "White evangelical racism".


March 12, 2021

Ha! I was answering a question for Elliott which led me to try to find out what I was so distracted by on June 22, 2019 that I'd let in a patch with at least 3 obvious problems. (Mostly likely I left a tab open to remind myself to do a follow-up fix patch, and then my battery died or something...)

My blog jumps from the economics of rooftop solar+batteries on the 20th and 21st to mentioning a toysh checkin on the 25th, so I dug into my twitter archive and wouldn't you know it, the next day had the recipe for fixing the sound from a previous time Linux decided it should just arbitrarily stop working. Ha! (My sound's been broken for weeks, I keep meaning to clear enough windows to reboot, but that's for upgrading from Devuan Ascii to current more than fixing audio. Still, yay audio. I dodn't have the right headphones with me today to use it, this laptop still hasn't got working bluetooth, but I can try to dig some up at home.)

At the moment I'm out at the table, still working on toysh almost 2 years later, ripping out the live xsetenv() global variable management and replacing it with "create a new env array at exec time" which is yet another "pull the thread and the sweater unravels".

My todo list runneth over because working through my todo list spins off more todo items faster than I implement them, but usually I can fling them on the list rather than have to close a can of worms before i can check it in again. (Because it doesn't RUN otherwise. What's currently there sort of works, what's there now does not because the design assumptions don't line up so there's handoffs to nowhere.)

Wince. Just just got email from a recruiter with a job I could easily do offering $180-220k/year. That's hard to turn down, although I almost certainly will. (Work did finally pay me on tuesday. Not even half that. Not even a third of that. But I can afford to keep doing what I'm doing one more month.) I really want to see this technology succeed, but it would also be nice to pay off the house and even retire someday. Elliott did eventually get back to me to with a pointer to Google's Open Source Funding page and the advice that I join an existing corporate entity that's already approved by the Google bureaucracy. I haven't done anything about that yet. Nor have have I cleaned out the spare room to rent it out on AirBNB, which my household has discussed. Nor have I tried to advertise my patreon (or updated it, which I REALLY should do but I'm trying to get a toybox release out). And unfortunately the notes from my conversation with Stephanie Hulburt were in my twitter DMs, which are inaccessable as the rest of my account. Sigh, I know how to fix this but keep just doing the work that's in front of me as long as the lights stay on, and as with upgrading my laptop tend to only address this sort of "laundry and dishes" side issue when it's either hard to ignore or becomes a problem for somebody other than me.

My entire career I've chosen to go for "interesting work" over "lucrative", but sometimes David Graeber's observations about late stage capitalism literally PENALIZING work that's good for society by insisting it can only be done in poverty (or as a volunteer sideline from your REAL day job as a member of some billionaire's entourage accomplishing nothing except to make them feel more important) rings true. (Graeber offered real, convincing fixes for what was wrong with America, and was starting to gather quite a following. Then he married a Russian and was suddenly and mysteriously dead within a year.)

Meanwhile Fade, up in grad school with good healthcare, got properly diagnosed with ADHD and is on meds for it now. (I was diagnosed as "hyperactive" and "gifted but unfocused" as a child, and was told I'd grow out of it and needed to try harder.) They just introduced her to Aderall. One of the first things she did on the new pills was put away the accumulated pile of clean laundry on the couch (her roommate went home over summer break and has been "returning next month" ever since). I am aware of the parallels.

And I found another bash bug (in devuan ascii, so who knows what current is doing):

$ exec could_not_find 2>/dev/null || echo yes
yes

Does not give your prompt back, does not respond to anything else you type, ignores ctrl-c, but but does exit if you ctrl-d. Broke down and emailed Chet because "bug report" is a reasonable reason to do so.

Sigh:

$ git diff toys/*/sh.c | diffstat
 sh.c |  946 +++++++++++++++++++++++++++++++++++++--------------------------
 1 file changed, 559 insertions(+), 387 deletions(-)

I REALLY need to get to the point I can check this in, but sh_exec() was using run_subshell for stuff it can't execve() (I.E. when you tell it to run a shell script that DOESN'T start with #!/bin/bash so the kernel doesn't know what to do with it), and I converted it to instead use xexec() with the command line rewritten to start with "sh" and "--" as the first two entries. Because A) it shouldn't fork an extra time, B) it's NOT a subshell, which would inherit the local variables and function stack visible with ${FUNCNAME[@]} which this doesn't. (And yes $() and <() both _do_ inherit those, and yes I should add tests for all of this...)

Ah, Chet replied to my email and pointed out that exec's redirects persist in the parent shell, even when it tries and fails to run something. (I didn't know that characters you type are echoed back on _stderr_ not stdin. Huh. I should add a test for that.)

Going through I also hit my code not looking up each existing variable before performing prefix assignment exports, meaning "readonly abc; abc=123 env" wouldn't error out. (Need to add a test for that.) And there's other flags I need to implement to force the contents to uppercase or integer only and such, which should also be honored here (all the declare stuff). Hmmm... I think what I need to do is create a new temporary function call context, look up each variable and create a whiteout with the same flags if found, and then do the assignment through the normal assignment mechanism. Which seems awkward (allocating a "name=" stub and then freeing it and replacing it immediately), but I want to reuse the sh_exec() infrastructure that's converting the sh_var array visible_vars() returns into an environ[] array execve() can consume... Ah, duh. Of course: have the whiteout stub added to the new function context be the full new string with VAR_NOFREE in the flags. Then the set function can pass the same string back in, and abuse it as necessary with toupper and such having forgotten the previous reference to it but not freed it.

Next problem: if toysh isn't keeping environ "live" (exports putting stuff into it immediately) but instead assembling a new environment variable list before calling exec, shell builtins aren't getting an updated environ list. Right now the only shell builtin that cares is pwd (which check $PWD). I suppose I could special case that variable the same way I have $IFS (to update TT.ifs), so when it's updated it goes into environ[] immediately?

SOMEDAY I WOULD LIKE TO CHECK IN THIS COMMIT. It has to stop spinning off TANGENTS for me to do this.


March 11, 2021

Slavish devotion to the GPL has turned Linux into a giant unmanageable hairball the exact same way it it did for GCC. The Linux kernel refused to have a stable internal APIs (allowing modules to be portable from one version to the next) the exact same way GCC's explicit refusal to have a stable internal API turned THAT codebase into a giant unmanageable hairball. In both cases, the explicit motivation was licensing (to allow the GPL to contaminate as much code as possible) which saw an API barrier to copyright (my code isn't a derivative work of yours if there's a stable documented interface between us) as a threat to their licensing model. The developers did something FOR THE LICENSE that was bad FOR THE CODE, with bad long-term results.

Sigh, I could write a long thing about how code being modular is an important part of maintainability (and scalability, whether to large line counts or long maintenance times or many different deployment environments, all surprisingly similar scalability issues), but I have too much else to do. IETF used to demand two independent interoperable implementations before calling something standardized, and many years ago I contributed material to a chapter about that in a book on unix design. (Back before Eric Raymond went the way of all libertarians, he and I had a productive working relationship.)

The tl;dr is gcc is being replaced by llvm and I expect Linux to undergo a similar fate at some point for similar reasons, but they're a number of years behind on the ossify-into-a-loon curve. Quite how many is unclear: Stallman was born in March 1953, Linus was born in December 1969, about a 16.5 year gap. GCC started to go off the rails in 2007 (port to C++, switch to GPLv3, launch of LLVM) and Stallman resigned in 2019. That implies Linux might start going off the rails in 2023 or 2024, with Linus' retirement around 2035... but RMS was already demonstrably nuts back in the 90's? Hmmm... Linus is historically pragmatic and technically driven, and seems more likely to age like Ken and Dennis than like Bill Joy. The thing is, it's really Greg KH who's the license nut turning the project into an unmanageable hairball, and I dunno how old he is or how long he'll remain in Linus's shadow?

This is why I do 0BSD. I should really try to promote that more, but my todo list runneth over and every time I've submitted a talk proposal about it to a linux conference it was never a topic they selected.


March 10, 2021

Yesterday I got the variable stack installed and got most of the code converted over to use it, which cleared up a number of TODO labels I had lying around, and now...

There are times I need to list all currently visible variables, WITHOUT DUPLICATES. I think I need to make an array and perform an insertion sort. This kind of raises the question of whether the variable arrays should always be kept sorted (reuse the plumbing), but... not right now. This commit is a can of worms at a _design_ level.

I leave a bunch of little notes-to-self in the code and then delete them again as I go. A current one is "TODO VAR_NOFREE whiteout x= truncate lifetime" which means NOTHING to anybody else, without a lot of backstory. The explanation is: I don't want to unnecessarily duplicate the environment variable string data inherited from exec, but having it in the same array as malloc() data is awkward because it's not part of the heap so I shouldn't free() it when a value is replaced or unset. The lib/env.c plumbing has a counter of "number of variables at the start of the array still pointing into the heap", but that wasn't flexible enough for the shell variable stuff which needs flags (readonly, integer, convert to uppercase, etc). So I have struct sh_vars array with a flags member, and added a "VAR_GLOBAL" bit to indicate that this variable was part of the environ[] array, but I kept the environ[] globals updated each assignment so the setup for exec() had less work to do. (The globals were _already_ exported, thus running commands was fast.)

And THEN I started implementing functions, which included local variables, and you can have GLOBAL LOCAL VARIABLES and there are whiteouts* too (there can be a global you CAN'T SEE right now because a local was unset, but when we return from this function it becomes live again; I have yet to find an "unlocal" command that restores access to the non-local version of the variable without returning from the function, and I should poke Chet about that but I don't want to bother him).

And THIS means that the old VAR_GLOBAL updating environ[] live isn't good enough, it's easiest to create a new environ[] array each function call with what's visible NOW and feed it to execve() as argument 3. (Or just swap the environ pointer and put it back afterwards. I'm not copying the string data, just the pointer array, and I have to do that anyway to modify it in a non-persistent way.)

If I still want to avoid calling strdup() on every global variable inherited from the environment each time you start the shell, I need a VAR_NOFREE flag indicating it's from somewhere else, but right now when you unset a local (turning it into a whiteout) it'll truncate the variable right after the 0 and realloc() it to free the memory. (Well it could be really long, I don't want to leave potentially kilobytes or megabytes of gorp inaccessable but still allocated.) And I can't do either to a NOFREE because it's not my memory. And that was the note, reminding me to fix that up before checking this in. (I.E. add a NOFREE test on the truncate in unsetvar(). Which I have now done while typing this up by the way, so the TODO got removed. But that's what it meant at the time.)

Back when I was first writing a proper tar for toybox I left a bunch of these todo notes-to-self in the code rather than stripping them out before checkin, and people started arguing with me about my own TODO notes (and submitting patches removing them because they THOUGHT it had been addressed because they didn't understand what it meant), so I yanked them and have mostly kept that sort of stuff private ever since. Which is unfortunately a large pain in the pending directory because I need to snapshot the file, delete the TODO entries, make a diff, check in the clean version, and then apply the patch from the diff to get my working copy back. But it's far LESS time than arguing with people who don't know what my note-to-self meant. It's unhygenic to check stuff into the public repo that I don't expect other people to interact with, the famous "you are not expected to understand this" comment circa Unix v6 is not something to emulate.

(I mean, I can still be annoyed when someone won't take no for an answer for a full year. But mostly the burden is on me to explain what I'm doing and make the code readable. Which is part of the reason I do so much cleanup. It may be CONCISE, but should not be difficult to understand if you stare at it long enough. All the answers need to be there, and when they aren't it needs comments or git commit messages or sections in code.html and design.html and the faq and such.)

*One slight problem with having a VAR_WHITEOUT is every time I read the macro the Surfaris song** starts going through my head. But that's just an idiosycrasy of my brain. My pathetic superpower is telling you the song just about any short phrase can be sung to. Forex: "My pathetic superpower" can be sung to "hit me baby one more time".

** Usually Honoka and Azita's ukelele version.


March 9, 2021

Welcome to 2021. The FBI is officially investigating which members of congress aided the insurrection, and it's being reported on by Vanity Fair. (Not that it's a big secret which ones were involved, but proving it requires legwork.)

The low birth rate is because capitalism. Late stage capitalism is a death cult that isn't just killing people, it's preventing them from being born en masse.

A few days ago John Rogers linked to an amusing thread about somebody breaking into unsecured online security cameras. (Something my friend Mark used to do back at the University of Texas ~10 years ago, for a definition of "breaking in" back then that was "completely unsecured, just point your web browser at this IP and it shows you a live feed of the classroom".) Well it looks like it's escalated to the point there are news articles about it. Rule 17 strikes again (any data retained long enough will leak).

Texas has jumped straight from "blizzard emergency" to wildfire season. Don't forget the house-flooding monsoons. Welcome to climate change, this isn't the new normal yet, it's going to get far worse.

Oh hey, facebook found a new way to be creepy. Must be tuesday. Let's see... white supremacists are organizing fundraisers for GOP candidates so they can suppress black voters. Yup, tuesday. (Today's thing you didn't know was ALSO racist: property tax assessments. And here's an informative write up the GOP history of evil.)

Microsoft's been under a security attack for a few days now, but I tend to dismiss this as a constant thing? (You gave data to microsoft and expected it to stay secure? Why?)

The USA could replace 3/4 of defense spending with UBI and still have the highest defense spending of any nation.

Hands up everybody who's surprised the british monarchy is just as racist as the british empire was.

Remember how the DCCC was blacklisting anyone who helped primary a Boomercrat? They just quietly let that policy expire. (Personally, I'm still holding a grudge.)

Billionaire philanthropy is a scam, video interview edition.

Citizens United has allowed the GOP to hire Russian troll farms to post misinformation. No, they're literally doing that. Not really trying to hide it.


March 8, 2021

Sigh. Toysh is approaching 4000 lines. That's just too darn long, I should try a cleanup pass once I get everything working. (Yeah yeah, forward looking statements...)

I broke down and am redoing the variable plumbing to implement local vars (I.E. moving TT.vars into TT.ff->vars so it's part of the function stack). I wanted that to be in a separate pass to keep this patch less unmanageable but it just doesn't make sense to have it NOT be part of this change. I once again hit the "magic variables are resolved at export time" issue I had a long thread with Chet about last year, but... it's wrong? $SECONDS and $LINENO both will produce the WRONG ANSWER if you do that. (And $RANDOM will be frozen.) Sigh, but that's what bash does...

Darn it, I hate hitting all these tangents. I'm implementing the "local" shell builtin command, and the obvious next question was when you "local abc" without assigning it a value does it count as "null value" or "unset" ala:

$ x=
$ echo -n ${x?fail}
$ echo -n ${x:?fail}
bash: x: fail

And as it turns out, it counts as unset:

$ func() { local potato; echo ${potato?bang}; }; func
bash: potato: bang

Which means it's creating a whiteout. Ok, easy enough to implement in the design I've worked out, but I want to add a TEST for this, which is slightly awkward because I don't want to try to match an exact error message (for one thing toysh isn't necessarily identifying itself as "bash" at the start of said error message), so something like: testing 'local creates a whiteout' 'func() { local potato; echo ${potato?bang}; }; func 2>/dev/null || echo yes' 'yes\n' '' ''

Except that fails, and the REASON it fails is that ${x?y} erroring counts as a syntax error which aborts execution so the "echo yes" never happens. But I recently worked out that those won't cross a "source" boundary, so I changed the func to "source input" and put the body in test argument 4, problem solved right? No, it isn't:

$ echo 'local potato; echo ${potato?bang};' > input
$ bash -c 'func() { source input; }; func; echo $?'
input: line 1: potato: bang
$ bash -c $'func() { source input; }; func\necho $?'
input: line 1: potato: bang

Now the error exit IS crossing a source boundary, and I don't understand what changed from last time. Which means what I'm implementing isn't necessarily right?

Ok, an ACTUAL syntax error ends at a source boundary, but ${x?y} is exiting any non-interactive shell. I don't actually have a control flow path for that. Hmmm... Add a TODO.

You can readonly a whiteout, at which point it doesn't count as a unset for ${var+value} but does for ${var?value}. You can export a whiteout, which means if it's LATER assigned to it's exported.

This is a can of CANS of worms.

Sigh, I suspect I should use a variable string that doesn't end in = (I.E. a bare name) in the list to indicate whiteout rather than having it be one of the flag values. But I have to change an unknown amount of plumbing to make that happen, and it's the auditing that's the hard part. If I was going through the code as a single pass changing just THAT I wouldn't worry so much, but the problem is my stack depth on change-suggests-change is so deep I don't have a good handle on what all the changes I'm making ARE. At the end I can examine a diff and audit m own code, but at what point do I get to check this IN? It's already been a month since I checked in "start of function call logic", which was itself a delta off of implementing $((math)) for some reason I forget. (I have an unfinished diff starting that which I might as well declare abandoned at this point, gotta redo it when I get back to that. I really wanted to merge the "expr" command in with the shell $(( )) plumbing, but... SEPARATE can of worms.

Right, I was looking at the flag list because export is inherited by local vars, and I wanted to see what other flags might be. (VAR_MAGIC isn't. -i and -u aren't. Looks like it's just export and readonly I have to check for. Sigh, "local" and "export" smell like they should share code, but I need to implement first and then see if the collapse together. Too tangled.)


March 7, 2021

Interesting thread about how Faceboot and Google's tend to collect mediocre white men. (I'm well aware I'm also a mediocre white man, I just try to find interesting things to do. I keep telling people I'm not particularly smart or talented, I'm just persistent.)

A basic thread about the history of copyright. On the one hand, authors are all arguing that if copyright goes back to "28 years with ability to renew for another 28", they will starve to death and their children die in poverty. On the other hand, capitalism is extending intellectual property law to the point the system is widely ignored with random draconian punishments meted out randomly, which is not a recipe for longevity.

John Scalzi also points out that universal basic income, rent reform, and medicare for all (or as england in the 1970's called it back when they HAD it before Thatcher tore it down: "the dole, sqatting, and NHS"), has to come _before_ tearing down intellectual property law. Because a lot of people currently depend on the broken system to survive. Of course artists and writers and actors, even including hollywood and video games, is only a small part of the money in IP law.

Some people refer to Boomercrats as "Vichy Dems", but the GOP remains self-defeating to the point even keystone Good Cop can occasionally beat them. The republicans insisted the stimulus bill be read alout for ~20 hours, and left for the night. In the absence of republicans, but with the Senate still in session, a few things were passed by unanimous consent. That'll do, Dems. That'll do. (Conservatives resent being adults, largely because they're so bad at it.)

Voter suppression isn't new but it is intensifying because that, gerrymandering, and racism are literally all the GOP has left.

Boomer media is going off the deep end.

March 6, 2021

Oh hey, is THAT how warp drives work? (I mean, assuming space is fluid.)

Toysh: I need to create the primary function call context (with the globals and the shell command line arguments) from sh_main(), then have "source" create another one but with a NULL (skipped) local variable context, and have actual function calls create a third with non-null locals.

Hmmm, I still have to deal with whiteouts:

$ x=a
$ one() { local x=b; echo $x; unset x; x=c; echo $x;}
$ one; echo $x
b
c
a

Once a local variable is created it seems to persist even if unset, I didn't spot a "local -d" or "unset -l" or an "unlocal" builtin or anything like that... Is there a way to get a local variable to STOP being a local? Other than returning from the function and ending the variable context...

There's a "declare -g" but it doesn't actually seem to work:

$ x=a
$ one() { local x=b; echo $x; declare -g x; echo $x;}
$ one; echo $x
b
b
a

It doesn't let me access the global x's value and it doesn't push the local's value into the global context. PLUS there isn't just ONE local/global context, EACH layer of function has its own variable context and the global one is just the last one you wind up in after searching all the others. So if you had one() call two() and each had its own local $x should a "declare -g" from two() give you one()'s context or smash all the way to the end of the stack?

I'm going to have to ask Chet again, aren't I? I kind of don't want to bother the poor man with all my weird corner case poking, I feel I should be done with this by now...

Oh lovely:

$ x=123
$ func() { local x=456; readonly x; echo $x; }
$ func; x=789; echo $x
456
789

You can have a local readonly variable. Of course you can. (But what you CAN'T do is turn an existing readonly variable local. Makes sense, I suppose...)


March 5, 2021

Another good explanation of why the Boomers can't adapt.

Here's an amazing graph showing the percentage of white and black voters registered to vote from the civil war through today. It went from near 100% in the 1886 election down to 10% with the grandfauther cloause of 1898, near zero with the poll tax of 1901, only started going back up in 1944 (as black GIs returned from World War II to confront Jim Crow) and has been faught against ever since. (Also, "I don't see race" is like saying "I don't see rape". It means they don't believe you were harmed, and will not help you. They're claiming the existence of people who were not harmed in the way you were harmed invalidates your complaint: some people were NOT run over by drunk drivers, have you tried being like them?)

The white supremacists (I.E. The GOP) have decied that asians are no longer white and are murdering them. The circle ever-tightens around a few billionaires and their immediate servants, using voter suppression to try to make women property again and reinstitute slavery with a murderous occupying police force serving only plutocrats.

The GOP remains self-defeating but can waste 100x the funding of their opposition due to inherited power and wealth.

Boomercrats are the Washington Generals of politics. Good Cop is a keystone cop. Their job is to always fail while saying "if only you gave me more, THEN maybe I could help. No, more than that. More than that. More than that..." Xeno's political party. They serve a useful purpose keeping GOP out of office, the same way electing a dog as mayor would, and right now we have to elect them since the GOP's entire goal is to hurt people to the point they're actively trying to drive humanity extinct. Considering that only 46% of the the people voting "for" a candidate in 2020 (but 68% of the people voting AGAINST) voted for Biden, he's serving his job as a potted plant clogging up the chair for 4 years (until AOC is old enough for Zombie Pelosi and Kamala Harris to block her if enough Boomers haven't died by then).

I still favor guillotines but if you wanna try taxes too... sure? I don't think it's enough, they'd still have the resources to overrule both democracy and market forces, and they're literally profiting from death. When 500 people control more than half of all money, market forces produce what those 500 people want, not what the other 7 billion want. And those 500 got that rich by not caring what happens to everyone else.

Speaking of leveraging inherited power and wealth to faceplant repeatedly, the best self-driving news is regularly NOT from Tesla. Also, modern AI really isn't, and a whole lot of technology is backdoored these days.

Meanwhile it's being argued that we can't get rid of intellectual property law until we institute basic income (which the GOP and billionaires assure us will only happen over their dead bodies). But the arguments people are making supposedly in favor of IP law tend to be a little more complicated if you know the actual history. (IP law is best viewed as an addiction. Needing it doesn't make it NOT bad for you.)

One of the points Sarah Taber has repeatedly made is that collecting food from properly managed wilderness produces far more food than agriculture does. A big political act european colonists do is destroy natural ecosystems so they stop producing food to compete with agriculture. This is so people must buy from stores with money, and are thus prevented from opting out of your political system on penalty of starvation. That's why they had to destroy the new york oysters, northwestern salmon runs, buffalo herds, passenger pigeons... The cowboy cattle drives were modeled on open ecosystems (learned from the natives), and stopped when we fenced in the land. This was a REDUCTION in efficiency and production capacity, traded off for political control.


March 4, 2021

Interesting developments in EV battery manufacturing. A mature industry is not "xerox/univac/kleenex", it's commoditized with multiple producers offering fungible products. The PC and Android are mature, the Macintosh and iPhone are not. Tesla needs to be buried by commodity manufacturers, and a trillion or so distributed through DARPA or similar to make it happen would help.

Toysh: when expanding $PS4 for "set -x" traces and duplicating the first character to indicate "levels of indirection"... that does not include function calls, that's only "source file" statements. Why?

You can call "source" within function calls, and it's live every time you do it:

$ for i in one two three; do echo "echo $i" > input; source input; done
one
two
three
$ func() { source input; }
$ for i in one two three; do echo echo $i > input; func; done
one
two
three

This also means that "source" is not an #include, it's a statement executed each time the function runs. BUT source blocks must be self-contained: flow control blocks can't cross source bounaries. So your curly brackets and if/else blocks have to be entirely within a "source".

The problem is, what happens when you have a syntax err? You exit the current "source" block but not the function call?

$ func() { source input; echo hello; }; echo } > input; func
bash: input: line 1: syntax error near unexpected token `}'
bash: input: line 1: `}'
hello

Yes, you do. Ok, sh_main() needs to create an initial function call context (with the initial command line arguments and global variables). Which means do_source() does NOT create a function call context, but instead switches out TT.LINENO with local variable context, and has a recursion cap using the same counter that's repeating the first character of $PS4...

No, the problem is do_source() changes the command line arguments. Right now function call has local variables _and_ command line arguments (you can pass arguments to source). I think source ALSO needs to create a function call context, but I need the local varable list to be a null pointer in that case and teach the logic to skip over it.


March 3, 2021

Never forget how cartoonishly evil the GOP are. These are literal Captain Planet villains. The republicans are literally testifying before the supreme court that preventing non-white people from voting is the only way they can be elected now. They're not trying to hide it anymore. But then saying the quiet part out loud is what rallied the base last time around. These guys are self-defeating clowns, except they've inherited power and privilege and money in a broken system where compound interest means you earn twice as much each year by sitting on one million dollars (coca-cola stock's annual dividend yield 3.2% = $32k) than working full time at minimum wage ($7.50*52*40 = $15.6k), so these clowns can drag people down with them basically forever because their endless uselessness and failure doesn't stop them. And that's before you get into the good-ole-boy network.

The utterly predictable Boomercrat cycle continues: Boomer Biden decided to alienate the middle class and repudiate the concept of basic income by means testing the stimulus even harder. That's the big lesson the Boomercrats learned from FDR's new deal: the way to make your plans more popular is to water them down and make them do less. Who said a 78 year old blue dog can't learn new tricks? Next up is he going to disqualify families earning more than $150k from sending their kids to public school, receiving social security, being able to call the fire department, or drive on non-toll roads? Means testing for all!

Boomer Media continues to suck: victim blaming servants of plutocracy. Here's an entertaining thread about how no one ever made a billion dollars honestly.

Speaking truth to power is always dangerous (and usually ineffective), it's much easier to strike at weakness. That's why victims come out of the woodwork once there are two or more public accusers.

Boomer Disposal has started but it's a capitalist ponzi scheme: the kind of "conservatorship" Britney Spears' father used to steal her money and force her to perform is being used to declare Boomers senile and stick them in nursing homes to sell their house and steal their retirement savings. It's dangerous and wrong and should not be allowed to spread, but Boomers are trying very hard to make sure the country collapses as they die so they make it hard to defend them even to prevent evil precedents from being set. (Late stage capitalism, the carceral state, and intellectual property law turning on and devouring Boomers isn't poetic justice if those things get stronger and turn against everyone else next. And elder abuse is bad even when grandpa's a senile racist hitting everybody who comes near with a stick, it's not their fault they grew up lead poisoned and were fed consumerist propaganda to prevent the great depression from returning after capitalism came to its natural conclusion during the Gilded Age. The _real_ tragedy of the commons is externalities, all of us suffer the poison produced by some of us, we can't wall republicans in with their own farts until they die.)

The federal judiciary needs to expand 40% to keep up with population growth since 1990 (which was 31 years ago now). Of course if Boomer Biden appoints them they'll all have sided with the government instead of challenging it.

Christianity and white nationalism are basically synonymous now.

Bill Gates remains an evil bastard trying to kill us all, and needs to watch Last Week Tonight's episode on nuclear waste and read the threads describing what happened to fukushima reactors one, two, and three.

Facebook is horrifying. Nazi recruitment is central to their business model.


March 2, 2021

Finally broke down and just checked in the simple cpio -u support I WANTED to do in the first place, which was like a 3 line patch: if -u unlink() each new file/dir up front and then open(O_EXCL) and let it fail if the unlink didn't work.

I spent a WEEK trying to get the google guy to explain WHY he wanted -u so I could figure out if the simple fix was or wasn't sufficient, and eventually gave up when (as far as I could tell) his entire motivation for submitting the patch was "a coworker noticed a difference from gnu". (Toybox patch does not print "patching file" when it sees a "diff" line without any +++ or --- lines, is that difference also a bug in toybox?)

I'm apparently still a bit stressed from the blizzard. But I'm making it to the table slightly more regularly now, which is good. I REALLY need the exercise...


March 1, 2021

I keep seeing reminders of why we can afford basic income now, such as how a single modern container ship has 3 times the carrying capacity of the entire 16th century english merchant fleet while requiring less than 1% of the manpower. Meanwhile the stimulus checks the house (but not senate) just passed are means tested to $75k, because nobody who lives in San Francisco or New York City where rent is $3k/month for a studio apartment has been hurt by the pandemic.

Another good thread on why we need to guillotine the billionaires. Which we can't until the Boomers die. (Meanwhile the damage will continue to accumulate.)

And here's a good thread from a british tax accountant explaining how government debt isn't a real problem... expressed in a somewhat frustrating way: he's an academic who can't produce a pithy sound bite to save his life. My attempt at rephrasing would be something like:

Last decade the UK government printed billions of pounds of new money and bought back government debt with it, which was called "quantitative easing".

That debt no longer exists: it's already been paid off just like paying off a mortgage early. Conservatives still CLAIM that debt exists to justify torturing poors until billionaires can buy harems and hunt peasants for sport because the 99% are too desperate to say no, but making interest payments on paid-off debt is literally the government paying interest to ITSELF.

The government sets the interest rate anyway because every auction the Bank of England offers to buy the government's newly printed bonds with newly printed money, and other bidders can only get any bonds by offering BETTER terms than that floor, which means interest rates CAN'T rise out of control. (P.S. interest paid on any remaining debt is taxable income, so a chunk comes right back in taxes. P.P.S. the UK has been doing this for over 300 years and the runaway interest rate spiral Tories clutch their pearls about has literally never happened.)


February 28, 2021

The endless argument about cpio -u once again ate the cycles I'd hoped to devote to toysh, and I admit I vented a bit at the end about being stressed. (Not exactly professional, but I've recently conformed this is strictly hobby, so...)

Well, not entirely. $DAYJOB has a list of commands they're currently using from busybox, which they don't want to deploy in the shipping version: ash, dd, stty, route, udhcpc, udhcpd, tr, flashcp, httpd, and ntpd. It would be nice to get toybox versions of for the shippable software image with IP due dilligence. But that's not our only option, and it's still a ways out. (Martin is still assembling the first round of dedicated hardware prototypes.)


February 27, 2021

Self-driving car subscription services (where you can commute every day to work/groceries/haircuts/lunch for a flat monthly fee) would be an enormous benefit to poor and middle class people. If losing the ability to drive means you lose your job and access to the grocery store, public transportation involving a 2 hour round trip bus ride returning with 6 bags of frozen food doesn't work work so well, especially while providing child care.... just doesn't cut it.

The progressives are pushing back against the Boomercrats (who are intentionally failing in obvious and pathetic ways), but the Boomers will preserve the fillibuster until they die. So the question is when enough of them finally die, and how bad things get before then, and what's necessary to shovel out the mess they leave behind (which will get worse every day until their death grip on power breaks).

Meanwhile, 78 year old President Biden has officially confirmed that MBS personally ordered Kashoggi's murder (which we already knew back in 2018), and then explicitly decided to let him get away with it because doing nothing about a problem is what the OTHER half of the Boomers want: "Don't rock the boat, let us die in peace!" Meanwhile, Biden has intervened in Syria's civil war, for some reason supporting Russia's puppet government against Iran's mercenaries?

The GOP is literally meeting to whorship a golden idol at CPAC. You can't make this stuff up. Every accusation a confession. They're not even trying to hide it anymore. Broadcasters covering CPAC are cutting away to legal disclaimers. And even then, Ted Cruz manages to stand out as especially dickish. The Attourney General of South Dakota who killed someone in a hit and run and said he thought he'd hit a deer even though his victim's glasses were inside his car comes a close second. When you hear about that sort of thing they don't SAY republican but do you really need to look him up to know? And no, his hit-a-deer excuse isn't fooling anyone.

Boomers did not lead the global effort to wipe out smallpox. The Greatest Generation did; the same people who fought World War II went on to found the World health Organization and NASA, both of which collapsed when their founders got too old to run them and had to hand control over to Boomers. That's why the WHO hasn't managed to wipe out Polio or Tuberculosis or Guinea Worm, and why NASA hasn't been back to the moon since 1974. The WWII vets could accomplish great things and the Boomers were fundamentally incompetent even back then, the Boomers just told self-aggrandizing lies about themselves a lot.

Now the Boomers are collapsing into a whirlpool of sexism, class warfare, and racism (not only against brown people, but also against asians, native americans, jewish people, muslims... pretty much 90% of the planet by this point). They hate everyone and everything, but don't want to roll the clock back to anything actually in their lifetimes, they want a wholly imagined past.

A nice thread explaining what a moral panic is, the white upper class pearl-clutching that gave us the Comics Code Authority and the Motion Picture Association of America's ratings board. It's a specifically christian phenomena, like the spanish inquisiton. But then christianity has been used to persecute people ever since Emperor Constantine used it to win the battle that made him Roman Emperor. Turning the other cheek by the sword is how it became Rome's state religion, and the catholic church was just the roman bureaucracy using religion to enforce its edicts when the legions were no longer up to the task.

Dear BBC: Thomas Edison did not invent the "Edison battery", Waldemar Jungner did. Saying Edison "invented" anything is like saying Bill Gates or Elon Musk did: no, they either copied someone else's invention or bought some smaller company that had invented it. This is a very common pattern where rich people use their money to buy credit for other people's work. (As compared to the history of men using sexism to steal credit for women's work, white people using racism to steal credit for brown people's work...) Thomas Edison didn't even invent the light bulb (Heinrich Goebel did).

My work is security-adjacent, and I keep bumping into people doing this sort of thing which only attracts attention. You're not Nalvany or Snowden, you're not INTERESTING. Your main protection from state level actors is being boring, and tedious to follow. Thirty years ago state level actors could already point an infrared laser at your window from down the block to read the vibrations as a microphone and listen in, and point a yagi antenna at your room from outside the building to listen to the EM interference and reconstruct your screen video. And that's BEFORE everyone started carrying a GPS tracking audio recorder around 24/7. But the professionals are almost entirely concerned with keeping their budgets unlimited so they're blackmailing the politicians, not you. (The "almost" is because there's also a lot of sexual voyeurism, it's not JUST the TSA porno-scanner operators passing around nudes taken without consent.) They mostly don't use their information for law enforcement purposes because it might compromise their sources. (Revealing to the world how Putin enabled Trump didn't increase the black budget, and if they wouldn't act on THAT they'll never act on ANYTHING.) Most people installing keyloggers are criminals stealing credit cards and banking info, or corporate espionage.

Defund the police. (The capitol rioter charged with beating a DC police officer with a metal flagpole was... a NYC police officer.)

Even full time authors are noticing that intellectual property law is broken. IP law allows corporations to steal from individuals, and is another reason to guillotine the billionaires.

The online advertising-driven economy is also entirely fraudulent. (People are making documentaries about this.) Just do basic income already.


February 26, 2021

Elliott sent me a patch to add tar --transform. Fundamentally, it's trying to do a subset of sed, and I keep wanting to pass it off to sed rather than reimplement the sed plumbing (which has a zillion corner cases like escaping delimiters and the substituting only the Nth match and so on), but it's hard to do that without allowing it to run other sed commands like "w FILE" which introduce security holes, or re-parsing the sed logic including curly brackets and /prefixes/ and such to filter them out (bigger than reimplenting s///) or adding some sort of sed --restrict which wouldn't work on a system using busybox sed instead of toybox sed (the commands MUST be individually selectable and replacable with other implementations, that's a design goal for toybox that it be modular that way)...

So probably what I need to do is figure out what subset of the sed plumbing tar needs and move that into lib/ which is a can of worms. Sigh, throw it on the todo list...


February 25, 2021

The CEO who took a pay cut to pay all his employees $70k/year points out that the poorest 90% pay $550 billion/year in taxes and the rich owe but DON'T pay $574 billion/year in taxes, but we spend $5 billion/year on the IRS and $115 billion/year on police. This is why I think addressing plutocracy with taxes is less realistic than addressing it with guillotines, and I lobby for the realistic approach.

There is no GOP civil war. They're the Party of No and of voter suppression, just like last time. When in power they embezzle, persecute, and scapegoat. When out of power, they obstruct. They lie and suppress constantly. Blue dog Boomercrat Joe Manchin is basically a republican. You've got the nepotism, price gouging, profiting from the sick, lying about reasons why...

The surviving Boomers tend to be stupid and vicious in part because the residue of boomerdom is full of survivorship bias. (The same pressure also explains why more recent cultural shifts come as such as surprise; modern people aren't that different, just less repressed.) It's easy to dismiss what the Boomercrats are doing as learned helplessness (a behavior of abuse victims), for example why is lying under oath to congress not grounds for firing the postmaster general? But that's not it: the Boomercrats are Good Cop to the GOP's Bad Cop. Hillary Clinton wasn't giving quarter million dollar speeches to Goldman Sachs because she was _bullied_, and Biden wasn't raking in tens of millions in campaign contributions from from hedge fund managers because he's helpless. The Boomercrats are bought and paid for servants of plutocracy.

An actual example of learned helplessness might be the US relationship with Saudi Arabia, which we've been placating ever since they intentionally engineered the 1970's oil crisis, and we're still letting MBS get away with literal murder (of Kashoggi and the relatives who conveniently died so MBS could ascend to the throne). Blood diamonds are a rounding error compared to the oil industry when it comes to funding evil.

Good thread about how just about every hate group is a "divide an conquer" strategy on the part of the rich white men trying to stay on top, and it always flares up again any time the persecuted minorites start seriously comparing notes. (Faceboot is basically a dedicated nazi organization at this point, while twitter remains bad at being twitter.)


February 24, 2021

Very low brain today. I meant to get out to the table tonight and analyze the cpio -u patch, but wound up falling asleep instead.

But hey, the city lifted the boil water notice! Progress! Half the grocery store's shelves are still empty (ironically, the frozen food aises are bare) and has signs up everywhere with "limit 2 per customer" on the remaining items and apologies about the supply issues. I can understand the complete lack of canned soup and ramen, but WHY did people respond to the blizzard by hoarding toilet paper? (Is that what we do now? Respond to any stressor event by buying all the toilet paper?)

But half the shelves ARE stocked, and their selection is... eclectic, but manageable. Oddly enough they've restocked the cans of milk tea in the international foods aisle (whoever else buys it all before I get to it hasn't been in), and we got a big pack of those v8 energy blueberry juice things (caffeine restocked: check), and we got a gallon of milk and some of the most disreputable bananas I've seen for sale in years (I was amazed that they _had_ them, but upon getting them home I'm not sure they're food and I don't feel like making banana bread right now), and a container of beef broth and the last container of the fancy parmesan Fuzzy needs to make risoto again (very tasty thing to do with rice), and Fuzzy baked a very nice no-knead loaf of bread from the flour we stocked up on back when that became available again mid-pandemic (four ingredients: flour, yeast, water, salt), and we dug all SORTS of stuff out of our chest freezer (we had several pounds of chicken quarters from a sale at Fiesta a couple months back, chicken sandwiches and Fuzzy is making soup). We've been eating fine, but I think we've destroyed our water filter pitcher. (It's full of white gunk because I was filtering _and_ boiling the water. VERY glad that's over, I was unsure of proper tooth brushing procedure, it was a hassle refilling ice cube trays from the kettle because the plastic isn't really boiling water safe...)

Yeah, a rounding error compared to the suffering around us. Can't really complain. But I'm very, very tired now that it's... over-ish? Less imminent? Back to our regularly scheduled pandemic tinged with insurrection tinged with not being 100% sure my startup can afford my paycheck at the start of each month? (They've managed it so far, but it's plus-or-minus a week and it's 1/4 what I was making at JCI so the uncertain timing is extra worrying because missing a paycheck would hurt more at this job than others, and I got stressed enough to email Elliott back on the 17th "If I were to ask google guys about getting a job actually working on toybox, where would I start?" but he never replied. Probably just as well. I don't want to leave Jeff and company in the lurch, I'm just stretched really thin in a way that isn't serving toybox or j-core well. If I can make it back to Japan I'm likely to focus on j-core to the complete exclusion of toybox for months at a time again, but having ASKED Google and gotten a "Linus's no" (I.E. being ignored), I don't have to feel remotely guilty about ignoring the next round of bug reports from them if it comes to that.

I'd like to get a release out before mothballing it though, and I've got a twisty MESS of shell changes to add function support I want to tie off before shelving it. Which I haven't been able to work on because my toybox cycles have been taken up with bug reports...


February 23, 2021

I forget, what's it called when a woman is promoted to take the blame for an unavoidable upcoming failure? (It happens regularly, there's a phrase for it.)

I'm aware that Biden is technically 4 years too old to be a Boomer, but that doesn't make him less old and out of touch, as evidenced by his student loan forgiveness cap. Not only does he still love means testing but his brain is too inflexible to wrap around inflation (a standard failing among Boomers). He was born in 1942 and leaded gas was introduced in 1923 so he didn't breathe as MUCH of it growing up but he's still a 78 year old man who spent 50 years breathing lead and bathed in postwar propaganda that tried to keep the great depression from coming back after the New Deal and War Bonds via endless consumerism. Capitalism turned into plutocracy and was already engineering scarcity back under the the Railroad Robber Barons of the 1870s (Carnegie and so on). We've been bailing it out and patching it up with the New Deal and Social Security and perpetual wartime spending and propaganda and financial shenanigans for over a century now.

Biden is a stopgap while we wait for more Boomers to die, plenty of young people are eager and able to do the job, but they won't be allowed until the geezers in charge lose their death-grip on power. (Then again, his Boomer fed chair wants to means test covid stimulus, so maybe the Boomercrats are just trying to alienate what's left of the middle class? Two-income households need not apply.)

The irredeemable GOP, billionaires, and late stage capitalism should die with the Boomers. Voter suppression is literally all the GOP has left, they can't win elections anymore. (Of course they freak out at bills to reduce voter suppression.) The GOP is horrible to poor people (and explicitly against basic income) and its fossil voters are clinging to fossil fuels. Republicans are objecting to renewables on behalf of buggy whip manufacturers. If we don't keep paying for things we don't need, the people performing obsolete tasks will be out of a job.

I live in a gerrymandered state, which has given us two truly awaful senators. Ted Cruz's PAC spent 80% of its budget buying copies of his book, from which he gets royalties. Not that this is a new trick for republicans (it was pioneered by a different cult). Meanwhile Texas' other senator is somehow almost as bad. Did I mention that we had purely digital voting machines with no paper trail right up until the 2020 election, with no possibility of a recount because whatever the results database was edited to say was all there was? Thank billionaire Michael Dell for those machines, who gave the Maximum Legal Donation to John Cornyn and Ted Cruz every year. (Yes, he's the Dell Computers guy, the one fined $100 million for accounting fraud.)

Still need to defund the police.


February 22, 2021

Somebody should really do the math from the public percent offline figures vs the predictions to come up with the talking point "texas estimated wind would provide 7% of its power in february, but during the blackout it actually provide X% of texas' power". Which is GOING to be a higher number if it declined less than other sources (which it did)...

Made it to the table again and stared at my pending sh.c change... which is completely out of control and I think I need to revert it and try again. (Sigh, function support is hard to do in reasonably sized chunks. It would also be a lot easier to do if I wasn't constantly context-switching away from it and feeling guilty about spending time on it instead of $DAYJOB stuff...)

I'm emailing back and forth with Jeff about some j-core design updates: We've wanted to do in-cpu DMA and repeat blocks for some time, and it would be nice to just knock that one out and get it posted to github.

The original idea behind in-cpu DMA was reusing the existing memory read/write bus plumbing to copy data when the CPU isn't using it; as a RISC chip all its math operations (including comparison) are done entirely on registers and its read/write memory operations are all to/from a pair of registers (one holding data, one holding an address), so the CPU is going to spend half its time NOT addressing memory (modulo instruction fetch but we have L1 cache now). This was also one of the drivers behind multi-issue where RISC chips have two execution cores and can do 2 instructions per cycle: one would deal with memory and one would deal with register-to-register logic.

Unfortunately, making them overlap properly to use unused cycles is large and intrusive enough Jeff isn't interested, and we DO plan to implement dual issue eventually anyway. The easy way to implement this is the "cycle stealing" approach to have the CPU execute invisible instructions that read/write through hidden registers, and sprinkle those in (probably 2 clock cycles, one to read and one to write) between the other instructions, which slows the CPU down a little while it's doing it, but at least avoids latency spikes.

We already have invisible instructions: they're called "system plane" instructions that handle reset and interrupts and so on: j-core instructions are 17 bits internally instead of the 16 they are in memory, and all the system plane instructions have the high bit set so the instruction decoder can distinguish them. Adding more up there and making the instruction dispatcher submit them instead of the next program instruction in response to an I/O pin is easy (I.E. small).

And we already have invisible registers: our register file is implemented as an sram block and in addition to the 16 numbered registers instructions can use there are some special ones (EBR, VBR, MACH, MACL, PR, SR, although not all of those are implemented as normal registers), and some multi-clock instructions need scratch space to store data between clock cycles so we've got a TEMP1 and TEMP2), which means our register count is 5 bits (32 entries) and the high bit set means it's one of those other registers. We're currently using... 22 I think? Plenty of space left in there for DMA.

So this implementation is less efficient, but can be done with almost no new circuitry, which means we can fit it in the ice40 version of jcore. And the main efficiency advantage is that a for loop copying data is repeatedly executing two unnecessary "test" and "jump" instructions each time through the loop, which directly injecting read/write instruction pairs wouldn't do. (Turns out read and write need to be on separate clocks anyway because there's only one DRAM bus which can only go in one direction each clock. I'd like to bypass cache for this because otherwise it's cache poisoning, but this needs design work...)


February 21, 2021

People aren't actually crazier today than they were hundreds of years ago: the current political crazy used to be religious crazy, but now capitalism is our religion, and capitalism perpetuates itself by actively creating scarcity (today's vaccine example). In that context, Republicans making it legal to murder protestors doesn't seem so historically out of place, does it? Same fights as always, obvious who the bad guys are.

Today, the catholic church has a policy that everyone who turns 75 has to submit their resignation, and can only stay on by exception. This makes them more progressive than the US house and senate. (In latin "senate", "senior", and "senescent" all come from the same root. Cluster of old geezers giving "in my day" speeches.)

AOC has raised $4 million (wait, now it's $5 million) to help shovel out from the storm in texas, and she flew to Houston to volunteer at a food bank. She's not from here, she's not responsible for this part of the country, but she showed up and did the job. Even Beta O'Rourke demonstrated competence (which is a first: he was in the House like AOC but ran for the senate instead of re-election, losing, then ran for president and lost, and no longer holds elected office). Meanwhile, Ted Cruz has become a meme and Texas' other senator The Asshole John Cornyn is missing in action. The best theory is nobody recognized him on _his_ flight out of the country.

Here's a good article with an analogy comparing the texas energy failure to the 2008 mortgage crisis as covered in the movie "The Big Short". It's the same late-stage-capitalism "optimizing" an increasingly brittle system to the point of collapse, because efficiency and resiliency trade off like security and usability do, and every libertarian plan ever turns into a nightmare when anything goes wrong. (The knee-jerk GOP/billionaire reaction is to scapegoat anything and everything you already don't like. That's what stokes most of the racism in the country, toadies blaming the ills caused by billionaires on brown people and immigrants.)

Faceboot's founder Mark Zuckerberg personally intervened to keep Alex Jones, founder of infowars, on the platform. He overrode employees who had already banned him, and changed the platform's policies to allow more violent extremism ahead of the January 6 capitol insurrection.

Boomer Media is "both sides matter"-ing itself off a cliff. This stuff is easy to counter but Boomer Media doesn't want to.

The most useful thing Biden might actually do is fix the justice department to prosecute the GOP using the existing laws they've already broken. (Alas, pointing out their hypocrisy does nothing for Boomers who haven't absorbed any new information since 1999.) The most useful thing Biden COULD do would be basic income but he's too old to believe it possible.

We need to double the IRS's budget and have the new staff focus exclusively on the top 1%, who owe more money than the 99% but are audited far less.


February 20, 2021

Made it out to the table tonight! Woo! Only stayed for about 2 hours, but I made some good progress on the "echo a1234b | grep -o '[0-9]*'" issue where zero length matches behave differently in -o than in non-o contexts.

I first went down a whole rathole of trying to teach regexec0() to filter out zero length matches, but that broke the grep '' empty pattern acts like .* tests, and I looked at special casing THAT but eventually figured out that "echo abc | grep '[0-9]*'" also matches: a zero length match is a match, and if you don't care what RANGE matched...

So what needs to change is the -o logic, recognizing a zero length match and advancing past it. I.E. rip out all the changes made so far and add stuff down in the "dealing with matches" section.

It's about a 4 mile round trip walk from my house to the table, and I am SO out of shape after a mostly sedentary week frozen in. (And several days of too cold to go out before that.)


February 19, 2021

Finally warm enough to decently melt stuff today, and it's supposed to stay above freezing for the forseeable future. Dunno when we get to drink the water again. (Also, trash pickup didn't happen today, but I can't say I'm surprised.)

Austin has a wood-burning power plant ("biomass") which was offline during the entire crisis because ERCOT hates it and has been trying to destroy it for years. You can't blame "renewables" if YOU'RE THE ONE WHO DISABLED THEM.

I do not understand the appeal of one of my state's senators even to his own base. I've voted against him every time I can, but they didn't fix the voting machines to produce a paper ballot until 2020, so none of the elections before that had any way to confirm the results. (Fascists always focus on voter suppression as their appeal narrows, which inevitably happens because none of their policies ever make anyone's life better. But all incumbent parties defend first past the post voting, which is fundamentally broken. The Boomercrats are Good Cop, doing a job that wouldn't exist without Bad Cop. Perpetuating the problem they claim to address.)

Over the lifetime of the Boomers, billionaires have stolen 47 trillion dollars from everyone else. When the Boomers Die, the GOP, late stage cappitalism, and billionaires all need to go down with them.

Speaking of historical relics past their sell-by date believing in the divine right of kings, Spain not only still has a monarchy it's disappearing critics of its monarchy. And oh look, Boomercrat Biden is caving to ICE, so the deportations may continue. (Yes, Ted Cruz is human garbage but Good Cop is still a cop. Bad Cop's real job is to drive you into the arms of Good Cop. Defund both.)

But at least the democrats have a tiny progressive wing that's pointing the Department of Fatherland Security at the nazis and will performatively fail to tax the billionares which is why to lobby for guillotines instead: your opening negotiating position should never be half measures, it should be the most extreme thing you're willing for a be-careful-what-you-wish-for monkey's paw to actually deliver. The existence of Billionaires racks up a continuous body count.

Yes I'm aware that "stock valuation" and "liquid assets" are not the same thing, and a controlling interest in a company like microsoft/amazon/faceboot comes with a dollar value that's not directly translatable into cash without losing control of the company or incurring a debt burden than results in a margin call if the stock price goes down temporarily. This stuff is complicated. It also kills people, and uprooting founders when their company outgrows them is almost as good as a sherman antitrust breakup. Steve Jobs left Apple to do Pixar (buying Industrial Light and Magic's discarded CGI arm after Tron flopped at the box office), and then almost became CEO of Disney (which involves appointed control, not owning a billion dollars of Disney stock). A publicly traded company does not need a dictator with a controlling interest rendering all other voting shares moot. Oh, and tax stock buybacks at twice the rate of dividends.

Speaking of Faceboot, its founder personally intervened to keep Alex Jones, founder of infowars, on the platform overriding employees who had already banned him and changing the platform's policies to allow more violent extremism.

As problematic as universal video surveilance is, it's used for punching up as often as punching down. Of course Powerful people try to distract from this fact, and leverage late stage capitalism to stop it.


February 18, 2021

The blizzard turning into a blackout is the fault of fossil fuel billionaires who are finger pointing like mad at green energy, I.E. lying (every accusation a confession). It was primarily natural gas that failed. (Yes it's an even numbered day but we're still under a "boil your water" advisory.)

MacOS is now the third most popular desktop, after ChromeOS.

Louis Rossman did a video about how he likes his dirt cheap $150 "moto g" android phone, and I still want a scratch device to install AOSP builds onto, so I thought I'd pull an aosp update to see if it's a supported target in vanilla, and... "repo update"? "repo upgrade"? "repo pull"? Nope, none of the above... sync. It's sync. (Every time, takes me MINUTES.)

[Several minutes later...] I have Google Fiber. How long does this update take? Ok, it's been months, but I have a GIGABIT FIBER CONNECTION and it's (finally) writing to an ssd instead of conventional hard drive. The download speeds are like 1.3 megabytes per second (times 4 because it's overlapping downloads, but still). Gigabit should be faster than the wireless connection and 802.11n's worst case config is still ballpark of 20 megabytes/second, why I am I getting less than _5_?)


February 17, 2021

The white male Boomer "Rush Limbaugh" died today. This makes today a good day by definition.

We needed some good news: here are informative threads on Texas' blizzard from an energy perspective and a freezing perspective. And in case you thought this was just a fluke instead of climate change, it's currently snowing in saudi arabia.

Late stage capitalism is circling the drain, but it will last as long as Boomer cognitive dissonance has the power to prop it up in a "beatings will continue until morale improves" way. Meanwhile the financial system is not ONLY entirely fictitious, it's also held together with string. (Guillotine the billionaires. And don't just defund the police (such as the ones in portland guarding a grocery store's dumpster from starving people), fire mayors who divert $300 million of covid money to police payroll.)

The survivalist preppers aren't handling the blizzard well. The sale of "survival buckets" mentined in those threads was pioneered by the televangelist Jim Bakker. I'm glad religion is slowly dying in the west, but the venn diagram of racism and misogyny and superstition and fascism is collapsing into a perfect circle. Every year texas and california fight to buy textbooks, and the rest of the country gets basically those ones due to economies of scale, and Texas is pumping its selections full of racism and editing out all mention of evolution in the name of religion. And any space dominated by white men is guarded by a moat of gatekeeping and harassment, not just historically but currently. Otherwise women and POC would work their way in and the imbalance would correct itself.


February 16, 2021

HEB is open today (noon to 5 the website says), but the line to get in stretches to the length of Hancock Center and then a block north along the sidewalk of Red River. (Fuzzy was willing to wait in it, I was not. She thinks she got mild frostbite in her feet doing so, but we have milk and a bread now; they were out of loaves but she got hamburger buns. The potato appears locally extinct, but we dug some flakes out of the back of the pantry and she made potato soup with that. Using fried deli ham in place of bacon; they were out.)

When the pandemic first hit I felt guilty for not using my time productively. Now mid-blizzard I feel again guilty for not using my time productively, but I'm kinda stressed by all this. It's stacking debuffs: the GOP broke the weather and Texas' electrical grid (back in the day Enron bribed the government to "deregulate" into a lucrative divide-and-conquer collapse, and now they're lying about it; our power hasn't gone out yet but COULD at any time, and so far the power outages are completely racist so I'm guilty about NOT having lost power yet, there are rumors of giant electrical bills coming for anything we do use)... The news is also making me feel very lucky that my pipes didn't burst. (We haven't lost power, the pipe that froze was the metal water main going into the house which is exposed for 6 inches in our concrete driveway with some half-assed foam insulation partially wrapped around 4 inches of it. Not exactly winterized. I took the heating pad back in but threw the old dog blanket over it and we've left a faucet dripping.)

I got a little work done. One of the google guys sent me some "df" command design suggestions disguised as patches, and I poked at that a bit. And a few days ago Elliott sent me a grep bug report I've diagnosed (-e '[0-9]*' produces zero length matches at every location that ISN'T between two numbers, including the first and last positions, and when combined with -o grep is not handling it right), and I need to finish that and check it in but I just haven't got the brain right now. People AROUND me are hurting, and the closest I can come to helping is staying out of the way.

I really really really really need to do $DAYJOB stuff but just can't focus enough at the moment. Toybox commands I already did the work and have a good mental model of, the GPS stuff is challenging exploratory signal processing stuff I don't quite know how to do and that takes brain. To quote the ever-quotable Seanan McGuire, "I cannot brain today, I has the dumb."

Watched a bit of Cells at Work with Fade and Fuzzy in the evening. Crunchandroll has obtained both Black and Season 2, but I only had the energy for 2 episodes and one of them was the 13th episode of season 1 that Netflix didn't have.


February 15, 2021

4 inches of snow in the driveway. The water pipe into the house froze. We ran an extension cord from the back yard out to the side of the house and stuck a heating pad on the water main going into the house, and threw two blankets over it, so maybe it'll thaw again before the sun goes down? Dunno. I should have left the water running but fell asleep instead. (One of those "let me nap for a couple hours after dinner... it's morning" things.) If nothing else I want to arrest the freezing before it makes it further along the pipe and maybe breaks something inside a wall.

HEB is closed today. So is Fiesta. As far as we can tell, NOTHING is open. We tried to stock up yesterday but they were closing as we got there and we had like 10 minutes and really long lines to get through, so we got a randomish assortment that did not include milk or bread or potatoes (all on the list, did not manage to grab them before the store closed). The website said they'd be open 12-5 today but that changed to shortly before it was scheduled to open and they just... didn't. Given the depth of snow around their loading dock, they wouldn't have been able to resupply anyway.

When faced with bald faced lies, modern journalists' pathological need to be two-faced (good people on both sides) results in contradictions like showing that wind turbines were producing 3200kwh when they were forecast to produce 2000 so COULDN'T be the culprit in power outages, and then end the piece with "balancing supply and demand on the grid has always been a challenge and prone to failure at times of extreme heat and cold. While the variability of renewable supplies will undoubtedly increase the challenge..." because you can't call out a lie, you have to support whatever both sides said.

The reason we can't fix this yet is Boomercrats and Boomer Media aren't dying fast enough. The Boomers are still driving and have stopped accepting anything new.

The continued existence of Boomers has splash damage everywhere. We can totally afford basic income, only the continued existence of billionaires prevents it. The easy fix to real estate hoarding by airbnb slumlords is to increase property taxes tenfold and then have "primary residence" rebates down to the old tax rate. (This is also incentive to keep rental units rented: then it's somebody's primary residence.) And David Graeber warned that ever-growing university "administration" (bureucracy) was crowding out the actual teaching staff, but here's an article on how university endowments are making that problem even worse, to the point they're firing lunch ladies and janitors to pay for more bureaucrats. And every day there's a new reason to defund the police.

Now that everybody knows what a sexist white man Joss Whedon was, they're talking about how horrible Rick Berman was and the damage he did to star trek.


February 14, 2021

For days now it's been too cold for my nightly walk to the table outside the UT geology building, and tonight we expect precipitation on top of that, which may not melt until SATURDAY. We already HAD snow January 10th, I have pictures in my phone of the snowman Fuzzy made in the backyard. Significant show twice in one year is historically Not A Thing in Texas, and they're saying we could get 8 inches tonight!

I'm trying to get some programming done anyway, but the cats are still clingy. I miss the booth at wendy's, the table at HEB, the sort of bar thing at junk-in-a-box, McDonalds, In-n-out, whatever the plural of "starbucks" is (starbii?), that bubble tea place next to the Mueller drafthouse, the ability to go INSIDE various UT buildings, libraries...

What I have is a kitchen table with cats. Multiple cats. If I get into anything like a zone, I get a demanding cat pulling me out of it. (They want to be held, and failing that on my keyboard.)


February 13, 2021

I miss the polar vortex.

Earlier today google thought tonight's low would be 29 degrees, but it's currently 27 degrees outside. Tomorrow it expects 13 and monday _8_. The expected low doesn't get back above freezing until next saturday, and the expected _high_ isn't above freezing until wednesday, and that's just 37 degrees. (Yeah yeah, Freedom Units. In metric everything but that last one is negative numbers.)

The Polar Vortex was a weather phenomenon that kept the cold contained up near the poles, where the intensity froze glaciers out of salt water despite salt usually melting ice. Freezing despite salt requires temperatures of ten or lower in Freedom Units, and growing LOTS of ice on salt water requires as much cold as you can focus up there: the south pole is over land but the north pole is on ocean. The ice sheet would melt again a bit over the summer because the sun would stay up 24/7 the same way it stays down 24/7 in winter, but as long as it got enough cold in winter to build back up everything would stay frozen over the summer.

But somewhere around 2014 global warming cracked the polar vortex, and all that cold started leaking out DOWN HERE rather than staying up there where it's supposed to be. The freezer door is open and the ice cubes are melting, and sure there's a bit of a draft in the rest of the room but none of the cold down here is going to keep anything frozen past march. Last year minnesota got up into the 80's in novemember, and the temperature is whiplashing all over the place which is where violent storms come from. We're having spontaneous hurricanes in the midwest now, and that's not just the new normal: it's going to get worse.

Meanwhile, the Boomercrats self-defeat at the impeachment trial. The Tories have gone full eugenics without pretext, the USA is still built on racism, and we need to defund the police. And for a combo bonus: late stage capitalism intellectual property law used to automate algorithmic police brutality video takedowns. (This is why you zero the budget. Not reduce, not reform. Clean slate.)

It's nice that the progressives are making an attempt to fix things, but I 100% expect the Boomercrats to fumble it until they're dead. After all, they preserved the filibuster and haven't managed to replace the head of the post office.

Oh look, this excellent thread explaining why to guillotine the billionaires starts with a picture of a guillotine in the first tweet. (You guillotine them because they've made it very clear that social change will only happen over their dead bodies.)


February 12, 2021

Here's how to uninstall some of the microsoft spyware the raspberry pi foundation added to the official PI operating system images. (They made the PI images dial out to microsoft servers every time you install something so they can track every package you've installed, which also lets microsoft's servers replace any package in a raspberry pi by adding a "newer" version of the package to their repositories, AND it installs binary only packages onto the system. The PI foundation is not actually that interested in open source, they just found Linux useful because it's cheap and runs well on low-end hardware.)

I'm getting a bit overwhelmed with toybox todo items coming in from github and the mailing list and the google guys. I need to be doing GPS stuff and I'm not getting it done...


February 11, 2021

The Boomercrats could eliminate the fillibuster at will, they just don't want to. (tl;dr: if they don't file cloture motions then septuagenarians have to stand and talk 24/7 until they drop, like in Mr. Smith Goes to Washington. Make them do it.)

The hollywood blacklists of the McCarthy era started as racist union-busting exercises driven by Walt Disney and Ronald Reagan. As always, follow the money back to rich white men lining their own pockets with blood.

Capitalism's suckage is increasing. The CEO of gofundme just took out a full page op-ed in USA Today calling the flood of fundraisers for bills and groceries on his platform a "national emergency". BS jobs are a result of the puritan work ethic, but capitalism creates scarcity in general. That's why Biden's vaccine program is so terrible, plus the people administering it are racist. (An opened vial of the MRNA stuff expires in 6 hours, a nurse opened a new vial at the end of a scheduled vaccination event and the doctor had to find 10 more people to give the rest to by midnight. He mostly knew other immigrants from Pakistan and was fired for "lack of equity" in his selections (I.E. too many Indians), and explicitly told he should have wasted the doses instead. The people who told him that should be fired.)

The GOP continues to be monsters (and one of my state's senators somehow managed to get even dumber), but the Boomercrats are Good Cop to their Bad Cop, enabling them. (Good Cop will not prevent any of this. Stop donating to the DNCC, start donating to Stacey Abrams.) Fascists are fundamentally people who fear change, but change is inevitable which is why they historically always lose, but only AFTER leaving a trail of destruction with concentration camps and kids in cages. Even their actions with a lower body count, such as the GOP in Georgia creating a state board to strip girls naked and examine their genitals for permission to participate in sports, are NOT GOOD THINGS TO DO.

It's long past time to defund the police. (And defund the Defense Intelligence Agency while we're at it.)

I vaguely recall (podcast?) Joss Whedon doing some sort of "mea culpa taking a time out" thing years ago, back when me-too winged him, and we've known for a while that his "feminism" consisted of constructing a work environment where he was surrounded by young women whom he had power over, but apparently he's even more of an asshole than was known at the time.


February 10, 2021

A few months ago Jeff was talking about how all the chip fab space is booked and backlogged, and now it's hit the auto industry. That site's follow-up article blames telecommuting and home entertainment, but ultimately it all traces back to the pandemic.

I've had writer's block on the GPS stuff, which you wouldn't think would be an issue but I've reached the point where I need to start comparing a bunch of candidate signals against each other, and my metrics for comparison are too hand-wavy for me to mentally put weight on them. Every time I sit down to code the Wrong Thing I'm expecting to produce lists of numbers sorted in an order that doesn't MEAN anything, and the purpose of the sorting is to discard all but the top few candidates.

Gold codes are special pseudo-random number generators easily implemented in hardware, which are based on polynomials selected to have certain characteristics. Basically you start with a register set to all 1 bits and you use a mask value to xor and shift it to get a new bit, and you do that repeatedly until it cycles back to all 1's in some "power of 2 minus 1" period. An "order 7" polynomial has a period of (1<<7)-1 I.E. 127, order 9 is 511, order 10 is 1023 (which is what GPS uses), and so on. Basically it's:

int gg_bit(unsigned gg, unsigned poly)
{
  unsigned x = 0, g = gg;

  while ((poly >>= 1)) {
    x ^= g&poly&1;
    g >>= 1;
  }

  return (gg<<1)|g;
}

The hardware doesn't need the loop, the new bottom bit is just a parity check on "gg&poly": 1 if an odd number of bits were set, 0 otherwise. But the PDP-11 didn't have an assembly instruction to do that, so there's no C operator for it, so we calculate it the hard way. (The above code leaves garbage in high bits; either mask them off or ignore them.)

So if you start with binary "1111111111" and use either of the (octal) poly values 2011 or 3515 (those are the two values GPS uses), after 1023 numbers the bottom 10 bits cycle back to being all 1 again and the cycle repeats. If you look at just the bottom bit, you get a sequence of 1023 bits which is guaranteed to start with a 0 (otherwise it wouldn't vary at all, so your poly must have an even number of bits set) and guaranteed to end with a run of ten 1s (to reset it back to where it started). This means we're using an "order 10" polynomial (and yes you can find both of those in the petersen table linked above, and bit 1<<11 being set makes it an order 10 table with the bottom bit of each poly always being zero and that's why the above is shifting one to the right before using it; I dunno why the math guys did that).

Then to get a proper Gold Code, you use two of these PRNG sequences with different polynomials, and XOR them together at an offset from each other. This produces a repeating bit sequence with the same length as its constituent PRNG algorithms, but is even more random. (Among other things, taking out that guaranteed 0 at the start and run of 1's at the end, it's xored against some part of the middle of the other one. The smallest offset GPS uses for an actual satellite is "5")

The way "spread spectrum" signaling works is you have a high frequency signal which you XOR with a repeating bit pattern (instead of a normal sine wave the radio signal "bounces" off the Y axis at zero when it toggles between 0 and 1 in the pattern). If you know the bit pattern, and you can line it up exactly in your receiver (either using atomic clocks and speed-of-light signal propogation delay math based on knowing where you are and where the sattelite is at all times because you have a mathematical model of its orbit and your position in polar coordinates... or you just do a brute force search, possibly via fourier transform), you can XOR the original signal back out with the same pattern like a key (this is called "correlation"), and a very weak signal becomes readable because the random (thermal) interference doesn't have that pattern. Even though the thermal noise is MUCH louder than the signal, when you invert half the samples a truly random signal will cancel itself out and each of our signals makes a tiny delta against that (when I'm looking for a 1 the signal is slightly higher, when I'm looking for a 0 the signal is slightly lower), and you add those up to get a strength indicator, I.E. consistent deviation from 0. You're looking for a tiny delta from truly random and adding it up over time.

To transmit data this way, you invert the whole cycle when you're sending a 1, so your delta from "zero" signal strength (actually 50% because random bits in the thermal noise should be set exactly half the time) in the correlated signal is either positive or negative. Except all this can still get drowned out by ground based radio thermal noise (which is VERY loud in comparison, and bits are very short so a single "pop" or "snap" from a static electrical discharge in the next room can easily obliterate one), so you repeat everything at multiple levels. The high frequency signal (like a couple gigahertz) only toggles every X waveforms, and then you repeat each correlated bit multiple times in a row. (And then WE plan to layer error correcting codes on top of it.)

It's called "spread spectrum" because taking a high frequency signal and switching it rapidly makes it look like a lower frequency signal. (This is how headphones produce bass notes, and how digital audio playback works in general: you sample at a very high speed and the result makes lower speed waveforms.) If you're switching sufficiently randomly you're essentially broadcasting old analog-style TV static or tape hiss and there's no significant interference at any one frequency. We want this, because we don't want satellites interfering with each other. (The ones with big expensive yagi antennas and kilowatts of broadcasting power broadcasting on an assigned frequency with carefully aligned antennas get pissed with dollar signs and lawyers behind them if you interfere with their signals. At the VERY least you'll never be allowed to launch another satellite.)

Another advantage is every satellite can be broadcasting on the same frequency and they all look like noise to each other, noise that is SO MUCH weaker than natural background static you can have lots of sattelites on the same band and they don't care. You pick out the signal you're interested in by correlating to it and letting the tiny deviations from randomness add up over time according to the very specific pattern you're looking for.

The GPS correlators run at 1.023 mhz (so each full 1023 bit cycle of the correlators takes exactly 1 millisecond). The GPS signal broadcasts at 1575.42 mhz, and 1575.42/1.023 = 1540 wavelengths of the ~1.5 ghz signal get emitted before toggling to the next correlator bit. Then each 1 millisecond long correlator cycle is repeated verbatim 20 times before toggling to the next bit of the encoded GPS signal, for a bit rate of 50 bits per second.

Fifty bits per second is pretty slow, but we have several knobs to twiddle to speed it up:

  1. What frequency are we transmitting (shift up from 1.5 ghz to ~2 ghz)

  2. How many wavelengths of the raw signal before we advance the correlator (1540 is pretty conservative, but it was 1960's technology being put into high orbit)

  3. How many consecutive correlator cycles do you repeat for each bit: having at least 4 makes "acquisition" (finding the signal in the noise in the first place) a lot easier for multiple reasons

  4. How long is our correlator code's repeat period (order 7 = 127 bits, order 9 = 511 bits, order 11 = 2047 bits)

This is before getting into more modern signal processing techniques where instead of a one dimensional plus-or-minus signal we decode a 2 dimensional sort of chessboard, but that's out of scope for now. Europe's Galilelo GPS constellation does that, as do modern wireless routers, and I _THINK_ the patents have now all expired but we haven't done that research yet...

The longer your correlator pattern is the more it helps the signal emerge from the noise, but some other math result Jeff dug up in his research says that even numbered polynomials have no real advantages over the odd numbered one below them when it comes to signal strength (for math reasons, ask him), so right now I'm looking at order 7, order 9, and order 11 polynomials. And the difference between an order 9 pattern and just repeating an order 7 pattern 4 times (same-ish number of bits!) is "better randomness".

The FIRST thing to do with each polynomial output is check that it's balanced, I.E. has the same number of zeroes and ones. (If it doesn't, throw it out.) The next thing is check the runs of zeroes and ones for randomness: in a truly random signal each bit has a 50% chance to flip so 2 adjacent bits will be the same half the time and different the other half of the time, 3 consecutive bits will have 4 runs of length 2 and 2 runs of length 3, and so on... except they never line up exactly and I dunno what's disqualifying? If there's a run of length 5, a run of length 6, and a run of length 7, is that better or worse than NOT having a run of lenght 6?

And this is where I start to get into writer's block. Jeff suggested running a fourier transform on it, which should produce a certain shape, but how do I test _that_ shape deviates "enough" from what's expected? Define "enough". I can easily come up with thousands of signal candidates, but am not comfortable making value judgements about them.


February 9, 2021

Oh hey, an update from the same Morgan Stanley analyst who gave that talk about self-driving cars back in 2017. Now he's saying the gasoline industry is a single digit number of years away from being "totally worthless". Meanwhile the rising prices of Palladium (now $2500/oz) and Rhodium ($20k/oz) has led to an epidemic of catalytic converter theft and rising prices for new fossil fuel cars (car markers are estimated to spend $40 billion on those two metals this year). Meanwhile lithium costs a little under $10/kg and an electric car has about 22kg of lithium in it, so that's $220 of metal. (That's after the price tripled over the past 5 years due to demand, which has led to And there's a whole lot of work going on to expand the supply.)

Twitter continues to suck at being twitter, but Faceboot is an "extremism amplifier" and one of the main reasons for the growth in right-wing loons in the USA.

Police are now using intellectual property law to take down videos of themselves posted on social media. (Intellectual property law is part of late stage capitalism, it cannot outlive the Boomers. Attribution is not ownership, and neither translate directly to support for artists creating. Tying funding to output is itself a source of stress, and the enemy is not piracy but obscurity.)

Of course republicans lie with statistics. They lie with everything. Reality has a well known liberal bias.

Years ago I wrote about how malaria gave rise to african slavery in the united states. Here's an article about how malaria in the USA ended. (The same Greatest Generation that knocked out smallpox did in malaria, and almost took out the bald eagle as collateral damage, by spraying massive amounts of DDT on the mosquitoes). And today I learned that the oklahoma panhandle is land Texas gave up so it could remain a slave state under the Missouri Compromise, which is also why it broke away from mexico in the first place.

Generation Jones has been screwed over by the Boomers, but lots of outlets still haven't learned to distinguish them yet.

Means testing still sucks.


February 8, 2021

I got poked about 0BSD today, although the result seems to be to leave it as is. David Graeber's observation that most work is maintenance (you make a cup once but wash it 1000 times) remains true.

I started to reply to somebody saying "Good to know" about free(0) and close(-1) both being defined as NOPs by posix, but decided it didn't belong on the mailing list, so here:

The free(NULL) thing is explicit in posix: "If ptr is a null pointer, no action shall occur."

But close(-1) being a NOP is implicit: it's reality but requires reading between the lines. The basic story is if the argument isn't an open file descriptor it returns EBADF (a harmless error) and open() returns -1 as its error value so that can never be a valid open file descriptor.

The problem is a literal reading of posix implies that the first file descriptor allocated should be -2147483649 because that's the "lowest numbered" value of type int, which MUST be signed to represent -1 and posix never said "positive" in "file descriptor allocation".

But even then -1 itself should be off limits because it has a defined value as the error return for open() (although pipe() could technically return it in its fildes[] array without violating what posix says). I'm aware of one other negative value in active use in Linux: -100 is AT_FDCWD to tell openat() and friends to use the current directory (which is again signalling, not an allocation return)

Practically speaking the file descriptor has always been an array index into the process's file table because it's about as hot as hot paths get, but "implementation detail everybody does" is not a standard. And posix ACTS like it means "lowest positive number" when it defines stdin as 0, stdout as 1, and stderr as 2 in the STDIN_FILENO and friends constants, so you can IMPLY that the next opened file descriptor should be 3, but posix doesn't actually _say_ it. As far as I can tell a "posix compliant yet horrible" implementation technically COULD return negative file descriptors, even though none historically ever have and unix is 52 years old now.

No I'm not poking the committee about it because Jorg Schilling isn't dead yet.) The historical reason posix is swiss cheese (to the point you can't BOOT a posix-only system because it doesn't mention mount or init) was so Windows NT and OS/360 could be be sold to the US federal government back when NIST FIPS 151-2 required posix compliance as a prerequisite for selling computers through the federal procurement process. Rather than fix their products IBM and Microsoft went for regulatory capture and punched holes in Posix big enough to drive a truck through. The result is that posix saying you _can_ do something might be meaningful, but posix failing to mention something means NOTHING. Posix is as "part of this complete breakfast" as the bowls of breakfast cereal surrounded by defensive rings of bacon, toast, juice, fruit, mashed potatoes, and an entire ham in the old saturday morning cartoon commercials to be able to legally call the net result food.

It's a pity that Red Hat similarly paid off the Linux Foundation to require RPM in the LSB until Ubuntu and Debian washed their hands of it, thus destroying the Linux Standard Base. It would be nice if there WAS a good linux standard out there, but bureaucracy begat cluelessness begat indifference and thus ended the LSB, and file /etc/os-release has replaced the "lsb_release -a" command, and the world moves on...


February 7, 2021

Today I learned about the Great Male Renunciation where jacobins during the french revolution declared it unmanly to wear bright colors or decoration (leaving women to inherit french court fashion like high heels, lace, and jewelry), and that men instead had to dress like monks, which suited the USA just fine since we'd been founded by religious loons who would go murderous at the drop of a hat. (White Men have always been trash, being one just lets me say that with authority.)

Microsoft continues to attack Linux, now using their "embrace/extend/extinguish" playbook such as when they switched from "the Microsoft Network will replace/destroy the internet" to using Internet Explorer to lock as many web pages as possible into microsoft proprietary data formats. The Raspiban idiots who fell for it in the raspberry pi are violating GPDR while they're at it.

Twitter hasn't emailed me about re-suspending the account for finding yet another "guillotine the billionaires' tweet all week, and yet they've barely scratched the surface. (I mean come on, those are visible in the backscroll when you look at the account. You're not even TRYING.)

Capitalism and Billionaires continue to suck. Most things should be easier to fix once the Boomers die, but in the meantime capitalism prevents a lot of kinds of creativity from scaling.

One hundred and forty of the DC police officers ordered not to stop the capital insurrection were injured by the maga rioters. Being police isn't even good for the police.


February 6, 2021

Today I learned about "gradual typing" and am still suppressing my gag reflex. (PICK ONE!)

I got poked about a patch from 2017. Ummm... ok?

I'm trying to buy a spare sd card so I can mail a turtle board to australia (not gonna send him an untested board in who knows what config state) and it turns out to be tricksy with the pandemic. I thought HEB carried them, but no. The kiosk in Fiesta that did closed. My sleep schedule is not lining up well with a trip to Best Buy right now, and mail ordering it seems silly...

Toysh! I haven't quite opened the line editing can of worms yet, but I did a quick experiment in bash to see what would happen if I typed a line of text and then resized the screen horizontally, and it does redraw the line every time the screen expands or contracts horizontally, but when the resulting number of lines decreases it cursors up one, so if you shrink and then expand multiple times the line gradually walks up the screen. And SOMETIMES (I think it has to do with contracting quickly and triggering the behavior another time while it's redrawing) it walks down the screen when it wraps to 2 lines, so I have repeats of the line smeared up and down the text window.

HOW AM I THE ONLY PERSON TESTING THIS?


February 5, 2021

Good quick read "Censorship as a tool that gives power to absuers" about how the Boomer pearl-clutching is just another misogynist way of keeping women "in their place".

Once again, the onion merely documents reality.

Week two of the Biden administration and democratic senators are already trying to destroy the internet. Please do not allow Boomers or people elected by Boomers near the Series of Tubes, they SUCK at it. (Honestly, under Amy Klobuchar's bill section 230 protections wouldn't apply to AO3, the Internet Archive, and Wikipedia. Those nonprofits do fundraisers, that means they accept payment to make speech available. I pay an ISP to host my personal website, who would this NOT hit?)

We still need to defund the police, and oh look more GOP campaign finance fraud. Speaking of which, it looks like Putin is now eliminating witnesses to his poisoning of Nalvany. (Putin is Joe Biden's age and has been making preparations for retirement, but Putin's riding a tiger he can't easily get off of...)

People keep joking about millennials killing stuff, but the reality is still Boomers destroying everything.

Sometimes algorithmic discrimination _is_ explicit, as in the case of TikTok presumably using discrimination against "poor and ugly" people to distract from the fact it's a chinese propaganda app.


February 4, 2021

Yay, $DAYJOB paid the moneys again! Both Neil Gaiman and John Rogers (creator of Leverage) have said that every job they took just for the money was a mistake, and while I agree it would be nice to be able to not worry about money living paycheck to paycheck is stressful. There should be a happy medium between "work from home doing what I love and wondering if I can pay the mortgage on time" and "live in an efficiency apartment in a city I'd never previously set foot in working in a cubicle for a company that just moved its headquarters to Dublin to avoid taxes" which literally pays 4x as much. (Yeah, my fault for buying a large house back under different employment circumstances. Thought I could have kids. Didn't work out.)

I need to circle back around to poking at the hello world kernel for j-core that Rich made recently, because I've been looking for something like that for years, and once did a writeup about why... (I've written so much stuff over the years that's not properly collated. Shouting into the void, you have to repeat the same thing dozens of times for anyone other than you to have even heard of it. Yes, that writeupu is a decade old, and I've repeatedly poked at it over the years. Never did get the ppc one working with qemu, but this one doesn't have the linker script the arm one did. Of course the NEXT logical thing to do is build a rom image for the j2 bitstream out of this which does NOT need the bare metal ELF compiler but can work with the same compiler that builds literally everything else, but Jeff objects strenuously to this for hardware engineer cultural reasons. The main difference between the two toolchains is the presence/absence of the _ prefix on symbol names, which propagates through to libgcc.a and you'd THINK you could fix this with multilib but the ELF toolchain build ends with an error, which is very much "this is not a real toolchain" to me... sigh.)

In toysh, right now do_source() automatically creates a new fcall context, which is a problem for eval wanting to use the $* from the parent context. Hmmm, I could remove TT.LINENO global variable and use TT.ff->LINENO, but there are two $LINENO contexts: parse context and runtime context. (Ala "$PS1 can prompt for the next line we haven't even run yet" and "we did a function call so it's a historical line number".

This is kind of similar to the global/local variable issue where what I really need is an "always there" TT.ff last entry. (Which points it back to being a doubly linked list, except it would want to be in reverse order which I still haven't got functions for...)

Oh great:

$ bash -c 'x=2; a() { local x=1; echo $x; unset x; echo $x;}; a; echo $x'
1

2

I need to support WHITEOUTS for local variables. Seriously? It's not just a stack it's outright UNION MOUNT semantics?

Ok, sometimes do_source() needs to reset LINENO and $*, and sometimes it doesn't, so when? Can the "name" argument signal it? Time to audit the callers: do_source() is called by run_subshell(), subshell_setup() (twice), sh_main(), eval_main(), and source_main(). And run_subshell(str, len) is called by pipe_subshell() and shexec() and run_lines(): run_subshell() does the fork() and returns pid, -1 for error, and 0 in the special case that we're called from the pipeline plumbing and need the child process to continue with the currently parsed pipeline data... shexec() is called by sh_exec() which is called from run_command() and from exec_main()...

I need to draw diagrams.


February 3, 2021

I hope Biden's bill to fix the post office doesn't get fillibustered, and it's good he's finally releasing the funds that were allocated to help Puerto Rico recover from hurricane Maria in 2017.

Republicans think the nanny state needs to take decisions away from citizens for their own good. That's what they think about drugs, what they think about abortion, why they do voter suppression and gerrymandering, why they need endless police and to imprison more of the population than any other country... Once again, every accusation a confession. (We still need to abolish ICE.) You don't have to dig too deep to find contradictions in any GOP policy, because they're hypocrites to the bone. Some of the GOP's go-to tricks are "blaming the victim" and "shooting the messenger", from Greta Thunberg to David Hogg.

If you don't think the GOP are monsters, ponder the case of a 16 year old girl who was sex trafficed, her seller murdered her buyer, and the DA wants to try her as an adult as an accessory to the murder. All those right wing loons who insist pizza shops must have hillary's sex dungeon in their nonexistent basement turn out to be on the wrong side of the real issues. (And of course that district attourney's bio mentions the church he attends.)

A big part of defunding the police is cycling out all the current officers, because they're not on our side. People keep quoting "a few bad apples" without finishing the proverb, "spoil the bunch". The rot spreads, unpunished bad drives out the good and you eventually have to start over. Give them pensions with the condition of never working in law enforcement again (from mercenary work to mall cops).

AOC recently recounted hiding from the GOP's capitol mob on January 6th, including from an angry white male police officer yelling "Where is she?" because she didn't know whose side he was on. AOC also mentioned she was sexually abused, but that's a bit like asking if a black person has ever been harassed by cops. Our society is deeply broken in many ways and every thanksgiving we celebrate how this country was founded by religious loons fleeing the wild licentiousness of england by settling land that european plagues had recently depopulated (as if Ghengis Kahn had arrived in europe right after the black death) and then the settlers murdered the remaining natives to take the rest of their land, erased their cultures, and continued to hound the survivors for centuries and continuing to this day, plus they imported a bunch more people to be explicitly racist at.

Capitalism continues to suck and we need to transition off it. (The next time amazon recruiters email me, I have fresh links to throw at them.) Our other religion (christianity) isn't doing any better.

We know exactly how to fix boomer media but step 1 is for Boomers to stop running it or being the target audience.

Tolerance of intolerance doesn't work, fascists must be punched for the same reason the immune system kills cancer cells.


February 2, 2021

There are currently 3 context stacks: one for "source" statements (resetting $LINENO), one for runtime function calls (call stack, can't be recursive because nests arbitrarily deep), and one for parse-time function assembly (which constantly drains when we're not saving a function; we only retain previously executed lines when we need to; command line history is seprate because that's raw input, not parsed structs).

I'm shuffling all this stuff to let actual shell function() calls work, and am restructuring a lot of previous assumptions as I go, mostly expressed as debugging to find a contradiction and then large structural changes falling out from that. I recently moved arg/shift/delete from source stack into function call stack, and need to move the variable list into the function call stack as well...

It's hard to do this in bite sized chunks with regression test checkpoints. After the most recent round of changes "eval" was segfaulting, and that's because eval calls do_source() which is the function that parses command text into structures from a FILE * (in this case a memopen). Calling "source" resets the argv[] list for $1 and shift and so on which means it adds a struct sh_fcall to the function call stack because that's where that lives. And when do_source does that it's using toys.optargs and toys.optc to initialize the struct sh_arg, but eval is a nofork command with a NULL optarg string so its arguments are in toys.argv instead with toys.optargs left NULL, and that's why the segfault when expanding $* with a null pointer in TT.ff->arg.v.

It's actually more complicated than that because eval reuses the $* expand plumbing to turn its arguments into one big string to feed to do_source(), so I need to feed it toys.argv as arguments, call expand_one_arg("$*"), and then put the previous arguments BACK so when I do_source() the resulting string any $1 and such that eval executes run in the right context. (I need to add a test for this, by the way: sh -c 'eval echo $*' one two three.) But that just means creating an fcall() and then popping it again right after, I've already got the plumbing for that (the struct sh_fcall stack in TT.ff).

But all this highlights the fact that the three contexts back at the start have different lifetime rules: the function list is basically like the variable list: you assign things into it with names but parsing a function() statement isn't necessarily an assignment because functions live inside blocks (if/else and while and such) which may delay or skip executing them, and they nest so a function can declare another function (each time it's called!). So a function being PARSED is not the same as the function being DECLARED which is not the same as the function being CALLED. And there's the three stacks.

I need to work out the storage lifetime for non-active functions which have been parsed but not yet declared (because we haven't executed the function() part of that if statement yet, or will re-execute it later because it's in a loop or other nested funciton call so it may get unset and reset multiple times and we may even have two functions swapping in with the same name... Inactive functions seemed like a fourth stack at first (simple command lines get parsed and then freed again immediately, how do you tangle persistent data within them that doesn't have the same lifetime as the current set of if/else blocks), but they're really an attribute of a pipeline segment roughly analogous to HERE documents. I already have an array of << EOF bodies that are addressed by index as we advance through parsing the command line, I can have an array of function bodies the same way, the question is what level they attach at and how to index them. And thinking about it, they may be an attribute of a pipeline segment, which means they're not indexed because there's just the one per segment, it's a "child" member.

And THAT means my current struct sh_function is combining two things that don't go together. It has three members: char *name, a pipeline segment list (I.E. the parsed function body), and struct double_list *expect which is basically the parsing version of sh_blockstack (which keyword to expect to end the current parsing block). The last two are used at parse time, the first two at runtime, and all they have in common is a pipeline list which is a single member of its own type. The two users are different instantiatons of this type in TT.functions which is the runtime active function list (declaring a function assigns an entry into this list, kicking the old entry with the same name if any), and struct sh_callstack TT.cc which is the source stack (and the only context in which the pipeline is self-emptying because everything is executed by default after each complete thought is read in, and goes away again if it didn't save data).

And the thing is, right now calls to do_source() DO nest. In fact I have a function prototype in sh.c for do_source() despite most toybox commands avoiding function prototypes because do_source() calls run_command() which calls expand_arg() which can have a $(subshell) or <(subshell) in it which can call do_source() again, and I dunno how to break that loop other than with a function prototype. Calls to the "source" comand also recurse into do_source(), which means that IS an actual recursive function and might as well just keep the call stack in local variables. (And I should add a stack depth probe depth probe to do_source() similarly to the toy_exec_which() probe in main.c, because nommu. Admittedly if you "echo source sh.sh > sh.sh; bash sh.sh" right now bash segfaults, but I'm trying to do BETTER here...)

But if TT.LINENO moves to be a local variable in do_source and gets passed on as arguments it has to be passed all the way into do_prompt() which gets called from everywhere. Grrr. Runtime line number vs parse time line number, and do_prompt() is... sometimes showing both? PS1 and PS2 are parse time, PS3 (for select) is run time? Oh for... Do Not Want.

This is already WAY bigger than I want to check in as one commit, and the hole does not go through yet. Hmmm.


February 1, 2021

Happy birthday to me, and for my birthday I'm intentionally NOT paying very much attention to the rest of the world, and instead focusing on fun programming (I.E. toysh).

Sigh. Toybox is now a mature enough project that a consistent part of the work is handling bug reports from people who blame toybox for what the kernel is doing.

Oops, I checked in some notes-to-self in test.c (because Elliott wanted the [ symlink back because somebody tried to run "sudo [ blah ]" and it didn't work). And I thought "the easy thing to do is just implement those TODO items now". I was wrong (about it being easy).

The problem isn't that ~= and string compare < and > are ideas which came from my quick reading of the bash man page where [[ ]] apparently does that. The problem is that what bash does is... non-obvious?

First of all, it's not ~= it's =~ which makes NO sense when != is right there (along with <= and >=), but fine. Don't wanna stomp $((x~=4)) being an assignment I guess, despite [[ ]] and $(( )) being different contexts with different operators. And it's not recognized by the bash builtin "test" or "[" but only by "[[": again, fine (said through gritted teeth in a british accent). But then when you DO work out the syntax enough to actually try to use it:

$ [[ abcde =~ '[b-d]' ]]; echo $?
1
$ [[ abcde =~ '[f-x]' ]]; echo $?
1
$ [[ abcde =~ 'a[b-d]*e' ]]; echo $?
1
$ [[ abcde =~ 'a[b-d]*' ]]; echo $?
1
$ [[ abcde =~ 'abcde' ]]; echo $?
0
$ [[ abcde =~ 'abcdef' ]]; echo $?
1
$ [[ abcde =~ 'a[b-d]cde' ]]; echo $?
1
$ [[ abcde =~ 'a.cde' ]]; echo $?
1

It doesn't work? What actual regex syntax is this thing accepting? The only "true" in that entire mess is the LITERAL MATCH.

Wait:

$ [[ abcde =~ [b-d] ]]; echo $?
0
$ [[ [b-d] =~ '[b-d]' ]]; echo $?
0
$ [[ abcde =~ a[b-d]c ]]; echo $?
0
$ [[ abcde =~ a[b-d]d ]]; echo $?
1
$ [[ abcde =~ a[b-d]*e ]]; echo $?
0
$ [[ abcde =~ a[b-d]..e ]]; echo $?
0

Quoting a section makes it literal, not regex. Which means I can't easily hand it off to an external command like test.c that isn't quote aware (doesn't have access to the sh data structures or global block). And it's regex syntax (not glob) which I don't already have my own quote range aware implementation for.

Bash's implementation details keep floating to the surface. They use in-band signalling for everything, and they punish you for NOT using in-band signalling. Sigh. Have to think about this one. (I wrote my own regex implementation in my first job out of college, it's not that I CAN'T do it again, I just really don't want to? Hmmm...)


January 31, 2021

Can we put AOC in charge yet? She actually addresses the real issues. (But I will admit Kamala Harris is acting more like AOC than I expected.)

We now know that the Secretary of Defense ordered the DC national guard NOT to arrest the maggats invading the capitol on January 6th, and the orders are dated January 4. That's about as inside job as it gets. And of course the vast right-wing propaganda network (started by Rupert Murdoch and Roger Ailes and so on back in the 1970s, but these days metastasizing into factions) went all in on it too.

Meanwhile, fresh nazi protests are being ignored by police because the police are on the side of the fascists (which is why their budget needs to be zeroed out), and the Boomers continue to fail predictably.

Old fossil fuel wells continue to poison the environment after they're abandoned: methane is lighter than air, it leaks up on its own once you punch a hole in the mile or so of rock containing it. Old oil wells are the next generation of superfund sites, and the lawsuits going after the oil companies once the Boomers die are likely to make love canal look like spilled milk.

What's the intersection of impostor syndrome and bullshit jobs where you're absolutely terrible at your job and get all the business anyway because you have status and money? I mean, other than "white male"? (And the occasional white woman.) Arthur Anderson was like that during the 2008 mortgage crisis, Enron was like that under the Dubyah administration, Bernie Madoff scammed a bunch of rich white guys via affinity fraud, and 80% of mutual funds lose to the market averages (which means they grow slower than index funds that make literally zero investing decisions). The poor are essential workers, the rich have bullshit jobs.

"Privatization" of government work means some parasite is inserting gratuitous profit-skimming middle men into a process that doesn't need them. It's not because the government can't do it. The government ran the New Deal, fought World War II, and landed on the moon via competent federal agencies. The post office worked way better before it was semi-privatized. The IRS knows exactly how much tax you owe, Intuit and TurboTax and H&R Block insert themselves into the process to get paid to hand off data you already have to people who ALSO already have it. But quiet competence is not rewarded for the same reason that the vast last-minute effort to prevent Y2K from being a disaster made everybody think nothing would have happened if they DIDN'T do all that work.

"Algorithmic bias" is the modern version of racists inventing stupid snake oil metrics to look down on others with. It's older than phrenology.


January 30, 2021

I went down a rathole of redoing tests/file.test because the toysh "should I run this script" test that currently explicitly checks for an ELF file (to avoid spamming lots of binary nonsense out as syntax errors when you "sh -c /bin/ls" or similar) does NOT notice if you try a mach-o binary, or a jpeg, or...

I suspected "the first line is valid utf8" might be a good test because the ELF check is really noticing "the first character is high ascii but it does not produce a valid UTF8 sequence". And I went what ELSE is like that? (Yes, I've since noticed that 0x7f is NOT high ascii, it's one char below that, but this is what sent me down that path...)

So I looked at the file.c plumbing, and invalid utf8 on the first line would catch PNG, and Java class files, and jpeg starts with ff (which would be 8 byte utf-8 and the unicode loons capped it at 4), gzip, xz, bzip2, Mach-o, whatever "android sparse image data" is...

I really don't care about ogg because it's been ten years since I encountered one in the wild and that was the recordings of a Linux conference trying to make a point. The signature of "Android DTB" may actually BE valid utf8 (0xd7b7ab1e big endian has high bits 110 10 10 0 so congratulations, I think you scan at least for the length of the signature file.c is checking)...

But this test does NOT catch gif, tar, cpio, wav, bmp, zip, or truetype. (And, let's be honest, ELF.) But all those end the first line with a NULL byte which xgetline() isn't noticing because it automatically strips the null terminator. Hmmm... The thing is, even if I drop back to normal getline() and check length/terminator myself... you can go a megabyte without having a newline in one of these file formats. I kinda want to read a chunk then back UP to do the line stuff. Is that reliable here? It isn't when you source <(output) and I kinda want to support that. I only need to special case the first line, the question is how...

And neither test will catch ar archives, ala "libc.a", which goes through TWO newline terminated ascii text lines before going into binary stuff, the first of which is "!" which is almost valid shell syntax. And an android dex file (whatever that is) also starts with a valid newline terminated ascii line.

But anyway, I looked at tests/file.test to see what input it was feeding in for some of these file formats where "yes you check the first 4 bytes but is there a NULL after them?" and... it's only testing like half the file formats that file.c knows about (no ar, no cpio, no mach-o...), and isn't testing remotely all the options that file.c is checking for within those file types. So I started making a list...

What I SHOULD be poking at is toysh function body lifetime and how to store the parsed input lines, and untangling the multiple list contexts.

Ok, what I REALLY should be focusing on is GPS code for $DAYJOB, but I want to get this tied off and checked in. It's time to cut a release...


January 29, 2021

Dear Vox: we've BEEN in a "period of political violence" all our lives, it was just aimed at brown people until recently, whom police have been casually murdering in large numbers for centuries. (Cowboys vs indians, slave ships with an average 30% mortality rate, random racism against irish refugees from the potato famine, the chinese exclusion act, FDR's japanese internment camps...) Police protect the rich from the poor. As white supremacy collapses they're circling the wagons tighter and tighter with ever-fewer Boomers inside, and shooting randomly out into everyone else.

The Occupy Wall Street protests were mad that the 1% was screwing the 99% after the 2008 Mortgage crisis, but had no leverage to fix it. The Black Lives Matter protests are even more people mad about basically the same issues: billionaires are using faux news to dupe poor white men into replaying Pickett's Charge on behalf of modern day plantation owners, to distract from the billionaires stealing everything from everybody. Plutocrats have always used racism to divide and conquer by convincing poor white people that even poorer minorities are the "real threat" to distract them from the wealthy slumlords (payday lenders, dollar store owners, wage theft, medical debt...) actually screwing everyone over.

I'm really hoping this is an extinction burst, that the idea of "whiteness" dies out, that the GOP goes the way of the Whigs and Federalists before it, and the Evangelicals go the way of the Shakers. The GOP has reached the point that democracy literally cannot survive their continued existence. The GOP has eliminated any middle ground in being for or against them: remaining a bystander watching an assault take place in front of you makes you an accomplice, we're long past plausible deniability. That's not a survival strategy for plutocratic white patriarchy, that's a "last stand".

Unfortunately this is a generational shift, empowered by 2/3 of the Boomers going collectively senile. And despite the year+ reduction in US average livespan due to Coronavirus already, and accepting the Generation Jones hypothesis, the expiration date of 1954-vintage Boomers is still 10 years out. There's a lot of work to do between now and then.


January 28, 2021

Internet flash mobs recently discovered the centuries-old concept of the "short squeeze", and have been using it to beat money out of hedge funds like a pinata. This clearly struck a nerve and the billionaires fought back with blatant market manipulation. (As in you can sell but not buy these shares, and if you don't they'll take your shares from you.) This is why the guillotine was invented.

Boomer Media is handling it about as well as can be expected (and of course right wing loons are trying to copy or hijack it as always), but tonight AOC did an excellent twitch stream where one of her guests explained that "Robin Hood" is backed by one of the two hedge funds that bailed out the original target hedge fund, and that's why they did the "sell but not buy" thing, and sold people's stock for them without asking. (Stealing from the poor to give to the rich.)

At least there is some pushback against the billionaires. Whether or not they ultimately lose, finding a new way to fight back seems like a good thing. Occupy Wall Street was experimental, the BLM protests and organizing work Stacy Abrams did in Georgia built on that stuff. That's probably why the newly re-occupied wall street is trying so hard to nip this in the bud...


January 27, 2021

At least there's some pushback on the Boomer pearl-clutching sour grapes about sex still existing now that they're too old for anyone to desire them, but the situation still looks like "Boomers Die, then we scrub the world clean of their crazy".

The GOP remains irredeemable to the core, and Boomercrats are Good Cop enabling Bad Cop but both serve plutocracy. At least Good Cop minimally responds to sustained screaming in its ear, if only to keep up appearances, but it's not MUCH leverage and they backslide if you give them an instant to breathe... Speaking of plutocracy, here's a short but excellent thread about how Late Stage Capitalism is utterly artificial. And speaking of late stage capitalism being corrosive, both Teespring and Hipstercart have gone bad. (Not necessarily MyPillow or Bain Capital levels of bad, but at least Chick-Fil-A and Wal-mart levels of bad.)

We need to defund the police because being police is not even good for the police, and we can do so much better things with the money. In that last link, the City Council here in Austin used money cut from the police budget to buy a failing hotel to permanently house homeless people, and an ex-homeless woman who's since won a World Fantasy Award for her writing talks about the benefits of doing exactly this. Type "abandoned hotel" into youtube to see a zillion videos where urban explorers go into places that _could_ have housed the homeless, but didn't because cities instead paid racists to be utter dicks.

Remember the viking cosplay insurrectionist snowflake who was starving to death without "organic" food? Yeah, the whole "organic" movement is quack medical science from nazis all about "purity" and scaremongering, so of course he'd be into it. There's a behind the bastards podcast episode about this topic.


January 26, 2021

Fielding some toybox bug reports: good reproduction sequence for a netcat bug, and people are using getty out of pending. Sigh. If toybox was my day job I'd try to do a WAY better job of shovelling out the pending directory, but as is I just don't have the time/energy...

Meanwhile I can't build current qemu git because I need a newer python source, and I can't boot a current kernel on m68k until I get the new qemu with the workaround to the kernel regression, and I can't get python 4 or whatever it is until I upgrade devuan from "ascii" to "chihuaua" or whatever the next release is that's been out forever and I haven't dealt with. (Or am I two behind at this point? Nope, Ascii is "old stable" but still nominally maintained except chrome keeps complaining it's out of date with no update queued in apt-get, Beowulf is current stable, and Chimaera is "in development" and Ceres is "unstable", whatever the difference between those is.)

And to "apt-get dist-upgrade" I need to close rather a lot of open windows on 8 desktops. It's not the literally hundreds of chrome tabs in over a dozen chrome windows that's the problem (if I lose those, eh). It's that I have a lot of terminal windows open with a lot of tabs in them, and those tend to have tests I ran that should go in the toybox test suite (often multiple tests per window, in the backscroll), and others have todo items I left off in the middle of that should go into one of my zillion todo.txt files in various project directories.

I'm dinking at it, but it's slow going. There's several months of backlog since the last time I rebooted this laptop...


January 25, 2021

The Donner Party resorted to cannibalism because they ignored the food the native Washoe people left for them (rabbits and wild potatoes), and shot at the ones who tried to bring them a whole deer. White people are the authors of their own problems, and we tend to hold up self-inflicted idiocy like "remember the alamo" or "custer's last stand" as examples of virtue instead of monumental stupidity. We're totally doing it with climate change again as we speak, just like we did with the Dust Bowl a hundred years ago. White men and plutocracy and the pervasive legacy of racism they engender remain the real problem. Luckily that problem seems at least somewhat self-limiting, but the collateral damage is biblical.

The Boomers have turned into the most prudish generation since Queen Victoria, trying to outlaw sex now that they're done with it, and the Boomercrats are right on board with the GOP's desire to outlaw women being anything but silent compliant wives. As usual, Sarah Taber has a good thread on the issue.

The GOP keeps posting video of themselves committing crimes, which still isn't enough to get useless Boomer Media off the "both sides" fence.


January 24, 2021

Capitalism is officially killing humanity, not even from global warming but from declining birthrates. People in capitalist countries can't afford to have children, it's too expensive. One interesting idea for a tiny band-aid is applying "modern monetary theory" to child support by having the government pay child support directly and then collect from the parent after the fact.

MMT is based on the observation that since the government is where money comes from, the government literally CAN'T run out of money, and the point of taxes is merely to control inflation. The government disguises printing money as "borrowing", but it's borrowing from itself. Ever since we went off the gold standard in 1971 (under Richard Nixon) and switched to "fiat currency", the Treasury department has regularly "borrowed" money by issuing bonds (IOUs that pay interest) and selling them to the Federal Reserve, which is the organization that creates digital money in the banking system.

Treasury bonds sold to the Federal Reserve are bought with newly created digital money. When the Fed issues an EFT (Electronic Funds Transfer), it doesn't come FROM anywhere, the Fed is the origin point that inserts new money into the system. This is also what happens when banks borrow from the Fed's "overnight window": they're borrowing newly created money (via wire transfer), and promising to pay it back (with another wire transfer) at negligible 0.1% interest. The Fed is the one bank in the USA that never has to balance its books: it can add money to an account by just changing the numbers in its computer. And that is how money is printed today. (The supply of physical cash is irrelevant to the supply of MONEY. Newly manufactured paper bills and coins can be "bought" from the bureau of engraving and printing with this digital currency, but these days most money stays digital: neither direct deposit of paychecks nor electronic bill payments actually involves cash changing hands. Even if you write a check it's scanned and OCR-ed and turns into an electronic payment behind the scenes, and those digital dollars being transferred all originate at the Fed.)

The sleight-of-hand exchange "borrowing" from the Fed hides the fact that "creating money" is actually what's happening, but the end result is the government (through the Treasury department) now has newly created money it can spend, and this happens ALL THE TIME. It's called a Treasury "auction", where the Treasury offers the new bonds for sale theoretically to all bidders (this is a way for billionaires and corporations that don't trust banks to hold their money to park it somewhere "safer" than in a bank account), but any bonds that don't sell at auction always get bought by the fed: treasury bond offerings never have any leftover unsold bonds.

And no, the government doesn't ever have to let the interest rate go up if it doesn't want to, the Fed sets the interest rate by specifying what price it will buy Treasury bonds at in the auctions. If another bidder doesn't offer more than that amount at auction then nobody else can buy any bonds, the Fed gets them all. And paying more means you get a LOWER return: If a bond is worth $10000 in 10 years and the Fed is offering to buy it at $9900, you need to offer more than that to get it, and that means the $10/year average profit the Fed would get as "interest" is even less for you. (Not that the Fed really cares about the interest: they don't NEED money, they're where money comes from.)

Treasury bonds are a government IOU, but when the Fed buys them it's an IOU from the government to itself. To pay the currently 0.1% "interest" the government can always sell more bonds (to the Fed, if nobody else buys them). So the government can't run out of money, all it has to worry about is inflation, and Japan's spent 20 years trying to CREATE inflation... and failing. Inflation in the United States has been falling for 30 years despite the enormous federal bailouts after the 2008 mortgage crisis, the 2001 dot com crash, the 1991 savings and loan crisis... Yeah, capitalism collapses and needs a huge injection of newly-printed federal money each decade. The current round of bailouts are being blamed on Covid but to be honest we were overdue. It's always something, because the system is rotten. Late Stage Capitalism doesn't actually work, and needs to be constantly rescued, propped up, bailed out.

The idea behind basic income is A) bail out the 99% instead of the 1%, and B) do a constant drip-feed instead of having an existential crisis every 10 years. That's it. Other than that, it's what we're ALREADY DOING. After the 2008 mortgage crisis the Fed injected $29 trillion into the economy (as "quantitative easing" and so on) to prevent a collapse. Averaged out over the decade between regular economic collapses that's $3 trillion/year, divided by ~300 million people in the USA is $10k/year. There's your basic income, right there. Just give it to everybody instead of rich people and corporations.

The government doesn't have to come up with the money for it, they just have to tax enough AFTER THE FACT to keep inflation manageable. Since billionaires and corporations own more than half of all wealth already, they are who you would logically tax to drain any superfluous pools of idle money clogging up the system. I've previously done the math to show that while 80% of the population used to work growing food, less than 2% does now, and less than 15% of the total workforce actually does ANYTHING related to human survival (food, housing, medical care, teaching...) instead of "entertainment" (which people constantly do for themselves when they're not being sued over IP rights, from fanfic to youtube videos) or pointless bureaucratic/financial shenanigans. The University of Texas has 3721 faculty but 24,000 faculty and staff meaning it has 5 times as many bureaucrats as teachers, and it is not remotely unusual in this. (David Graeber's excellent book Bullshit Jobs went into this at some length, and he has another called "The Utopia of Rules" about bureaucracy specifically which I need to read.)

The spiraling inflation in zimbabwe or 1930's germany wasn't because of money printing, it was a supply shock. When there isn't enough to go around people scramble to meet their needs, otherwise they bargain hunt, save extra money, buy optional extras like maid service instead of suddenly wanting 3x as much mac-n-cheese, and spend money on things like pay-per-view movies that can't run out. (Capitalism is GOOD at inventing empty nonsense for people to spend money on.) When supply meets demand you have GROWTH, not inflation.

The 1970's "stagflation" in the USA took place during the first major Opec oil embargo and a global crop failure: there wasn't enough food or energy to go around, and people couldn't easily do without either. Plus we left the gold standard for fiat currency in 1971 (in RESPONSE to already-existing inflation) and it took a few years to work out how to properly use the new system. We haven't repeated those mistakes for a long time now because we figured out we don't NEED to. If you haven't got shortages of things for people to buy, and you have competition among producers who aren't extracting monopoly rents (by intentionally CREATING shortages as the only supplier of the thing, thereby "cornering the market"), you tend not to get much inflation. When you have shortages, you get inflation even when you don't add money to the system (because those who do have money outbid those who don't for the limited supply).

A controlled amount of inflation is good for normal people, not just as incentive to spend and keep money flowing and the economy ticking over, but because 2% annual inflation means that 2% of your mortgage and student loans are paid off every year simply because the old dollar amount is less money today. If you have $50k of student loans that's $1000 of the principal paid FOR you each year. (A hundred years ago $4000 would buy a house. Today, paying off $4000 of debt is not as hard as saving up to buy a house entirely in cash with no mortgage. Yes if the minimum wage isn't raised that's a separate problem, but even social security has an annual Cost of Living Adjustment and as stagnant as our minum wage is, it WAS raised in 2009 and is $15 already in a lot of jurisdictions.) The stagflation of the 1970's paid off half the mortgages on the Boomers' starter homes.

Rich people don't want any inflation at all because they're who money is owed TO. Creditors who are owed specific dollar amounts hate ANY inflation, which is why you hear so much hand wringing about inflation from rich people who own everybody else's debts. Rich people and corporations can buy very large megaphones and entire think tanks to trick people into thinking "what's good for GM is good for america" when it simply isn't true.

But deflation is as bad for an economy as running out of oil is for an internal combuston engine: if my money will be worth more tomorrow why would I spend it now? But if everybody stops spending at once the economy collapses (everybody's unemployed, no customers, unsold inventories pile up), and deflation turns out to be sticky: once you're in it it's hard to get out, just like the "zero lower bound" problem with interst rates a few years ago. The annual inflation rates for the first 5 years of the 1930's "Great Depression" were 0%, -2.3%, -9.0%, -9.9%, and -5.1%. The Fed has targeted 2% annual inflation to leave a little buffer so every little market hiccup doesn't immediately put us into deflation, except that turned out not be be enough. We eventually hit the zero lower bound and got stuck there anyway, and the people arguing for a higher (5%) annual inflation rate way back when were retroactively proven right.

Traditionally, controlling interest rates was how the Fed controlled inflation, because it let the fed add money to the system (by lowering rates) or drain money out of the economy (by raising rates) due to encouraging or discouraging borrowing (I.E. going into debt), because banks create money too every time they make a loan. If I have $1000 in my bank account, and the bank loans it out via somebody's credit card purchase, that money exists twice. (Or three times if you count the value of what the person bought and the payment the vendor received for it as well as the bank balance.) When the loan is paid back, the multiplier goes down. (And if I withdraw cash at the ATM which the bank doesn't have on hand, it borrows from the Fed overnight window mentioned above, except that's not a real issue these days, lax regulation and plutocracy allows big banks to more or less create money like the Fed does now.)

But after the 2008 crash the global economy got stuck at the "zero lower bound", were even an interest rate of zero wasn't enough to get money flowing again to dig us out of a demand limited liquidity crisis. They've even pushed some interest rates literally negative to try to raise inflation... and failed. Japan's been stuck at the zero lower bound 10 years longer than the rest of us, and still not quite out of it despite years of trying.

In the modern economy, when most people get extra money they're not buying things. They're paying student loans and credit cards, and a lucky few are saving for the next emergency (let alone retirement). With 1% of the population capturing 99% of the gains ever since Reagan, wages haven't gone up and people have been forced into debt to cover the gap. Billionaires love this because everyone else is indebted to them: unlike federal debt the government owes to itself, every dollar of private debt is owed TO somebody, and that's where billionaires come in. All that money everybody else has borrowed winds up in their pockets, as does the newly printed federal reserve money the treasury borrows so the government can spend it, billionaires suck that up too. But massive private debt and financial inequality is an incredibly unhealthy way to run an economy, which is why it keeps crashing.

PUBLIC debt is just money printing in disguise. Conflating public debt with private debt is a trick billionaires pull to keep the inequality going. Always enough money to bail out the rich, never enough money to bail out the poor, because without the poor desperate to dance for pennies the wealth of the rich is meaningless. Warren Buffett does not hire Bill Gates to wash his car.

Circling back around to "being able to afford to have kids", a National Health Service paired with Basic Income means that if you want to be a stay-at-home parent, you can do that. Populations of capitalist countries are going to continue to decline, and lose out to countries that subsidize the creation of new citiziens. Boomers will never understand this, and Billionaires will never allow it. But once they're gone the right thing to do is obvious.


January 23, 2021

We still need to eliminate faceboot, which just did a purge of left leaning pages. Meanwhile GOP state legislatures are currently passing fresh voter suppression bills while the Boomercrats argue amongs themselves about doing the obvious. But at least this clown can get financially pummeled now.

Capitalism is not well. The CEO who cut his pay to raise all his employees salary to a minimum of $70k points out that he didn't just prove it works, he proved other companies won't do it unless forced.

Boomer media continues to suck at epic levels, and Boomercrats are looking to preemptively pardon as many capitol insurrectionists as they can get away with because it's too much work to charge them all (unlike the endless flood of brown people going into for-profit prisons), and that's why we need to defund the police. If they're happy to let THESE clowns walk, why do they bother to arrest anyone else? The Seattle police are doubling down on prosecuting wednesday's "Abolish ICE" protest. Police unions aren't real unions, we need to defund the police now more than ever. Of course they released flex-cuff-guy from the capitol invasion, they only punish brown people.

The boomercrats aren't "falling for" the GOP's rhetoric: Good Cop is complicit. It's a servant of the plutocracy currently running the exact same "divide and conquer" playbook as southern plantation owners in the 1800's: that's what all the racism IS, rich people arranging "let's you and him fight" so nobody gangs up on the real parasites making everyone's life miserable. Racism in the united states is engineered. It's carefully cultivated so rich John Galt wannabe libertarian assholes can exploit the poor without ever facing united opposition. I think we will only ever pass the amendment to overturn citizens united over the Boomers' dead bodies, but I'm happy to be proven wrong there. (Or be proven right, just pass it.) Interestingly, it seems the term "bipartisan", like billionaires, is only as old as the Boomers, as is the fillibuster.

Guillotine the billionaires because the parasite class insists they will only ever be taxed over their dead bodies, and we should take them up on it. Not singling out any specific billionaire, change federal law so that ANYONE hoarding an offensive amount of capital is committing a capital offense. It's an uphill slog because Good Cop serves the plutocracy, but it's good to have goals.

Russia is having protests.

Sometimes I worry about drones and boston dynamics killbots micro-policing the population into a pacified dystopia the way the KGB tried hard to do in east germany, then I remember that they can't cope with feral hogs and invasive pythons. The real world is always way harder to deal with than laboratory conditions.

Only 5% of US corn is fed to cattle, about 3 times as much is used to make high fructose corn syrup, and almost half goes to make ethanol for cars (not just gasohol, it's all got ethanol in it for anti-knock, these days _without_ gratuitous lead in the ethanol for intellectual property reasons).


January 21, 2021

Jeff and I are giving an online j-core talk a week from friday.

Still doing lots of little GPS programs to evaluate satellite encoding candidates for the ESA bid proposal we've already missed the first deadline for. This is not really my strong suit, but we're overscheduled and I'm a jack of all trades equally bad at lots of different things. I'm the guy you throw problems nobody else is available to do at. It's... really slow going, and as with previous GPS stuff it took a couple days to context switch into it and I can't really work on toybox stuff while doing it. They fight in my head...

Why do I want Android to win? Because Apple is now blocking sideloading on desktops. And yes, this is a follow-up to macs unencryptedly phoning home to Apple's servers for permission to launch every program. Google has its issues but Apple is "all the evil of microsoft, but mostly competent and somehow even greedier". (And I mention this on a GOOD news day because my toybox project is aimed at helping Android kick their ass. Problematic as it is, it's open source, customizable, available from multiple competing vendors, and capable of coexisting with other systems. You can use gmail on an iphone, you can't use apple keynote on any other system.)

Here's an engineering argument for Basic Income, and it's good to see the $70k minimum wage spreading.


January 21, 2021

Tax appointment today. Looks like I owe about $6500 (despite 104 days of per diem in japan deducting $229/day: jan 8-feb 18, oct15-dec 15, 24 in jan, 18 feb, 17 oct, 30 nov, 15 dec = 104). The problem is I have to pay self employment tax because Coresemi hasn't got a US subsidiary. Sigh. Let's see how much I can save up between now and April 15th. Applying the second stimulus check to it is a start...

The pandemic has gone to plaid.

The boomercrats are once again exploring preemptive unilateral compromise before even approaching the GOP, but I'm still hoping they don't fall for it again, but then Good Cop is still a fully owned subsidiary of late stage capitalism.

Here's a thread about a guy taking a college course in the age of Covid (I.E. online lectures) who tried to email a question and found out his professor died two years ago, but the university still lists him as the professor because that's who recorded the lectures. This is why we need basic income: the job has essentially been automated away, no living human is doing it, but the university is still collecting the full fee from customers to sit on its laurels as a rentier and didn't even bother to SAY they no longer have access to this content creator because it's not relevant to their business model.

We still need to defund the police. They are profoundly biased.

The collapse of oil and gas's business model is not just because of the pandemic. Putin gratuitously arrested the political opponent he recently poisoned the underpants of, and in response Europe has joined the US in opposing the nordstream 2 gas pipeline. It's interesting, the Voldemort administration opposed it because it US gas interests wanted that market to theselves so were hobbling a competitor, and the new administration opposes it (and other pipelines) because fossil carbon is cooking the planet and pipelines leak regularly. Opposite reasons, both bad news for the international fossil fuel industry. It's stranded assets all the way down.


January 20, 2021

Today is a good day. (And yes, they did the other thing. Good.)

Had to bump my return flight to japan: the place I got my covid test at last time switched to handling employer contracts only (no individuals), and none of the places I've called since will sign the form from the consulate. (Not even the one with "travel" in its name.) Plus Japan's covid/immigration policy changed again (yesterday!) so Jeff's having a japanese lawyer look at what we need to do now.

China installed 100 deloreans of renewable generating capacity in 2020 (about 70 gigawatts of wind and about 50 of solar), which is admittely only about 6% of their 2 terawatt generating capacity but still an excellent sign.

Yay, I heard back from Sundeep who pointed me at the correct defconfig and confirmed I need to use one of the forks because mainline hasn't got support. (Except all I want to do to start is run an initramfs with serial console, how much of this can I fake up with a vanilla tree?)

There should be a name for The Y2K effect where avoiding a catastrophe convinces people the problem wasn't real. This is related to "never let a good crisis go to waste" which is often attributed to Winston Churchill but dates back to at least Machiavelli. A common machiavellian technique is to never PREVENT forseeable crises (because you won't get credit for prevention, if you succeed it looks like you did nothing) and instead wait for the fire to spread and take credit for putting it out only once everybody is desperate for your solution. (Which is an evil sort of brinksmanship that gets people killed and spins out of control half the time because of how exponential curves work, but VERY effective politics when you can pull it off.)

This is why teaching stem without teaching humanities is self-destructive. This problem is POLITICAL, not technical. We need political science majors with courses in health and human services to have the backs of people doing the right thing, not 8 gazillion silicon valley douchebros extrapolating success in one narrow technical field into the dunning-kruger belief that everything else is trivial for them to understand and do, and the ensuing inevitable faceplant was obviously because they're surrounded by obstructionist morons telling them to look both ways before crossing the street, a thing they obviously do not need to do because they've never been hit by a car before, so they double down and do it HARDER.


January 19, 2021

And twitter just emailed me another "your account has been locked!" with 7 more tweets it found about guillotining the billionaires. (Keep in mind I haven't been able to log into that account since October 2019, but they're scrupulously defending billionaires from years-old criticism retroactively anyway. Apparently twitter has a quota of attacks on the left they have to do to stay "balanced" or some such? Good people on both sides...)

So we know it was the rally attendees who marched on the capitol, the Dorito is on tape ordering them to do it as part of his speech, yet investigative journalists are working to tie the rally to the ex-president? I'm confused as to what they're trying to prove here, which part of this is non-obvious? I don't know why the GOP still exists. (I mean the answer is "billionaires puppeting senile boomers", but even so.) People are attempting to explain things to Boomers but I expect we just have to wait them out. The GOP has nothing left but voter suppression, intimidation and embezzlement. And, unfortunately, violence and cult brainwashing.

Speaking of brainwashed cults, christianity in america is merging with white supremacy to become one big terrorist organization. It's interesting that nothing the church teaches, nor anything in the bible, stops these guys from beating police offiers to death with a fire extinguisher when they don't get their way. But then these "moral teachings" didn't stop the crusades, the inquisition, conquistadores, burning people at the stake, missionaries handing smallpox blankets to native americans, magdalene laundries, the church participating in the rwandan genocide, the church's peace treaty with nazi germany... Remember how Pope Palpatine was the guy in charge of covering up the decades of choirboy rape (as in covering it up was his day job before he became pope), and his successor has "fixed it" by requiring all priests and nuns to report sex abuse to their superiors within the church instead of secular authorities... So of course they're merging with the GOP.

Blaming cows for global warming remains profoundly stupid, but vegans are happy to use GOP lies to attack people they don't like. Speaking of methane, the wildly swinging price of "natural gas" (going way up and down based on the weather) makes it a bad fit for electricity generation. This year it's increased tenfold from $1.85/mbtu back in May to $21.45 for the same million british thermal units in the week ending January 8. Plus it funds Russia to hijack our government. Here's an utter asshole's highly biased explanation of how fossil fuel mining can't properly refine and distribute the products it gets and winds up dumping them into the air and rivers and such because selling them would lower the price, and only intentional supply restrictions keep the industry profitable pretty much the same way the debeers diamond cartel works.

There could easily be a daily twitter of "Cops murdering the person who called them". Oh, and the munitions used by the seattle police are toxic and there was a cover-up about the adverse health effects that just got exposed. Baltimore has 1900 police officers of which 1826 have faced complaints the department basically ignored. This is why defunding them is such an obvious goal.


January 18, 2021

Ooh, 8 year pathway to citizenship for undocumented immigrants. That's actually kind of reasonable.

Trying to get toysh out before getting on a plane back to tokyo friday.

Another problem with replacing the cached pl value with TT.ff->pl is that dlist_add_nomalloc() appends to the list but does not move the pointer, which stays pointing at the start of the list. So all references to pl should really be TT.ff->prev->pl which is just too long: it means TT.ff->prev->pl->end->arg->v[TT.ff->prev->pl->end->arg->c] is the block terminator, which you need to find when "if true; echo hello; fi" has an & or | at the end of it, or trailing redirections. You have to handle those at the start of the block so the filehandles the child processes inherit are correct.

I haven't got left-handed dlist_add() and dlist_pop() variants in lib/llist.c, I just use a singly linked listed for that which is reversed by nature, the simplest implementation pushes and pops like a stack. But if I want a "base" function call layer that contains the global variables (so the variable logic just naturally iterates to end of list without a special case, see "exported local variables" encountered earlier) then a doubly linked list lets me TT.ff->prev to access that directly when necessary. (I.E. for all the variables that are NOT marked local.) Except...

$ potato() { x=123; }
$ chicken() { local x=$((x+1)); echo $x; potato; echo $x; }
$ x=7; chicken; echo $x
8
123
7

You have to iterate through all the local variables anyway, because you can have multiple local contexts and you stop at the most recent one. So having it be a doubly linked list is silly, it should be a singly linked list, which makes it naturally reversed. Which means once again I'm frogging code.


January 17, 2021

Of COURSE parler is back online using servers in Russia. Russia has been stoking white supremacy and funding it since 2011 because it's easy way to split the country down the middle: a minority of bastards hate half the population, the more power they get the worse off everyone else is.

Meanwhile Nancy Peolosi just kicked Katie Porter off the finance committee. Now that the Boomercrats are in power, they no longer need "the squad". Keep in mind that plutocracy is currently behind both parties. (Racism has been a tool of plutocracy for centuries, divide and rule.) Obviously bad cop is worse than good cop, but good cop is not on our side.

Another argument for basic income is watching the guy behind leverage come up with equally intricate plots for his RPG campaign: creative people aren't creative BECAUSE of capitalism, it's usually in spite of it. Getting paid to create is stressful, and a huge source of writer's block. It's gotta be good enough to justify the money, and you have to KNOW it is before you've done it. How much risk is it comfortable to take when your livelihood is involved? Not everybody can perform on command, and if you get 90% there and throw it out because it's not good enough you've wasted money.

A historian makes the excellent point that our current issues with racism are because we didn't punish confederate leaders by taking their stuff and giving it to black people to start new lives with. The whole "reparations" movement boils down to "our family was enslaved for 300 years and these white assholes got to keep everything we made even after the civil war", and the resulting billionaire wealth and privilege infrastructure is behind today's racist misogynistic GOP.

In the absence of war profiteering (because nuclear weapons make war unstable), disaster capitalism has had to invent new disasters to steal money through. And now they're campaiging to "free billionaires from the constraints of democracy".

The first thing right wing loons do is attack/capture the news outlets.

The lack of municipal broadband is because of regulatory capture by monopolies.

The ongoing pandemic has already cut US life expectancy by over a year.

Every libertarian kobayashi maru thought experiment is a lie.

Defund the police. No seriously, they're counterproductive.

Here's one of the capitol rioters lamenting on the parler nazi network that he might lose his job as a pastor because of participating in the insurrection. Of course all white guys ever have to do is apologize once and all is forgiven. (The South Park movie had a musical number about that.)

Sigh. At least the end of fossil fuels is still on track, and it's entirely possible that will take out late stage capitalism. (1/6 of the global economy, and the original model for the "resource curse".) And here's an interesting thread postulating that bitcoin may be banned for environmental reasons. As climate damage increases there will be lawsuits and they may be next in line after Exxon...

Sigh. I suppose this could have been worse. ASCAP and BMI are terrible, anything they're unhappy about is probably a win? But they need to lose WAY MORE.


January 16, 2021

Today for work, I am reading another old master's thesis, and analyzing corresponding data tables. Yup, the GPS stuff has resurfaced. I really need to cut a toybox release so I can stop doing that for a while, they push each other out of my head.

Even in Austin, it's really cold out at the table outside the geology building at 3am in January. A few days ago we had actual snow that lasted a full day on the ground (in places anyway). People were making snowmen. I have gloves, a hat, a scarf, a hoodie under a jacket, shoes and socks, and I brought a towel to sit on between me and the metal bench, and I'm still cold. I want to walk somewhere for exercise and then go INSIDE, which is still two rounds of vaccinations away from being plausible. (And then what, do we get special "I've been vaccinated" hats?) I miss the booth at Wendy's I could hang out in for 3 hours between the mealtime rushes. (All the seats were empty from 2-5 pm and 7-10, it was away from the cats, easy access to snacks and endless beverage refills. I am SO ready for this pandemic to get cleaned up by actual adults.)

Wind power generated almost a quarter of Texas' electricity last year, second only to natural gas. Coal was down to 18%, and 95% of the pending generation proposals under consideration are wind, solar, and batteries. Which is good because the fossil fuel industry is funding literal nazis. (Fascism is where the Koch brothers got their money. Their daddy made his fortune working for Joseph Stalin as the oil drilling expert who got the USSR into the oil business in the first place. But even numbered day, focus on good news and programming stuff...)

I poked the guy who broke Linux on m68k QEMU and he basically said "yeah, I know, upgrade QEMU to get the workaround for my change", which I can't do because building current qemu requires a newer python 3.x than Devuan ascii packages, so it won't compile from source until I upgrade and I have a few too many open windows to want to do that right now.

Toysh: I need to background nonterminal pipeline segments, and THAT means the current pipe handling should also handle & backgrounding, which I guess is why break & is a thing in bash. Bash is also backgrounding the last command in a pipeline, hence the "echo | x=5" behavior where variable assignments in the last pipe segment are discarded by bash... but is it a bad thing if "echo $x" prints 1 after that? Prefixed assignments only last the length of the command anyway, what else could a trailing standalone assignment mean? Bash not honoring it seems a bit like a bug.

Except only type 1 needs to get backgrounded for | because normal type 0 commands are already spawning child processes when they need to. (Unless you exec in a pipeline which is pilot error if you ask me, I vaguely recall playing with that earlier and being kind of exasperated at what bash was doing.) And the redirects should be done and unwound again before backgrounding (again, for nommu) so the sequencing is wrong.

I want to avoid duplicating the backgrounding plumbing, but really it's only type 1 that needs to do anything new. Unless... hmmm. Some builtins (wait, read, suspend) can block. But then "echo $(sleep 999)" can too? And some builtins (exec, exit) can exit. And what does return in a pipeline mean?

$ chicken() { echo | return 37; }; { chicken; echo $?; } | cat
37
$ chicken() { echo | return 37 | echo potato; }; { chicken; echo $?; } | cat
potato
0

Nope, terminal pipeline segments ARE being treated differently than nonterminal pipeline segments by bash. Sigh. (But not consistently! They have that darn short-circuit logic where sometimes they run a command directly without the extra fork, and it's some sort of heuristic.)


January 15, 2021

Microsoft is performing a digital book burning, and it's a normal part of Late Stage Capitalism. Meanwhile, Bill Gates uses the ill-gotten gains to become the USA's largest landowner. Youtube possibly needs a rethink, not that this is a new observation.

Police are "worred about a black eye for the entire profession" due to so many off-duty officers being part of the capitol mob that tried to capture and assassinate elected officials. The fix is to have fewer police officers, the path to get there is defunding. At some point you go beyond "useless" to being net "part of the problem". The carceral state is charging BLM with felonies for actual peaceful protesting while ignoring actual insurrection. The point of defunding the police is you move the money to other more important things. Calling the police or fire service doesn't cost $2000 for one vehicle to show up, but calling an ambulance does? You still have the national guard and such if an active shooter situation breaks out. (You know, those services who were denied _permission_ to come to Washington DC to help out.) In June, DC Police arrested 5x as many people during an anti-racism protest as they have for the capitol invasion. Defund them, they're racist bigots.

The evangelical rapture cult is still poised to pass a flurry of bills outlawing birth control and being gay and so on, but now they're focusing on doing it at the state level instead of the federal level. (That's why they were installing all those judges, so making pre/extramarital sex a felony punishable by death can't be struck down in court.) The Boomers are old and trying to buy their way into valhalla at the last minute, so they'll take whatever snake oil is sold to them that makes dying sound easier, and Boomers have had such unhealthy relationships all along they think constantly hurting people is normal.

Opec's released numbers from oil prices going negative last year, $595 to $323 billion is almost a 50% decline. $202 billion of which went to Saudi Arabia, but they've screwed themselves over with the privatization/IPO of aramco. Six months ago all the oil producers were borrowing money to stay afloat and that debt load hasn't gone away. (Not that soverign debt actually means anything in modern economies, it just affects inflation and exchange rates. But "company" vs "country" is an interesting distinction. And foreign curency exchange and debt denominated in foriegn currency are a big deal no matter how much money you can print, self-sufficiency in basics like food, water, and energy are a big national security issue.)

Meanwhile in the USA, all fossil fuel fields are overvalued and the rebooted SEC just noticed. And in China, the Xi administration seems almost as weak as the Trump administration, at least when it comes to energy policy. Their stated goals are not what actually happens in the country. Of course that was back in october, now they've doubled down and caused another Mao the Dong style crisis. (Dunno the body count from this one yet, but freezing to death isn't fun.) Speaking of methane note the "5-6pm prices": duck curve (woo-ooo).

Oh look, another way rich bastards stole half a billion dollars of pandemic money. The maggats are still begging for pardons from a man infamous for not paying his workers. The NRA is declaring bankruptcy and swapping juristictions to try to escape pending litigation.


January 14, 2021

Good news: we have a fourth vaccine, this one from Johnson and Johnson. Similar to the Oxford vaccine, it's a conventional "store below 8 degrees celsius in a normal refrigerator, lasts up to 3 months, only needs one injection" type. Not the fancy new MRNA nonsense that decomposes instantly upon exposure to brightly colored wallpaper or in the presence or large flowers. And remember that CEO who took a pay cut so he could raise his minimum employee salary to $70k/year? His company has survived the pandemic just fine.

A bit concerned about an ongoing thread on linux-kernel where they're tacitly acknowleding that since the Linux Foundation finished the corporate-friendly purge of all hobbyists, their development community is not just aging but shrinking (obituaries aren't quite a section at Linux Weekly news yet, but they're definitely increasing in number), and the response is to throw hardware support overboard.

Unfortunately arch/sh looks a lot like #1 on that thread's list: it started renesas-only, they abandoned it, now it's SEI/Coresemi only because we haven't built a proper community and we vanish for months at a time... Not an _immediate_ threat, but despite repeated poking Rich hasn't sent patches upstream in months.

Speaking of which, the post in the thread I linked to is by the guy who broke qemu on m68k, I should poke him about that...

Also, now that qemu-system-arm has -M emcraft-sf2 support, I'm trying to find the kernel .config for smartfusion2. This is the board I used at innoflight, it's a nommu cortex-m3 system (with a large currently irrelevant FPGA attached) and would be great to add to mkroot's list of test systems as my cortex-m boot. (Arm thumb2 nommu: check.) Alas, I last used this 3 years ago (in one of the holes in my blog, I should check my USB backups to see if I can find the files I wrote but never published during that period) and I can't find the kernel config for it. The emcraft website (a company headquartered in Moscow) wants you to register to download half their stuff. (It's the same problem Renesas had with qemu-system-sh4, the idea that anyone other than paying customers exists is confusing to them.)

Emcraft has their own kernel fork on github, and the guy who submitted support to qemu also has a github but I'm not finding an obvious defconfig there either. So I emailed him. (I VAGUELY recall it's an stm32? I think? But I built stm32_defconfig with the musl-cross-make cortex-m toolchain I build toybox release binaries with, and -kernel vmlinux died with "can't escalate 3 to HardFault" whatever that means, and qemu couldn't load -kernel arch/arm/boot/xipImage at all. And when you google a LOT to follow obscure links to archived pages it just boils down to "cd into our magic tarball and type make", and the page ends with a note effectively saying "buy the .config from us, no questions answered without money".)

In toysh land, run_function() is now run_lines(), and call_function() has been broken out into its own thing, and I got rid of the pl local variable to just use it out of TT.ff->pl each time. (Which is verbose, but means there's a single location for it. Having a local variable cache a global variable is what the optimizer is for. Keeping said cache in sync by hand and flushing it back as appropriate is a brittle pain.)

This is a much longer slog than I'm happy with before I can get the pieces back together compiling and running the test suite again. I'd _really_ like to get a release out before getting on the plane back to tokyo...


January 13, 2021

When the electoral college vote reconvened after the coup in the capital, the GOP continued to object to Biden winning, and now they're calling for unity. That's not how unity works.

The coup was an inside job. There was nothing spontaneous about it, it was planned and supported by the entire republican party. People trained for it. Then right after the insurrection the GOP reps still voted against certifying the election, and now they object to impeachment. They still side with the treasonous dementia patient, even now. That's what their votes mean. It's ok when we do it, only what YOU do can ever be wrong. The GOP wants "conservative" judges who can outlaw abortion and so on, and are happy to murder people to do it, and scream victimization at minor personal inconvenience, all while mishandling a pandemic.

The problem is rich white people. They're who caused the civil war, they're why we haven't got medicare for all or Universal Basic Income, they've been driving up the price of rent and real estate, and now they're trying to violently undo a democratic election.

Another report just came out about the Catholic Church's Magdalene Laundries where pregnant women were kidnapped, forced to give birth, and the results either given up for adoption or interred in mass graves (15% mortality rate because they gave basically no medical care due to "sin"). On this side of the atlantic evangelicals trying to take down the US government are a more immediate concern. After all, Ireland shut down the church's pregnant woman kidnapping operation in 1998, and voted to legalize abortion two years ago.

Defund the police and give the entire department's budget to this guy and let him sort it out.

Seriously, the whigs ended, the GOP can too.


January 12, 2021

Sheldon Adelson died today. He was the largest political donor in the USA, all of it going to GOP loons. I know it's bad form to speak ill of the dead but he earned it. Despite everything, it is a good day.

The toysh function() plumbing has a design contradiction: after the set of design changes I'm making, it won't actually be called to run shell functions.

I don't want to recursively call run_function() because nommu has limited stack depth (both because it cann't do on-demand allocation without page faults so it has to consume the entire maximum amount of physical memory up-front, and because the stack has to be a physically contiguous memory allocation which is often the limiting factor on a busy nommu system; so while most linux stacks are 8 megs/thread, nommu stacks are usually in the 8k-128k range).

So I moved the blockstack list from a run_function() local variable into a new function call linked list in the globals() block, which I kind of need anyway to show the function call stack for debugging purposes. I still have pl and blk cacheing data out of the new struct sh_fcall (largely because I don't want to change everything to TT.ff->blk and TT.ff->pl yet which makes me have to re-wordwrap a bunch of lines), and pplist is still a local because a function call in the middle of a pipeline has to run in a subprocess for the same reason loops do (which boils down to "the halting problem"; there's no guarantee any loop will actually terminate but piping the output to something that consumes finite input and then closes the pipe should usually terminate the earlier process, so they MUST go in parallel to not hang). That means each pipeline stays within the same function context, with a short lifetime appropriate for a local variable.

But if the function call stack is a linked list in globals, then calling a function is logically a builtin or "break" style inline that adds a new entry onto the function list and updates the two local cache pointers. (Flushing the old ones into the old struct because it has to know what pl position to return to when this function ends, and this function has a new if/else/while block stack.)

I suspect all the local variable cached entries should just move into TT.ff and be dereferenced every time they're used, I've already moved a few of them (like the TT.ff->urd pipeline unredirect list for recovering redirections; remember I dup/close file descriptors to high filehandes and then dup/close them back down after the vfork() because nommu support), which means the list can never be empty. (Unlike the blk list, when is checked for emptiness ala !blk in several places.) Right now it run_function() adds a TT.ff entry to the list when it's called, but that's the same "call run_function() recursively to call a shell function" logic I'm trying to avoid here. So I need to split that out into a separate function that's called before run_function(), and then rename run_function() to something else. (My sleep deprivation suggests repeat_until_spanked() which is a reference to Matt Groening's "life in hell" comic from before he started The Simpsons. It's probably run_lines() to go with parse_line().)

The difference between the new struct sh_fcall and the old struct sh_function is that the first is runtime (argv[] and such the shell function was called with) and the second is parse time (list of commands in pipelines and blocks). Possibly the new one should be sh_function and the old one sh_parse (or some such) but renaming a bunch of things at once is hard to keep track of. (My problem here is this change is naturally very big, and doing it in stages is tricksy.) So sh_fcall is the runtime function call stack, and sh_function is a parsed block of input data with a lifetime, which again gets strange when "if true; then blah() { echo hello;}; fi" starts with the if, but the if has already run and you have a pointer to the echo at the start of blah and the whole parsed block has to stick around until that function gets undefined. The fact function definitions can live in other function definitions... As I said, reference counting.


January 11, 2021

The GOP can go the way of the Whigs and Federalists before it. In reality, it's going the way of the confederacy. Here's a thread on how white supremacy defends itself by lynching white people who step out of line.

The party has switched all its efforts to defending itself. The I was only following orders defense from the Neuremberg trials breaks down when you make the laws, and keep doing the behavior that got you in trouble. Numerous GOP lawmakers were directing the coup.


January 10, 2021

I'm trying to write a regression test for the behavior difference between

function() { stuff; }

and

function() ( stuff; )

And although the PID constantly varies I went "I'll just curly bracket collate it and pipe the result to sort -u | wc -l and expect a 1 or a 2 to distinguish the behavior" and then bash does:

$ { echo $$; chicken() { echo $BASHPID;}; chicken;}
10868
10868
$ { echo $$; chicken() { echo $BASHPID;}; chicken;} | cat
10868
10928

Why? Ah! If that first $$ is $BASHPID then they match, the pipeline is doing a subshell for each segment and $$ is the root shell. The important part is that all the elements of the outer { } are executing in the same process.


January 9, 2021

I'm hoping that Boomer pathologically abusive misogynistic racism is coming to a head and the fever's breaking, but there's so much clean up to do. The Boomers' cultural history of racism and domestic abuse isn't exactly new, but it is ongoing. And their whole society is bent to protect their racism and sexism: a man who drove his car into BLM protestors pled guilty and is not going to prison, will in fact have the incident erased from his record in 3 years, because he's a white male.

As always, follow the money, the insurgents are useful idiots for billionaires. Let's explain how stupid these clowns are: one of the guys photographed on the floor of congress during the riot, in full tactical gear, talking to a guy in a maga hat, holding plastic flex cuffs (often misidentified as zip-ties but these were disposable handcuffs), who made a bee-line for Nancy Pelosi's office as soon as he got in the building, now claims he found the flex cuffs on the floor and was just holding them, was wearing the tactical gear to protect himself from Antifa and BLM, and thought he was allowed in the building.

Don't let escalation distract you from what they've already done. One purpose the terrorist riot at the hill served was to distract from the georgia call, which wasn't even the only call. (Of course not merely distract, just like domestic abusers escalate from passive aggressive insults to shouting to hitting they double down until you bust out, and are backed by billionaires...) And yes, the invasion was organized and carried out with the full unwavering support of their party, it was entirely predictable and was racist on every level.

Their attempts to rehabilitate hitler continue: apparently nazis haven't had a bad enough reputation? (And yes, these clowns are full nazi, with zero loyalty even to each other. They're throwing each other under every bus.

And now that this iteration of coup has failed (they're trying again this weekend) they're trying to laugh it off, which I fully expect the Boomercrats to fall for.


January 8, 2021

There is good news today. And people doing excellent forensic work. (We still need to defund the police.)

Trying to focus on toysh stuff despite everything. Not doing a great job. Over in bash, pipelines are running just about everything in subprocesses:

$ chicken() { echo $$ $BASHPID; }; echo $$ $BASHPID>&2  | chicken
5109 5165
5109 5166

Note how neither is under the $$ parent PID. I'm not currently doing this, but I suspect I have to if things like:

$ while X=$(($X+1)); do echo $X; done | \
> while read i; do echo $i; done | head -n 5
1
2
3
4
5

Are ever going to work properly. Otherwise, the first while loop never exits so it doesn't move on to the second while loop (which also never exits) so it can't feed data into head. They pretty much have to be separate processes (or something truly horrible with select: no).


January 7, 2021

Of course the GOP can spend years investigating benghazi and and immediately excuse the capitol invasion. They were never about truth, or law, or rights. They're about naked power over everyone else, and nothing else. And they're getting worse, not just because of the "southern strategy" but because gerrymandering causes radicalization. People in those "safe seats" only have to worry about being primaried by a more extreme loon, not about winning the general, so the candidates get ever more extreme (and detached from reality).

Meanwhile, defund the police and a fine is a price.


January 6, 2021

Hands up everybody who's surprised by the coup. Didn't think so. Yeah, it's an even numbered day, I didn't get a lot of programming done.

After losing the senate last night, they're panicing. Thanks to the rules changes they made to fillibuster-proof judges and cabinet nominees so a simple majority can push through any nominee, EVERYTHING is going to be investigated and prosecuted now. They can't survive that. If Biden doesn't pardon them, half the GOP senators are going to wind up in jail.

The literally nazi terrorist mob in Washington DC today isn't the only attack on democracy the GOP is currently performing. (People wonder why I'm not surprised. I'm hoping that the timeline gives us long enough for the Boomers to die.) And of course the police have waffled between useless and actively collaborating, despite people pointing out their much larger racist crackdowns on non-nazis. (Plus how surprised were the capitol police supposed to be when the other side was selling shirts about it with the date on it? Are they now going to ignore the footage?)

I still expect Biden to pardon them all if the lame duck doesn't first. As hilarious a pick Merrick Garland is as attourney general (you wouldn't put this center-right Rockefeller republican on the supreme court? How do you like him NOW!), he's also a terrible choice for AG for significant reasons. Boomers just want things to be quiet for their remaining decade, they don't care who dies in service of Boomer comfort.

Meanwhile, there's still a pandemic. Austin is once again threatening to turn the convention center into overflow hospital beds which doesn't help because the limiting factor is staff (each nurse can supervise at most 2 ventilated covid patients, it's worse in that regard than many other diseases) and we're burning through staff darn fast.


January 5, 2021

Of course they're still lying. They always do. Republicans (and Tories) are fractally evil, example du jour: they prevented regulation of dietary supplements by the FDA (and oppose food labeling in general) so of course dietary supplements have become a major cause of liver failure, even in otherwise healthy people. (Which the pandemic is leaving in short supply.)

The intersection of "do unto others" and "judge not lest ye be judged" is "turnabout is fair play".


January 4, 2021

Monday! Start of a new year, end of the holiday time off. Time to start shouldering the $DAYJOB work again.

The price of batteries went down 89% over the past 10 years, from $1110/kwh to $137/kwh. (Except 137/1110 is 12.33? 100-12.33, or 87.66876 percent which rounds up to 88, not 89?)

Either way, that's almost exactly 3 doublings: 100%/2 = 50%, half of that is 25%, half of that is 12.5%. For a doubling time of 3 years and 4 months. Which means if it keeps going by mid-2024 we can expect batteries under $70/kwh and at the start of 2028 under $35/kwh. (And of course the analysts in that article are expecting it to go down 1/3 of 89% over the next 3 years, I.E. about 30%. That's... not how math works. Seriously, you covered Moore's Law for 30 years and don't understand exponential curves?) And then the analyst talking about how it would take over a decade to replace all the cars on the road, when:

  • An on-demand service needs 1/10 as many cars to handle all riders because the vehicles aren't sitting idle 95% of the time, and yes that covers rush hour because the same vehicle can make 8 half-hour trips between 6am and 10am.

  • You only need to replace 20% of the oil demand before the mining, refining, and distribution network becomes unprofitable and the whole thing implodes, as demonstrated by the 50% price drop circa 2015 or oil prices literally going negative during the pandemic. Bloomberg did a good video about this at the start of 2016, right after said 50% price drop.

The main reason I haven't put solar panels all over the roof of my house yet is I want about 3 days of battery storage, and while I can afford the panels (and the installation), I can't afford as much battery storage as I want yet. (Sending power from my house back to the grid isn't really something the grid _wants_. Much better to be self-sufficient.)


January 3, 2021

While we're all waiting for Biden to pardon Nixon again (the entire purpose of the DNC at this point is to block AOC), here's a Lovely thread about how most of the online ad industry is demonstrably a big scam that does nothing for the people paying money into it, and how ad buyers are improving their metrics to actually notice.


January 2, 2021

I need to make changes to the existing toysh code in stages, and figuring out a functional and coherent trail of breadcrumbs is tough. The data structures are a house of cards, I move one thing everything wants to switch over to an obvious new organization, but redoing the code to USE that is a giant tangled flag day change that's hard to debug. And I am not at my best right now.

Hmmm...


January 1, 2021

I kind of want to start the new year by NOT talking about bad things on odd numbered days, even though late stage capitalism has not let up. (Twitter has now locked my account 13 times for expressing the obvious sentiment resulting from this.)

That said, there is good news. The Boomers get older and more infirm every day and have to give way eventually. Here's an explanatory thread on the structural problems in the DNC that lead to gerontocracy over there, and here's Cory Doctorow recommending another excellent explanatory thread on where money comes from these days. (Reminder, twitter sucks at being twitter and threads randomly end abruptly with a tiny "show this thread" link you have to click to see the rest of the thread. That's why their authors often copy threads they wrote into blog entries which read awkwardly because of the original tweet length constraints they were composed within.)

Ok, I'm up to four shell contexts:

  • sh_process - list of currently running child processes, with PID and command line and exit status and so on.

  • sh_parse_context - my old sh_function struct renamed and extended, contains the information for each "source" level (pipeline list, lineno, array of function definitions).

    Possibly the $(subshell) stuff should be treated as functions so it can handle case/esac embedded in there (rather than just counting parentheses), but I dunno how to represent that yet.

  • sh_function_name - the directory of callable functions (which is not the same as _parsed_ functions because you can have function definitions and "unset -f" in a for loop; this means the sh_parse_context needs reference counting so we know when to free it).

  • sh_function_call - the runtime information for function calls (which are _not_ child processes), including their command line arguments (which can be reset by 'set') and local variables.

Switching to this requires rather a lot of reshuffling. I've come up with a set of structure definitions in GLOBALS() that I'm reasonably happy with for the moment, but changing all the code to USE them is a big deal and probably has to be done in stages. Global vars are just the top level of local vars, so the shell has to start with an "empty" function call.

The lifetime for sh_parse_context is just outright FIDDLY (see "reference counting", above): the common case is "you're typing at a command prompt" and commands are executed and freed right after, which means parsing shell scripts should work that way too: it remembers stuff it needs to and frees it as soon as it can.


Back to 2020