Iterate a directory - How hard can it be?

For one of my current projects I needed to do the following:

  1. Iterate over all files in a directory, recursively.
  2. Filter for PHP files, only take those into account.
  3. For each of the files, execute a shell command, with the file path as the first argument, get the output of the shell command, and do something with the output.

The choice of language is free, so I was contemplating my options:

Given that I wanted to continue building stuff, I opted for the tried and true C/C++ combo for building my little program. So I started out to write a recursive function that iterates over directories. Ah, see, C++ now has <experimental/filesystem> - how cool is that? Oh, not so cool, seems like libc++ on mac os at least in this version doesn't include the exerpimental features, at least I couldn't make it work out of the box and didn't find any useful solution for it. Ok, then back to C, how was that with opendir() and readdir() and stuff ... ok, need to look it up on Stackoverflow, otherwise I only create a weird bug by forgetting about edgecases.

Nice now I have a function that iterates a directory recursively. Now I need to filter for PHP files in that directory. Ok, so how can I check the file extension in C/C++? I could of course install boost, I'm sure there is a solution for everything in there, but that is so heavyweight, I do it myself. I can use strrchr() and look for a dot (.) and then return a pointer to the next char. Why not. Not so modern, but works, just check again on Stackoveflow, if this is how it's done or if I will invoke some undefined behaviour because I violated the standard which any serious C programmer should know by heart anyway.

After that, I only need to execute a shell command for each file and capture the output. Now I was in really deep waters, most of the stuff I found suggests popen() and friends. Or system(), which is easy enough but doesn't capture the command output. Then popen(), but this C++ solution doesn't capture stderr. That sucks, if something goes wrong. Suggested solution: redirect stderr to stdout. No, that's not what I'm gonna do, because I want the stdout of the command, how should I then find out if it's an error or not? The next suggestion is to do it THE HARD WAY by using fork(). I'm sure this would work, although just from a glance at the long winded piece of code, it looks neither very elegant nor easy do debug when stuff goes wrong, it just looks - hard.

At this point in time I got a bit frustrated with my choice of C/C++ and gave up. I got this far:

Which is OK, but very far from modern C++ how I would like it to have. Maybe I should have installed boost, but I don't like to install one gigantic library for such a tiny problem. Yes, I don't need to use everything from it, but then again ... I want to recursively read a directory, how hard can it be?

In the end I then went back to Rust, installed one library that does exactly one thing: iterate a directory recursively. Even though the API is not perfect (when filtering files by extension, I need to make sure to let directories pass, otherwise it doesn't recurse anymore?), it does what I wanted and feels nice to use. Then I used the excellent Rust std::process::Command API for executing shell commands and everything felt much better.