如何在C

时间:2019-05-23 11:34:22

标签: c linux command-line text-editor

我正在用C(Linux环境)开发命令行应用程序,以编辑特定的文件格式。此文件格式是纯XML文件,先压缩后再加密,然后再加密签名。

我想为用户提供一种简便的方法来编辑这种文件,而无需手动提取文件,对其进行编辑,然后对其进行压缩,加密和签名的麻烦。

理想情况下,调用时,我的应用程序应该执行以下操作:

  1. 打开加密/压缩的文件并将其提取到一个临时位置(例如/tmp
  2. 根据所安装的软件以及用户的喜好,调用外部文本编辑器,例如nanosublime-textgedit。等待用户编辑文件并关闭文本编辑器。
  3. 读取修改后的临时文件并加密/压缩,以替换旧的加密/压缩文件

我如何能达到要点。 2?

我考虑过用nano调用system()并等待其返回,或者将inotify()放在临时文件上以了解图形文本编辑器何时对其进行了修改。

哪种解决方案更好? 如何调用用户的默认文本编辑器? 有什么办法可以做得更好吗?

2 个答案:

答案 0 :(得分:1)

首先,考虑不要自己编写一个实际的应用程序或包装,而这会调用另一个编辑器,而是为某些现有编辑器编写某种插件,该插件足够灵活以支持其他格式并通过解压缩传递其输入。

当然,这不是唯一的解决方案,但对您来说可能更容易。

使用您的特定方法,您可以:

  • 使用EDITOR and/or VISUAL command-line variables(也由@KamilCuk指出)来确定要使用的编辑器。
  • 将编辑器作为子进程运行,以便您知道何时结束执行,而不必与之通信。仅仅由于文件编辑器可能对多个文件进行更改,而仅在文件中打开文件时,某些编辑器甚至没有打开文件。 / li>
  • 请记住要处理编辑器出现问题的情况;或悬挂或者您收到通知以停止等待编辑器;或者等

答案 1 :(得分:1)

  

根据所安装的软件以及用户的喜好,调用诸如nano或sublime-text或gedit之类的外部文本编辑器。等待用户编辑文件并关闭文本编辑器。

有趣的问题。使用用户的默认编辑器打开xml文件的一种方法是使用xdg-open,但没有提供应用程序的pid,用户可以在其中编辑文件。

您可以使用xdg-mime query default application/xml来查找默认编辑器的.desktop文件,但是随后您必须解析此文件以找出程序的可执行路径-正是{{3 }},在how xdg-open actually works函数中,仅从Exec=中提取以*.desktop开头的行,以调用编辑器可执行文件并将目标文件作为参数传递...我正在尝试可以这样说,就是在找到编辑器可执行文件后,可以启动它,然后等待其关闭,然后检查文件内容是否已更改。好吧,这看起来像很多不必要的工作...

相反,您可以尝试使用固定的知名编辑器(例如gedit)来实现所需的工作流程。您还可以为用户提供一种方法(即提示或配置文件)来设置默认的xml编辑器,即/usr/bin/sublime_text,然后可以在下次运行时在程序中使用它。

但是,关键是要打开一个编辑器,该编辑器会阻止调用过程,直到用户关闭该编辑器为止。关闭编辑器后,您可以简单地检查文件是否已更改,如果已更改,请执行进一步的操作。

要了解,如果文件内容已被修改,则可以在打开文件之前使用stat系统调用获取文件inode change time,然后比较时间戳记值与当前的一旦关闭。

即:

stat -c %Z filename

输出:1558650334

总结:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void execute_command(char* cmd, char* result) {
  FILE *fp;
  fp = popen(cmd, "r");
  fscanf (fp, "%s" , result);
}

int get_changetime(char* filename) {
  char cmd[4096];
  char output[10];
  sprintf(cmd, "stat -c %%Z %s", filename);
  execute_command(cmd, output);
  return atoi(output);
}

int main() {
  char cmd[4096];
  char* filename = "path/to/xml-file.xml";

  uint ctime = get_changetime(filename);

  sprintf(cmd, "gedit %s", filename);
  execute_command(cmd, NULL);

  if (ctime != get_changetime(filename)) {
      printf("file modified!");
      // do your work here...
  }

  return 0;
}