Как файлы GNOME реализуют диалог копирования? - proUbuntu
1 голос
/

Для простых задач я использую файлы GNOME (Nautilus) для копирования файлов, а не rsync. Я попытался покопаться в источнике nautilus-file-operations.c , с которым я не знаком, и я предполагаю, что он использует собственную собственную реализацию (не cp) для обработки ошибок и до report_copy_progress? Я понятия не имею, где происходят реальные системные вызовы.

1 Ответ

0 голосов
/

Я считаю, что все файловые операции GNOME используют GFiles, которые в соответствии с описанием :

GFile - это абстракция высокого уровня для работы с файлами в виртуальной файловой системе. GFiles - это легкие неизменные объекты, которые не создают ввод-вывод при создании. Необходимо понимать, что объекты GFile представляют собой не файлы, а просто идентификатор файла. Весь ввод / вывод содержимого файла реализован как потоковые операции (см. GInputStream и GOutputStream).

Таким образом, ввод-вывод действительно реализован в ginputstream.c и goutputstream.c , в таких функциях, как g_input_stream_read , но это зависит от некоторой функции чтения GInputStreamClass class->read_fn, который варьируется в зависимости от того, выполняет ли программа потоковую передачу из сокета, локального файла, файла win32, потока для запроса и т. Д. (Мое предположение)

Для локальных файлов (на самом деле я не могу найти определение локального файла, но я предполагаю, что это файл с диска) в g_local_file_input_stream_read мы наконец находим системный вызов read в строке 158 :

static gssize
g_local_file_input_stream_read (GInputStream  *stream,
                void          *buffer,
                gsize          count,
                GCancellable  *cancellable,
                GError       **error)
{
  GLocalFileInputStream *file;
  gssize res;

  file = G_LOCAL_FILE_INPUT_STREAM (stream);

  res = -1;
  while (1)
    {
      if (g_cancellable_set_error_if_cancelled (cancellable, error))
    break;
      res = read (file->priv->fd, buffer, count);
      if (res == -1)
    {
          int errsv = errno;

      if (errsv == EINTR)
        continue;

      g_set_error (error, G_IO_ERROR,
               g_io_error_from_errno (errsv),
               _("Error reading from file: %s"),
               g_strerror (errsv));
    }

      break;
    }

  return res;
}

Аналогично, write вызов in g_local_file_output_stream_write:

static gssize
g_local_file_output_stream_write (GOutputStream  *stream,
                  const void     *buffer,
                  gsize           count,
                  GCancellable   *cancellable,
                  GError        **error)
{
  GLocalFileOutputStream *file;
  gssize res;

  file = G_LOCAL_FILE_OUTPUT_STREAM (stream);

  while (1)
    {
      if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return -1;
      res = write (file->priv->fd, buffer, count);
      if (res == -1)
    {
          int errsv = errno;

      if (errsv == EINTR)
        continue;

      g_set_error (error, G_IO_ERROR,
               g_io_error_from_errno (errsv),
               _("Error writing to file: %s"),
               g_strerror (errsv));
    }

      break;
    }

  return res;
}
Добро пожаловать на сайт proUbuntu, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...