用 execl() 替换 system() :我什么时候需要使用 fork()?

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

我正在尝试从我的 C 程序中调用外部程序。我知道调用 system() 是一个坏习惯。我一直在阅读如何使用execl()execv()来替换system(),但由于我的脑容量有限,我想请一些例子和指导。

如果我要去 运行

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

那我应该这样做吗?

    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");
    }

我在 Whosebug 上发现了一个类似的问题,关于用 execl() 替换 system(),但是答案(3 票)没有提到 fork() 如果我正在等待 child 进程完成以便我自己的程序可以继续,我是否需要 fork()

我知道还有 execv() 但我的 limited-capacity 大脑更喜欢 execl() 除非有人告诉我这有缺点。网络上的大多数示例使用 execv 而不是 execl,可能是因为当我搜索 execl 时,Google 一直告诉我有关 MS Excel 函数的信息。


我将描述我的用例,但如果我在其他情况下需要它,我更喜欢对我的问题的一般性回答,而不是针对我的具体情况的回答,例如“你为什么要使用 $PROGRAM1 ?你应该下载$PROGRAM2 代替!"

我正在为我的 child 的 Kubuntu 系统拼凑一个 PyQt 应用程序,以将对某些站点 (youtube) 的 Internet 访问限制为每天特定的小时数。他可以自愿关闭自己的互联网接入,为以后节省上网时间;当他重新打开它时,我的应用程序将根据剩余时间设置 iptables 规则。理想情况下,我会在我的 Python 应用程序中调用“iptables”,但 iptables 需要以 root 身份执行(我不想使用 sudo 获取密码或设置无密码的 sudo 用户帐户),并且 Python 脚本不允许 运行 作为 setuid root。因此,我正在编写一个 C 程序,其唯一功能是 运行 作为 setuid root 并将(已清理)参数传递给 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")

几十年没做过C编程了。关于 execl() 电话的一些 hand-holding 将不胜感激。谢谢。

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

如果没有 fork(),您的程序将在 execl 之后 不会继续 ,因此您将无法“等待”。所以如果你想有一个“child”和一个“parent”过程,你确实需要 fork()。否则它是相同的进程,被新的可执行文件替换。

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

太棒了,所以您不需要 fork() - 您不需要 parent 过程。只需调用 execl 并成为 iptables.