219 results for "":

Abstracting away correctness

I’ve been banging the same drum for years: APIs must be carefully designed.

This statement doesn’t resonate the same way with everyone. In order to really understand what I mean by “careful API design”, one has to have experienced both ends of the spectrum.

But there is a silver lining - once you have experienced “good design”, it’s really hard to go back to the other kind. Even after acknowledging that “good design” inevitably comes at a cost, whether it’s cognitive load, compile times, making hiring more challenging, etc.

Thoughts on going down the network stack

So!

I have no shortage of ongoing writing projects - I still need to edit and publish the final parts of making our own executable packer, and I’ve recently announced I was working on a Rust book/series. Those are still both on the table.

Buuut… I’m also looking at other things. My best writing happens when I’m learning about something at the same time I’m writing about it. So for example, the Rust book is a bit harder to write, because I’m mostly trying to distill knowledge I’ve already absorbed (for the most part).

Thumbnail for {{ page.title }}

Day 3 (Advent of Code 2020)

Hello all, and welcome back to Advent of Code 2020, featuring Cool Bear.

Cool bear

Hey y’all!

Let’s get right to it.

The problem statement for Day 3 is as follows: we’re given a map, that looks like this:

..##....... #...#...#.. .#....#..#. ..#.#...#.# .#...##..#. ..#.##..... .#.#.#....# .#........# #.##...#... #...##....# .#..#...#.#

And we imagine that it repeats infinitely to the right, like so:

Thumbnail for {{ page.title }}

Making a dev shell with nix flakes

In the previous chapter, we’ve made a nix “dev shell” that contained the fly.io command-line utility, “flyctl”.

That said, that’s not how I want us to define a dev shell.

Our current solution has issues. I don’t like that it has import <nixpkgs>. Which version of nixpkgs is that? The one you’re on? Who knows what that is.

Also, we haven’t really seen a mechanism to use .nix files from elsewhere.

Thumbnail for {{ page.title }}

Does Dioxus spark joy?

Amos

Note: this article is adapted from a presentation I gave at a Rust Paris Meetup — that’s why it sounds a little different than usual. Enjoy!

Good evening! Tonight, I will attempt to answer the question: Does Dioxus spark joy? Or at the very least, whimsy.

What’s Dioxus, you ask? It is first and foremost a name that is quote: “legally not inspired by any Pokémon”.

Thumbnail for {{ page.title }}

Developing over SSH

With the previous part’s VM still running, let’s try connecting to our machine over SSH.

Network addresses, loopback and IP nets

Normally, to connect to a machine, you’d find its IP address. On Linux, a decade ago, you would’ve used ifconfig. Nowadays you can use ip addr:

The ip addr command output, run in VirtualBox

The loopback interface (lo) is local, so it’s not useful to reach the box from the outside: you can see it can be accessed over IPv4 at address 127.0.0.1 but not just! What we’re reading here is 127.0.0.1/8, which corresponds to the range 127.0.0.1 - 127.255.255.255

Thumbnail for {{ page.title }}

A no_std Rust binary

In Part 11, we spent some time clarifying mechanisms we had previously glossed over: how variables and functions from other ELF objects were accessed at runtime.

We saw that doing so “proper” required the cooperation of the compiler, the assembler, the linker, and the dynamic loader. We also learned that the mechanism for functions was actually quite complicated! And sorta clever!

Thumbnail for {{ page.title }}

Consuming Ethernet frames with the nom crate

Now that we’ve found the best way to find the “default network interface”… what can we do with that interface?

Well, listen for network traffic of course!

use rawsock::open_best_library; use std::time::Instant; fn main() -> Result<(), Error> { let lib = open_best_library()?; let iface_name = format!(r#"\Device\NPF_{}"#, netinfo::default_nic_guid()?); let iface = lib.open_interface(&iface_name)?; println!("Listening for packets..."); // doing some low-cost logging over here let start = Instant::now(); iface.loop_infinite_dyn(&mut |packet| { println!( "{:?} | received {} bytes", start.elapsed(), packet.len() ); })?; Ok(()) }
Thumbnail for {{ page.title }}

Day 13 (Advent of Code 2022)

The day 13 puzzle needs a speech therapist.

Cool bear

???

…because it has an awful lisp!! Ahhhahahahhhh

Cool bear

Are you ok? What is.. what is going on with you?

No but seriously we have what are ostensibly S-expressions, except they use JSON-adjacent notation:

[1,1,3,1,1] [1,1,5,1,1] [[1],[2,3,4]] [[1],4] [9] [[8,7,6]] [[4,4],4,4] [[4,4],4,4,4] [7,7,7,7] [7,7,7] [] [3] [[[]]] [[]] [1,[2,[3,[4,[5,6,7]]]],8,9] [1,[2,[3,[4,[5,6,0]]]],8,9]
Thumbnail for {{ page.title }}

In the bowels of glibc

Good morning, and welcome back to “how many executables can we run with our custom dynamic loader before things get really out of control”.

In Part 13, we “implemented” thread-local storage. I’m using scare quotes because, well, we spent most of the article blabbering about Addressing Memory Through The Ages, And Other Fun Tidbits.

But that was then, and this is now, which is, uh, nine months later. Not only am I wiser and more productive, I’m also finally done updating all the previous thirteen parts of this series to fix some inconsistencies, upgrade crate versions, and redo all the diagrams as SVG.