Skip to content

Instantly share code, notes, and snippets.

@creachadair
creachadair / socket-api.md
Last active July 27, 2026 03:07
Socket API

BSD (POSIX) Socket API Flow

Edges in this graph indicate order dependencies. Broadly, you may only legally use an operation if you have performed all the operations on some path to it, starting from "ø", the entry point. Error paths are not illustrated. Once created, a socket can be close'd at any time.

"Legally" here is intentionally somewhat imprecise. For example, most implementations will not report an error if you call recvmsg on a socket that has no address bound to it; however, no message will ever become available, and if non-blocking, the call will time out.

graph TD
  O(("ø")) --> S
 S --> GSO[getsockopt]
@creachadair
creachadair / update-go-tool.sh
Created July 25, 2026 20:56
A shell function to update an installed Go binary
#!/usr/bin/env bash
# This takes advantage of the fact that "go version -m" writes out
# build metadata from a Go binary. We use this to extract the import
# path of the program, as well as any build tags it was built with.
# The latter we want so that when we update, we will get the same
# build tags.
#
# Note, however, that this will not work for cross-compiled programs.
# You could also extract GOOS and GOARCH and set those, but this script
@creachadair
creachadair / rsync-pitfall.md
Last active June 25, 2026 15:59
A Curious Permission Preservation Pitfall in rsync

A Curious Permission Preservation Pitfall in rsync

When using rsync to back up or archive data, you typically want to preserve file metadata such as owner and group ID, permissions, and modification times, in addition to the file content. You might run with --archive (-a) or using the --times (-t), --perms (-P), --owner (-o) and --group (-g) flags, for example.

In particular, preserving permissions naturally means that if a file is read-only in the source (e.g., mode 0444 or -r--r--r--), then its mirror in the destination will also be read-only. This is working as intended, and does not ordinarily cause any problems because (by default) when rsync updates file contents, it does so by creating a (writable) temp file with the new content, then replacing the target file (and updating the file metadata) once it is complete.

The --inplace flag overrides the default behaviour, causing rsync to update existing target files directly rather than via a temporary. This can be useful when dea

@creachadair
creachadair / app-installation.md
Created June 3, 2025 16:28
Finding the installation ID of a GitHub app installation

Find the Installation ID of a GitHub App Installation

  • Go to the org settings.
  • Select GitHub Apps.
  • Find the app and select its "Configure".
  • In the title choose "App settings".
  • Open the tab "Install App".
  • On the installation of interest, select the settings (gear icon).

The installation ID is the trailing number in the resulting URL:

@creachadair
creachadair / compact-func.md
Last active May 21, 2026 22:34
A Go syntax for compact function literals

A Go Syntax for Compact Function Literals

Note

This does not exist, I am sketching out a design idea.

The go keyword accepts a call expression, evaluates all the terms of the expression up to the point of the call itself, then issues the call inside a newly-created goroutine.

By analogy, the call keyword accepts a call expression and generates a function literal that evalutes that expression.

Examples

@creachadair
creachadair / port-mnemonics.md
Created December 3, 2024 22:32
Port numbering mnemonics

Mnemonics for port numbers

Although this convention is quite old, I only learned of it fairly recently. One way to pick a "memorable" port number is to use a telephone-style encoding of the digits to their corresponding letters on a (QWERTY) keyboard. So, just as one might spell 364-9255 as "DOG-WALK", you can do the same trick with the keyboard letters.

In tabular format, that is:

1  2  3  4  5  6  7  8  9  0
Q  W  E  R  T  Y  U  I  O  P
A S D F G H J K L ?
@creachadair
creachadair / reddit-api.md
Created October 22, 2024 22:43
Calling the Reddit API

Calling the Reddit API

Most requests go to https://www.reddit.com[/path], where paths are either /api/... or /r/subreddit/... or similar, depending on the method. API docs give the details.

Many APIs permit unauthenticated access, but Reddit imposes rate limits and—perhaps more annoyingly—blocks various IP ranges (notably a bunch of AWS). Their support does not respond to tickets unless you embarrass them publicly. I lack both the ability and the desire to do that, so I needed another way.

So anyway, the recommended way to talk to the API is using OAuth, which is annoying if all you wanted to do was grab a few stats about your subreddits. Fortunately, they have a lighter-weight auth flow you can use, described in https://github.com/reddit-archive/reddit/wiki/OAuth2#application-only-oauth

In summary:

@creachadair
creachadair / update-aws-cli.sh
Last active March 13, 2026 15:34
Update installed version of the AWS CLI on a Linux system
#!/usr/bin/env bash
#
# Update the installed version of the AWS CLI on Linux.
#
set -euo pipefail
: ${TMPDIR:=/tmp}
tmp="$(mktemp -d $TMPDIR/awscli.XXXXXXXXXX)"
trap "rm -fr -- '$tmp'" EXIT
@creachadair
creachadair / remove-taint.sh
Created September 13, 2024 17:09
Remove quarantine taint from files on macOS
#!/usr/bin/env bash
#
# Usage: remove-taint.sh <filename>
#
# Remove the annoying mark-of-the-web taint xattrs from a file.
# For some reason macOS ignores a removexattr for these attributes,
# but the taint does not survive a pipe copy and rename.
#
set -euo pipefail
@creachadair
creachadair / self-signed-tls.md
Last active November 24, 2024 23:54
Self-signed TLS certificates

Creating Self-Signed TLS Certificates

(see also: https://github.com/creachadair/tlsutil)

A "CA" certificate is basically just a self-signed certificate that someone has blessed. There are a few pedantic details you have to get right in the cert settings if you want a browser to accept it (particularly an older browser), but CLI tools seem to be less picky.