<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title>angora blog</title>
<description>yes</description>
<link>https://www.angora.pet/blog</link>
<copyright>no</copyright>
<item>
<title><![CDATA[`mmap`ing guarded pages]]></title>
<link>https://www.angora.pet/blog/2026-07-24-mmap-guard-pages/index.html</link>
<description><![CDATA[
# `mmap`ing guarded pages

in one of my forths i use a guarded page for the working stack.
this guarantees a segfault if memory on either direct side of the stack
(which is just a single memory page) is accessed.
here's the slightly nifty way in which i did this.

as it is a forth it is written in x64 assembly,
but i will include the C library equivalent as well.

`mov rsi, MEM_SIZE`

`add rsi, PAGE_SIZE * 2`

`MEM_SIZE` is the size of the amount of memory we need.
`mmap` allocates in memory pages, so it should be a multiple of the page size
(on x64 non-big pages can only be 4096 bytes, so luckily you don't have to
do some horrible bullshit to figure out the page size on that platform)

alongside our desired allocation size we need two extra pages,
these will be the Guards and interacting with them will cause a segfault.

we do this maths in `rsi`
to set up for the `mmap` system call's `length` parameter
which is passed through `rsi`.

the rest of the parameters to `mmap` are constants:

`mov r9, 0`

`mov r8, -1`

`r9` and `r8` are the `offset` and `fd` parameters respectively.
for our purposes they are entirely irrelevant
because we are not mapping a file.

`mov r10, 0x22`

this is the `flags` parameter, it must contain one of three values
and can have a few other values orred onto it.
0x22 is `MAP_PRIVATE` (0x02) `| MAP_ANONYMOUS` (0x20).

`MAP_PRIVATE` does basically what it says,
it makes the mapping private to the process.
the alternatives `MAP_SHARED` and `MAP_SHARED_VALIDATE`
seem to only make any sense for mapping files, which we are not doing.

`MAP_ANONYMOUS` indicates that we are not mapping a file
and want a zero initialised page of memory.

`mov rdx, 0`

this sets the `prot` parameter to `PROT_NONE`,
marking the memory area as having no read/write/execute permissions.
accessing the memory at all will cause a segfault.

'but doesn't that include the part we actually want to access too?' yes.
we will fix this afterwards.

`mov rdi, 0`

`mov rax, 9`

`syscall`

`rdi` is the `addr` parameter, which if set to zero, which it is here,
will just use whatever address is available.
you could use this to tell `mmap` where to try to allocate the memory,
if you wanted to.

and in `rax` we put the syscall for `mmap` which is 9, and everything is complete. here's all that in C:

`mmap(0, MEM_SIZE + PAGE_SIZE * 2, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);`

the result of the syscall is returned in `rax`.
it will either be a memory address or a negative number corresponding to
`-errno`. we can filter out a failure with

`test rax, rax`

`jl .fail`

now we have a bit of memory which we cannot access. let's fix that.
the strategy here is to now change thhe permissions of `MEM_SIZE`
leaving a page before and after the allocation unaffected and still inaccessible.

`mov r15, rax`

`add r15, PAGE_SIZE`

we'll keep the start of our block of memory in r15.
it will still be there after the syscall so we can use it for Storing Stuff.

`mov rdx, 3          ; prot`

`mov rsi, MEM_SIZE ; size`

`mov rdi, r15        ; addr`

`mov rax, 10`

`syscall`

10 is the syscall number for `mprotect` which lets us change the permissions
on a block of memory. `rsi` (`size`) and `rdi` (`addr`) dictate, Shockingly,
the size and address of the memory we want to change.

the `prot` value here is `PROT_READ` (0x1) `| PROT_WRITE` (0x2) which sets
read and write permissions on the memory space.

congrations. we now have a block of memory with one page on either side
that will safely(?) segfault when your program Fucks up.

here's that in C. goodbye + sorry about how im bad at writing and explaining things, i hope this helped anyway (`a` is the address here)

`mprotect(a, MEM_SIZE, PROT_READ | PROT_WRITE);`

thank you
]]></description>
<pubDate>2026-07-24</pubDate>
</item>
<item>
<title><![CDATA[guess i'll do it myself then]]></title>
<link>https://www.angora.pet/blog/2026-06-25-guess-ill-do-it-myself/index.html</link>
<description><![CDATA[
# guess i'll do it myself then

pro tip: you cannot find good sources of technical information online.
every result you will find is some combination of:

- stinky sloppa
- unrelated to the issue
- incorrect
- incomprehensible

i was lamenting this state of affairs yesterday
when i came to the Realisation that:
_"You can in fact Do things"_

so maybe i'll write some stinky little articles about Things sometimes
in the hopes that someone will find them
and get the information they actually need.
unless i can't be ever bothered or i forget to.
which is very possible.

ok good bye
]]></description>
<pubDate>2026-06-25</pubDate>
</item>
<item>
<title><![CDATA[old computer challenge 4: day 9]]></title>
<link>https://www.angora.pet/blog/2024-07-21-occ4-day9/index.html</link>
<description><![CDATA[
# old computer challenge 4: day 9

the challenge has been over for almost a day now.
i was thrown off in quite a few places going back to my regular
setup. i grew used to `rio`, and `plan9port`'s `rio` is

1. janky
2. laggy
3. lacking window swallowing

i really like automatic window swallowing.
i'm working on getting it set up.
my main laptop lacks any physical buttons,
which is throwing me off.
i am again considering getting a thinkpad X200 or something.

the plumber is fucked if you need to plumb a file name
with spaces in it. i do not feel like putting in the
annoying amount of effort to fix it.

plan9port, like 9front, does not have any support for
fallback fonts. maybe there's a program or something that
merges font files together, because that's basically the
one thing that is stopping me from mostly switching from
`vi` to `sam`.

i like `sam`. i'm writing this in plan9port's `sam` right now.
i would try out `acme` but i would like to
get the p9p plumber configured first, which may be a challenge
because i have a shit load of files with spaces in the name.
also mouse chording was a shit idea and you can't do them at all
on a touchpad without physical buttons.
]]></description>
<pubDate>2024-07-21</pubDate>
</item>
<item>
<title><![CDATA[old computer challenge 4: day 8]]></title>
<link>https://www.angora.pet/blog/2024-07-20-occ4-day8/index.html</link>
<description><![CDATA[
# old computer challenge 4: day 8

this is the last day. i've been looking at
writing 9p filesystems, but i barely get around
to writing C code in general and i have never,
for some reason, been able to grasp how to best
read data from a file into a buffer. i think
i overthink everything too much and then
never actually implement anything.

i thought i had mentioned this before, but
apparently i hadn't, but i was able to watch
some videos via `treason`. before, when opening
a file, the audio and video would be immediately
out of sync. turns out i just had to pause and then
play, and it worked fine. (except for sometimes,
probably because of network issues because the video is
over sshfs, the player would freeze)

i haven't figured out how to make the plumber deal
well with files with spaces in the name. adding
a space into the regex rule for file names seems
to tokenise the whitespace as separate `rc` arguments.

will probably try doing occ again next year.
it was fun.
maybe i'll try freeDOS, or duskOS.

i've been thinking of getting a thinkpad x200 or something.
my dell inspiron is quite bulky and hard to carry around.
x200s seem to be well supported all around, which is nice too.
may even try using it to replace my main laptop, as my main laptop
is falling the fuck apart. the main charging port no longer works,
only USB-C. the headphone jack is broken, so I need to use bluetooth
audio. that laptop is from 2021. this 2006 dell laptop is in better
shape.

`sam` is a nice editor, even though i never actually read the tutorial
to learn the command syntax. oops

i think i'll be using 9front more, going forward.
maybe setting this laptop up as a cpu/auth server?

`git9` is ok. `git/walk` seems to only work from
the repository root, though, because otherwise
it can't find the `.git/fs`.

i never got around to writing more of `uxn9`
because i got `npe`'s SDL working. or porting
sfeed, which i also wanted to do.

there are still a few hours left until the challenge
is over though so maybe i could try it tonight.
]]></description>
<pubDate>2024-07-20</pubDate>
</item>
<item>
<title><![CDATA[old computer challenge 4: day 6]]></title>
<link>https://www.angora.pet/blog/2024-07-18-occ4-day6/index.html</link>
<description><![CDATA[
# old computer challenge 4: day 6

i think after this challenge is over i'm going to be using
plan9port a lot more. i may replace my sh-based plumbing script
with the plan 9 plumber.

i would also like to somehow port webfs to plan9port.
i don't know how hard that would be.
]]></description>
<pubDate>2024-07-18</pubDate>
</item>
<item>
<title><![CDATA[old computer challenge 4: day 4]]></title>
<link>https://www.angora.pet/blog/2024-07-16-occ4-day4/index.html</link>
<description><![CDATA[
# old computer challenge 4: day 4

i finally figured out why the uxn emulator wasn't working.
my vga colour depth was set to 16 instead of 32.
it works now. i wonder if a lot of the programs i couldn't get to run
were because i was using 16bit colour.
]]></description>
<pubDate>2024-07-16</pubDate>
</item>
<item>
<title><![CDATA[old computer challenge 4: day 2]]></title>
<link>https://www.angora.pet/blog/2024-07-14-occ4-day2/index.html</link>
<description><![CDATA[
# old computer challenge 4: day 2

i am writing an uxn implementation for 9front.
preliminarily named `uxn9`

![screenshot of xxiivv uxn docs, man page, many windows](uxn9.jpg)

i have completed a very basic skeleton and i intend
to start implementing the uxn instructions
and then the devices.
]]></description>
<pubDate>2024-07-14</pubDate>
</item>
<item>
<title><![CDATA[old computer challenge 4: day 1]]></title>
<link>https://www.angora.pet/blog/2024-07-14-occ4-day1/index.html</link>
<description><![CDATA[
# old computer challenge 4: day 1

it's currently 00:20 on day 2 so this post is dated as such.
i didn't write anything on day 1 proper
but i did make significant progress and continue
setting everything up.

about 5 minutes ago i finally figured out
why the system time wasn't correct:
by default `/rc/bin/termrc` calls the
`aux/timesync` command with arguments
that treat the system clock as local time
instead of UTC.

i have practically ruled out video viewing,
some videos crash `treason` outright and the ones that don't
are so slow that the video lags significantly behind
the audio. i think this laptop is too slow for that.
audio actually works pretty well, even opus when
everything is patched.

i also installed the rio theme patch.
i'm not sure why it isn't merged into 9front.
but regardless it's useful and it works.

i might try installing uxn again on day 2.
`uxnemu` would not run last time i tried it.
maybe on this install it will magically work
for some reason

edit: it does not

![uxnemu says 'no' with regard to running](uxnbroke.jpg)
]]></description>
<pubDate>2024-07-14</pubDate>
</item>
<item>
<title><![CDATA[old computer challenge 4: day 0]]></title>
<link>https://www.angora.pet/blog/2024-07-12-occ4-day0/index.html</link>
<description><![CDATA[
# old computer challenge 4: day 0

## occ4 index
if i actually end up writing anything during the challenge i will
link it below.

* **day 0** (you are here)
* [day 1](../2024-07-14-occ4-day1/)
* [day 2](../2024-07-14-occ4-day2/)
* [day 4](../2024-07-16-occ4-day4/)
* [day 6](../2024-07-18-occ4-day6/)
* [day 8](../2024-07-20-occ4-day8/)
* [day 9 (aftermath)](../2024-07-21-occ4-day9/)

## what i am doing

well, i guess i'm doing [occ4](https://occ.deadnet.se/).
after much deliberation i have decided to make my life as hard as possible
by spending the week on [9front](http://www.9front.org/).
i spent the last few days figuring out how to get 9front working well
(with wireless networking) on my dell inspiron 6400
(1gb ram, from 2005 i think?).
also i guess i will be `ssh`ing into my home server.

here are some possible issues:
* nobody has bothered to port `sfeed` to 9front.
* i can't get `uxn` to run without crashing.
* i have not figured out how to change the timezone from GMT.
* a lot of the videos on my home server do not work with `treason`.
* i have no clue if i can get my wacom tablet to work.

## oh no
i had to recompile the kernel for wireless drivers to work.

![a screenshot of my desktop](window.jpg)

note the battery percentage of 156% when it is full,
and the time zone which is
wrong. i can not figure out how to change it.
copying the correct timezone to `/adm/timezone/local` seems to
have no effect. problem with the timezone file?

`ssh`ing for git only *occasionally* works.
usually it just refuses to connect.
]]></description>
<pubDate>2024-07-12</pubDate>
</item>
<item>
<title><![CDATA[sticky tiling windows in bspwm]]></title>
<link>https://www.angora.pet/blog/2023-10-03-sticky-tiling-windows-in-bspwm/index.html</link>
<description><![CDATA[
# sticky tiling windows in bspwm

`bspwm` has a useful `sticky` flag, which keeps the window on whatever the focused desktop
is, basically like using `node -d` whenever you change desktops.
for floating windows this works very well, but the situation is more complicated if
you set the `sticky` flag for a tiled window.

It works, of course, but since the sticky window is moved away from a desktop when it
stops being focused, it loses its location in the desktop's layout,
and switching back to that desktop places the sticky tiled window in the location any
window would be. This is not ideal if you don't want to constantly reconfigure your
layout after switching to a browser or something similar.

There's actually a draft pull request from 2019 on `bspwm`'s Github that addresses this,
[#1032](https://github.com/baskerville/bspwm/pull/1032), but patching bspwm to solve this
problem is quite bothersome if you use a binary package. Plus, `bspwm`'s great advantage
is how extensible and scriptable it is; there must be a way to solve this problem that way!

There absolutely is, but it took a while for me to figure it out. I spent a few hours on this,
getting it to *almost* work, but be flawed in a way that made it not worth using.
But I finally got it working after [emanuele6](https://github.com/emanuele6) helped me
on IRC (thanks!), and now I use it. So, here it is, `bsp_movedesk`:

    #!/bin/sh
    # deal with sticky windows when moving workspaces.
    test -z "$1" && exit

    # path format: desktop/stickywindow: parent
    bspc query -N -n '.local.leaf.!hidden.sticky' | while read -r wid; do
    	[ "$(bsp_countwindows)" = 1 ] && break
    	dir="$HOME/run/bspsticky/$(bspc query -D -d focused)"
    	mkdir -p "$dir"
    	bspc node "$wid" -i
    	bspc query -N "$wid" -n '@brother.leaf.!window' > "${dir}/${wid}"
    done

    bspc desktop -f "$1"

    bspc query -N -n '.local.leaf.!hidden.sticky' | while read -r wid; do
    	dir="$HOME/run/bspsticky/$(bspc query -D -d focused)"
    	[ "$(bsp_countwindows)" = 1 ] && break
    	stdir="${dir}/${wid}"
    	if [ -s "$stdir" ]; then
    		rece="$(cat "$stdir")"
    		bspc node "$wid" -n "$rece"
    		rm "$stdir"
    	fi
    done

    # remove hidden window's receptacles. sucks but better than the alternative
    while bspc node 'any.local.leaf.!window' -k; do :; done

The script is a wrapper around `desktop -f`, and can be used by replacing instances
of `bspc desktop -f` with `bsp_movedesk` in your `sxhkd` config.

It works by reading and writing to a special directory
(on my machine `$HOME/run/bspsticky`, kept inside a ramdisk),
which contains directories named with a desktop's ID.
These directories contain files named for a sticky node's ID,
and contain the ID of a receptacle which the window should be
moved to if that desktop is focused.
These receptacles are placed before the focused desktop changes if there
are multiple windows open (because doing this when the sticky window
is the only open window is unnecessary.)

This is the `bsp_countwindows` script:

    #!/bin/sh
    bspc query -N -n '.window.!hidden' -d | wc -l

There are definitely improvements that could be made here,
but It Works. the end.

---

here's a completely unrelated script, which swaps a window's parent to its sibling,
in case you want that:

    #!/bin/sh
    # move focused window to sibling
    set -e

    # possibly causes a race condition if focused changes during script?
    focused=$(bspc query -N -n)

    if [ "$1" = "2" ]; then
        bspc node -f @parent/parent/brother
    else
        bspc node -f @parent/brother
    fi
    bspc node -i
    bspc node $focused -n $(bspc query -N -n .local.leaf.!window)
    bspc node $focused -f
]]></description>
<pubDate>2023-10-03</pubDate>
</item>
<item>
<title><![CDATA[computing dystopia: part 1]]></title>
<link>https://www.angora.pet/blog/2023-09-30-computing-dystopia-part-1/index.html</link>
<description><![CDATA[
# computing dystopia: part 1

hi. on my server i run a javascript-based daemon
(its function is irrelevant here).
i also, seperately, run the rss fetcher
[`sfeed_update`](https://codemadness.org/sfeed.html) which i then
transfer to my laptop where i read it.

today i noticed my feeds did not seem to be fetching. weird.
after like a minute of investigation i find that my `/tmp` directory,
kept on an 8GB ramdisk, had run out of space...
but what could be causing it?

so it turned out that my `/tmp` directory was filled with temporary
directories created by the javascript package manager(?) `yarn`,
which would create a new directory every few seconds.

so i find a github issue about this, open since *november 2018*,
which contains no solution other than running a cron job or
changing to `yarn v2`, which my daemon does not seem to support
and distro does not package.

of course, while this massive issue affecting quite a few people
is not worth fixing after five years, it is important to hide
a comment, labelling it 'unprofessional' and 'not worth visibility'
for containing a silly image in it.

writing software in javascript is immoral.
]]></description>
<pubDate>2023-09-30</pubDate>
</item>
</channel>
</rss>
