我有一些设备有一个sysfs驱动程序。在做任何其他事情之前,我需要通过将文件的内容" configs.txt",写入子系统的sysfs目录中的文件来配置设备。这可以通过
成功完成popen()
如果在终端中输入此命令,则打印下一个shell提示大约需要5秒钟。我认为这意味着无论sysfs驱动程序正在做什么,大约需要5秒钟才能完成。
但是,如果我尝试使用int main(void){
FILE *file;
char terminal[512];
if(!(file=popen("cat /home/configuration/configs.txt > /sys/bus/iio/devices/device3/config", "r"))){return -1;}
while(fgets(terminal,sizeof(terminal),file)!=NULL){
printf("%s\n",terminal);
}
pclose(file);
printf("Done\n");
}
,如下所示:
popen()
然后程序立即打印"完成"并退出。我希望它等到配置完成后,相对于从交互式shell执行相同命令的快速程序终止似乎表明它没有这样做。
我猜cat
认为popen()
命令的完成是进程的结束,因此结束了Text
并继续前进。它没有考虑sysfs驱动程序正在做什么,并且不会等待它。
我的想法是,它可能会在第二个子进程中分离出来,但是我不知道如何验证这一点,或者如何让我的程序等待第二个子进程完成在继续之前。
我如何监控并等待该程序结束?
答案 0 :(得分:1)
使用pclose()
使用popen()
打开的管道应使用pclose()
关闭。它还会阻止执行,直到子进程完成:
pclose()函数等待关联的进程 终止并返回由返回的命令的退出状态 wait4(2)。
但它没用,因为没有任何东西会通过那个管道回来。
这样会更好 使用system()
它启动你的进程并等待它完成,所有这些都在一个函数调用中。问题是,当出现错误时,您的程序无法分辨出错误。你得到一个退出状态,但它没有告诉你,例如缺少源文件或目标文件。
最好的方法是
自己动手
您可以自己打开config.txt
和sysfs中的文件,然后复制内容。之后一定要关闭它们,并检查每一步的返回值,这样你就会知道什么时候出错了。
答案 1 :(得分:0)
我猜
popen()
认为cat
命令已完成 作为过程的结束,因此结束popen()
并继续前进。 它不考虑sysfs驱动程序正在做的任何事情 这个,并没有等待它。
shell 认为cat
命令的完成是进程的结束。你的司机显然会导致这需要几秒钟。
您的程序会监视执行命令的进程中的管道。当该管道的写入结束时,这很自然地表明已达到popen()
ed文件的结尾。 fgets()
将返回NULL
作为回应,打破循环。因为您的命令会将其标准输出重定向到文件,所以会立即发生。
我的想法是,它可能会脱离第二个孩子的过程 要做到这一点,但我不知道如何验证这一点,或如何使我的 程序等待第二个子进程完成之前 仍在进行中。
popen()
启动子进程。插入另外一个是愚蠢的,无论如何,这样做不会解决你的方法中的根本问题。
您最简单的方法可能是使用system()
而不是popen()
。与shell一样,system()
将等待传递给它的命令的完成,而不是监视它的输出。无论如何都没有预期的输出(见上文),所以popen()
毫无意义。
另一方面,既然你不想做任何事情,只要等到工作完成,为什么不直接做呢?让你的程序打开这两个文件,将一个文件的内容复制到另一个文件中,然后关闭它们。或者考虑让程序在内部生成配置数据,而不是从单独的文件中读取它。
我如何监控并等待该程序结束?
system()
命令将为您执行此操作。如果您fork()
有一个子进程来完成工作,那么您可以通过wait()
或waitpid()
等待其完成。如果您直接写入目标sysfs文件,那么在成功关闭该文件后,您的程序将具有cat
可以提供的已完成配置的保证。