~jscott/which

Include musl libc's implementation of reallocarray() as a subproject

Work smarter, not harder.
Remove the test from the build system also
Delete the dumb test and slightly tweak our copyright/license statements
Remove unnecessary include of <limits.h>

Thanks to deheader for catching this!
Initialize pathname_found.

clang-tidy pointed out that if the addition overflow
checks were to turn out true, the loop could stop and
reading pathname_found would be undefined.
Add an assertion that a loop runs at least once.

This should demonstrate that pathname_found isn't
used uninitialized.
Suppress a couple GCC warnings.
Use open_memstream() to dynamically allocate the path list.

Trying to count the number of paths in the string beforehand
was error-prone, as is trying to reallocate the memory ourselves.
Make the error handling more robust.

In particular, update the value of threads_joined so
we don't accidentally join with the same thread twice.
Use faccessat() to determine executable permissions.

Be portable to POSIX-conforming systems. These changes
too were drawn from the Code Review Stack Exchange.
Fix attempts to join with a thread multiple times.
Stop using thread cancellation.

It was pointed out to me at the Code Review Stack Exchange
at https://codereview.stackexchange.com/q/274956 that
none of the child threads make calls to blocking functions,
so we may as well not use thread cancellation. This simplifies
things substantially.
Add the restrict qualifier to our comparison functions.

Since the pointers point to const-qualified objects,
here the restrict qualifier merely indicates that
the pointed-to objects are not modified.
Don't deadlock waiting for children to finish if there are none.
Suppress Cppcheck warning about our usage of strtok().
Fix the build time XSI check.
Add some tests and assertions to the build system.
Add a missing call to free().

I found this by noticing that a call to free() from
the "goto ladder" wasn't included in our resource cleanup
on success.
Handle pthread_create() returning EAGAIN more gracefully.

Previously, we'd enter a busy loop with calling sched_yield()
and trying to create the thread again. This is suboptimal: a
far cleaner approach which is less likely to cause failed
thread creation attempts is to wait for a thread to terminate.

The best way to do this is with a condition variable which
gets raised when a thread terminates, and so that's what we
do here.
Next