Как взаимодействовать с внешним текстовым редактором на С - PullRequest
1 голос
/ 23 мая 2019

Я занимаюсь разработкой приложения для командной строки в C (среда linux) для редактирования определенного формата файла. Этот формат файла представляет собой простой XML-файл, который сжимается, затем шифруется, а затем криптографически подписывается.

Я бы хотел предложить пользователю возможность редактировать этот тип файла простым способом, без необходимости ручного извлечения файла, его редактирования, а затем сжатия, шифрования и подписывания.

В идеале при вызове мое приложение должно делать следующее:

  1. Откройте зашифрованный / сжатый файл и извлеките его во временную папку (например, /tmp)
  2. Вызовите внешний текстовый редактор, например nano или sublime-text или gedit, в зависимости от того, какой установлен, и, возможно, от пользовательских настроек. Подождите, пока пользователь не отредактирует файл и не закроет текстовый редактор.
  3. Считать измененный временный файл и зашифровать / сжать его, заменив старый зашифрованный / сжатый файл

Как я могу достичь точки №. 2

Я думал о вызове nano с system() и ожидании его возврата или о размещении inotify() во временном файле, чтобы узнать, когда он изменяется графическим текстовым редактором.

Какое решение лучше? Как я могу вызвать текстовый редактор пользователя по умолчанию? Что-нибудь, что может быть сделано лучше?

Ответы [ 2 ]

1 голос
/ 24 мая 2019

Вызовите внешний текстовый редактор, такой как nano, sublime-text или gedit, в зависимости от того, какой из них установлен, и, возможно, от пользовательских настроек. Подождите, пока пользователь не отредактирует файл и не закроет текстовый редактор.

Интересный вопрос. Один из способов открыть файл xml с помощью редактора пользователя по умолчанию - использовать xdg-open , но он не дает pid приложения, в котором пользователь будет редактировать файл.

Вы можете использовать xdg-mime query default application/xml, чтобы узнать файл .desktop редактора по умолчанию, но затем вам нужно проанализировать этот файл, чтобы выяснить путь к исполняемой программе - это точно как xdg-open на самом деле работает , в функции search_desktop_file () строка, начинающаяся с записи 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;
}

1 голос
/ 23 мая 2019

Во-первых, подумайте не о том, чтобы написать собственное приложение или обертку, которая вызывает другой редактор, а о том, чтобы написать какой-нибудь плагин для какого-то существующего редактора, который достаточно гибок для поддержки дополнительных форматов и пропускает свой ввод через декомпрессию.

Конечно, это не единственное решение, но оно может быть проще для вас.

При вашем конкретном подходе вы можете:

  • Использовать EDITORи / или VISUAL переменные командной строки (на что также указал @KamilCuk), чтобы определить, какой редактор использовать.
  • Запустите редактор как дочерний процесс, чтобы вы знали, когда он завершит выполнение.вместо того, чтобы иначе общаться с ним.Получать уведомления об изменениях в файле или даже об его открытии или закрытии недостаточно, поскольку редактор может вносить изменения в несколько файлов, а некоторые редакторы даже не оставляют файл открытым, пока вы над ним работаете.
  • Не забудьте обработать случаи, когда редактор не может появиться;или висит;или вы получаете какое-то уведомление, чтобы перестать ждать редактора;и т. д.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...