Your question seemed to call for a forest answer, and the answers here seem like tree answers, so I thought I'd give you a forest answer.
This is very rarely how C programs are written. It is always how shell scripts are written, and sometimes how Python, perl or Ruby programs are written.
People typically write in C for easy use of system libraries and direct low-level access to OS system calls as well as for speed. And C is a difficult language to write in, so if people don't need those things, then they don't use C. Also C programs are typically expected to only have dependencies on shared libraries and configuration files.
Shelling out to a sub-process isn't particularly fast, and it doesn't require fine-grained and controlled access to low-level system facilities, and it introduces a possibly surprising dependency on an external executable, so it is uncommon to see in C programs.
There are some additional concerns. The security and portability concerns people mention are completely valid. They are equally valid for shell scripts of course, but people are expecting those kinds of issues in shell scripts. But C programs are not typically expected to have this class of security concern, which makes it more dangerous.
But, in my opinion, the biggest concerns have to do with the way popen
will interact with the rest of your program. popen
has to create a child process, read its output and collect its exit status. In the meantime, that process' stderr will be connected to the same stderr as your program, which may cause confusing output, and its stdin will be the same as your program, which might cause other interesting issues. You can solve that by including </dev/null 2>/dev/null
in the string you pass to popen
since it's interpreted by the shell.
And popen
creates a child process. If you do anything with signal handling or forking processes yourself you may end up getting odd SIGCHLD
signals. Your calls to wait
may interact oddly with popen
and possibly create strange race conditions.
The security and portability concerns are there of course. As they are for shell scripts or anything that starts up other executables on the system. And you have to be careful that people using your program aren't able to get shell meta-charcaters into the string you pass into popen
because that string is given directly to sh
with sh -c <string from popen as a single argument>
.
But I do not think they are why it is strange to see a C program using popen
. The reason it is strange is because C is typically a low level language, and popen
is not low level. And because use of popen
places design constraints on your program because it will interact strangely with your program's standard input and output and make it a pain to do your own process management or signal handling. And because C programs are not typically expected to have dependencies on external executables.
udevadm
executable in the same directory as your program and use it to escalate privileges? I don't know much about unix security, but will your program be run withsetuid root
?PATH
, then no - it would have to be run with./udevadm
. IIRC Windows would run same-directory executables, though.