Posts tagged: Alpine

What is BusyBox?

Two ducks swim through a narrow stream partly hidden by tall reeds and yellow autumn leaves
before you even know, this moment will be a memory

I've often stumbled upon BusyBox, but only after noticing Alpine, by default, has wget installed did I start to investigate where it comes from. Except the wget version was "BusyBox Wget".

But what's that?

docker run --rm -it alpine sh
/ # which wget
/usr/bin/wget
/ # ls -lah /usr/bin/wget
lrwxrwxrwx    1 root     root          12 Apr 15 04:51 /usr/bin/wget -> /bin/busybox

After running ls -la /usr/bin, my mind was blown: nearly 130+ executables are from a single binary!

That explains the name "multicall binary". But... how? How does BusyBox work?

How does a single binary know which executable to run? Well, I guessed it right:

applet_name = argv[0];
if (applet_name[0] == '-')
  applet_name++;
applet_name = bb_basename(applet_name);

So, an explicit invocation would also work:

/ # busybox ls -1
bin
dev
etc
home

/ # busybox meheh
meheh: applet not found

So, to run wget, we find it by name and run it:

int applet = find_applet_by_name(name);
// ...
run_applet_no_and_exit(applet, name, argv);
// ...
xfunc_error_retval = applet_main[applet_no](argc, argv);

Each applet has its own C file, wget being wget.c. Each applet also appears to have some sort of "config" defined in code comments:

//config:config WGET
//config:	bool "wget (41 kb)"
//config:	default y
//config:	help
//config:	wget is a utility for non-interactive download of files from HTTP
//config:	and FTP servers.
//applet:IF_WGET(APPLET(wget, BB_DIR_USR_BIN, BB_SUID_DROP))
//kbuild:lib-$(CONFIG_WGET) += wget.o

And eventually, we invoke the wget main:

int wget_main(int argc UNUSED_PARAM, char **argv)

Other interesting bits: BusyBox also supports hard links.

busybox --install -s

-s creates symlinks.

You can also list what commands it has compiled in:

/ # busybox --list | wc -l
304

So, Alpine is more like an interface to BusyBox-based binaries. Each binary seems to be a bit stripped-down version of the actual full-blown one. I'd still be interested to know if these are reimplementations or just the original source code of the utility shrunk down.