The first method (using getenv("PATH")
and scanning it....) is preferable and more efficient... This is often what which
usually does (but don't depend on which
whose behavior can vary a lot...) but you won't fork(2) any process (and fork
or system
or which
may fail).
However, I question why you need to find the path of some executable. You could simply use execvp(3) (and similar exec*p*
functions, all of them doing the equivalent of getenv("PATH")
, then scanning it like you would, internally before execve(2)) when executing that program.
(In very pathological cases which you are right to ignore, the getenv("PATH")
could fail)
Notice that the binary executable could be removed (or added, or corrupted...) between the moment when you test its existence (and find it in PATH
) and the moment you are execve(2)-ing it. And that execve
can fail (rarely) for many reasons, or not work as you expect (in particular, if some shared library on which your 7z
executable depends is corrupted or removed).
Don't forget that on Linux, several processes could read and write (or execute) the same file (which could also be removed or renamed while it is read). Please read more about i-nodes.
Hence, finding the full path of 7z
before execvp
-ing it is wrong -or inaccurate: some other program could have removed or reinstalled 7z
after the path check and before its execve(2). I don't understand why you want to scan the PATH
, and I believe it is generally useless, leave that to execvp
See also wordexp(3), glob(3), glob(7)
Since most software on Linux distributions are free software, you can (and perhaps you should) study their source code. For which
it is often a builtin of your shell (and bash
, zsh
, fish
are all free software), or a program from debianutils (perhaps not coreutils), and I am not sure that most distributions have it (and some of them won't install it by default).
PS. My feeling is that your code should not use 7z
which is usually not available on most Linux systems - and not on my systems; you are perhaps implicitly requiring your user to install it (at least document that). You might prefer tar
archives to zip
ones, notice that tar.h is a POSIX header! See this question and consider libtar