Glibc hates, 4565-minutes-into-the-workday edition.
No d_namlen on struct dirent. Instead I get to use the more computationally expensive strlen().
No fgetln(), so I have to elaborately read characters into an internal buffer and kiss goodbye to any sort of optimization that stdio can do with it.
regexec() only works on null-terminated strings. Which I don't have if I'm going line-at-a-time grepping against a mmap()ed file. mmap() isn't a perfect solution to the problem of having to repeatedly read a file into memory (on my 512mb MacOS box, mmap()ing a 2.2gb file converts the poor macbook into an electrical anvil that is completely unresponsive to any sort of user input short of a nail through the keyboard) but on small files it's nice to have the vm system do the buffering for me.
It's an added hate that glibc doesn't #define REG_BASIC. FreeBSD has supported this (and being able to regexec() inside arbitrary buffers) for pretty much forever, but no, it's not a fucking standard because goddamn Linux doesn't support it and if Linux doesn't support it it doesn't really count these days.
(To be fair and unbalanced, I'll extend a special agnostic hate towards the rocket scientists who decided that basename(1) should treat filenames beginning with “-” as something special. I love it when “basename $0” returns
basename: -k: unknown option basename: -s: unknown option basename: -h: unknown optioninstead of just returning what $0 was, because it adds an additional layer of excitement to the obviously-not-challenging-enough chore of writing portable shell scripts. It's stunts like this that make me realize why so many people use p*rl.)