Search code examples
cforksystem-callsexecl

replacing system() with execl() : when do I need to use fork()?


I am trying to call an external program from within my C program. I understand that calling system() is a bad habit. I've been reading up on how to use execl() or execv() to replace system(), but due to my limited brain capacity, I would like to ask for some examples and guidance.

If I was going to run

    int return_val = system("/usr/bin/someprogram arg1 arg2 arg3");

then is this what I should do instead?

    if ((pid = `fork()`) == -1)
       perror("fork error");
    else if (pid == 0) {
       execl("/usr/bin/someprogram",  "arg1", "arg2", "arg3", NULL);
       perror("Return not expected: execl error");
    }

I found a similar question on StackOverflow about replacing system() with execl(), but the answer (3 votes) did not talk about fork(). How to use execl as replacement for system Do I need fork() if I am waiting for the child process to finish so my own program can continue?

I know there is also execv() but my limited-capacity brain would prefer execl() unless someone tells me there is a disadvantage to that. Most examples on the web use execv instead of execl, probably because when I search for execl, Google keeps telling me about MS Excel functions.


I'll describe my use case but, in case I need it for other circumstances, would prefer general answers to my question over answers specific to my circumstances like, "Why are you even using $PROGRAM1 ? You should download $PROGRAM2 instead!"

I'm cobbling together a PyQt application for my child's Kubuntu system to limit Internet access to certain sites (youtube) to a certain number of hours per day. He can voluntarily turn off his own Internet access to save up access time for later; and when he turns it back on, my app will set the iptables rules according to how much time is left. Ideally I'd call "iptables" from within my Python app, but iptables needs to be executed as root (I don't want to sudo for a password or set up a passwordless sudo user account), and Python scripts aren't allowed to run as setuid root. Hence I'm writing a C program whose sole function is to run as setuid root and pass (sanitized) parameters to iptables:

    int return_val = system("iptables -A Parental_Timeblock -m time --weekdays Su,Mo,Tu,We,Th,Fr,Sa --timestart <sanitized argv params> --timestop <more sanitized argv params> -j DROP")

Haven't done C programming for decades. Would appreciate some hand-holding regarding the execl() calls. Thanks.


Solution

  • Do I need fork() if I am waiting for the child process to finish so my own program can continue?

    Without fork() your program will, like, not continue after execl, so you wouldn't be able to "wait". So you do need fork() if you want to have a "child" and a "parent" process. Otherwise it's the same process, that is replaced by a new executable.

    Hence I'm writing a C program whose sole function is to run as setuid root and pass (sanitized) parameters to iptables:

    Cool, so you do not need fork() - you do not need a parent process. Just call execl and become iptables.