Does portability worth it?

For a long time, I took for granted that POSIX is super-important since it allows my programs to run on different operating systems and hardware configurations. Probably this article by Drew DeVault summarizes this pro-POSIX point of view perfectly.

https://drewdevault.com/2017/11/13/Portability-matters.html

A week ago, I got reason to question this belief.

Story of readdir(3)

POSIX way

I was reading the documentation for the s6 supervision suite, trying to understand whether I like it more than runit I use right now and found a statement that some particular program does not use dynamic memory with note in fine print that it uses the readdir(3) function, which does use dynamic memory.

https://skarnet.org/software/s6/

http://smarden.org/runit/

I did some quick checks with strace(1) and verified that this is true: readdir(3) function results in brk(2) syscalls. If we look at the function interface, it becomes quite clear that there is no way to implement this interface without dynamic memory and arbitrary limits:

Unfortunately, POSIX provides no better interface. But can we do better if we abandon POSIX and go straight to Linux syscalls.

Screw POSIX, I know better

Linux exposes the content of a directory with getdents64(2) syscall (there are also readdir(2) and getdents(2), but they are strictly worse). This syscall expects the user to provide a buffer and populates it with as many structures, representing entries in the directory that can fit into the provided buffer. That interface allows the user can balance memory usage versus the number of system calls depending on his needs.

For example, ls(1) is very slow in huge directories not because inherit limitations of the kernel, but because readdir(3) uses hard-coded size buffer for getdents(2) calls and can do no better constrained to POSIX interface.

Here is my take on how to design a better interface for enumerating content of directory (full source is not published yet):

With this interface, the user is in charge of memory allocations and file descriptors, so only one function is needed, down from three. I think my interface unequivocally closer to the lodestar of minimalistic C interfaces.

https://nullprogram.com/blog/2018/06/10/

It comes at a price

Sticking to POSIX means your program will run on different software and hardware platforms at the price of sub-optimal interfaces that induce sub-optimal implementation. Does it worth it for you?

Not for me. I have never had access to a real computer (mobile phones do not count) with architecture different from x86 or x86_64, and I have never used any POSIX-compatible operating system for real work other than Linux.

I do not expect this to change soon, and I do not want it to change. While I hate what happens to GNU/Linux ecosystem right now -- systemd, cater-to-idiots philosophy, web interfaces everywhere -- I am satisfied with Linux proper and my x86_64 system.

Proxied content from gemini://tilde.pink/~kaction/log/2021-07-05.1.gmi (external content)

Gemini request details:

Original URL
gemini://tilde.pink/~kaction/log/2021-07-05.1.gmi
Status code
Success
Meta
text/gemini;lang=en
Proxied by
kineto

Be advised that no attempt was made to verify the remote SSL certificate.