1

我正在尝试从我的 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");
    }

我在 StackOverflow 上发现了一个关于替换为的类似问题system()execl()但答案(3 票)没有谈论fork(). 如何使用 execl 作为系统的替代品fork()如果我正在等待子进程完成以便我自己的程序可以继续,我 是否需要?

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


我将描述我的用例,但如果我在其他情况下需要它,我会更喜欢我的问题的一般答案,而不是针对我的情况的特定答案,例如“你为什么还要使用 $PROGRAM1 ?你应该下载 $PROGRAM2 !”

我正在为我孩子的 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()。谢谢。

4

1 回答 1

1

如果我正在等待子进程完成,我是否需要 fork() 以便我自己的程序可以继续?

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

因此,我正在编写一个 C 程序,其唯一功能是以 setuid root 身份运行并将(经过清理的)参数传递给 iptables:

很酷,所以你不需要fork()- 你不需要父进程。只需调用execl并成为iptables

于 2020-07-29T11:28:12.067 回答