LINUX.ORG.RU

GNU Coreutils 8.13

 ,


0

1

Джим Мейеринг (Jim Meyering) объявил о выходе GNU Coreutils 8.13.

Новая версия включает более 200 коммитов от 18 разработчиков, а также более 1000 коммитов из gnulib, внесённых со времени выхода Coreutils 8.12.

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

Исправление ошибок:

  • chown и chgrp теперь корректно работают с опциями -v и --from, то есть для файлов, которые не удовлетворяют указанным в --from UID:GID, выводится их текущий владелец, а не новый владелец остальных файлов (ошибка появилась в sh-utils-2.0g);
  • cp -r ранее могла ошибочно изменить права доступа у существующих каталогов (ошибка из coreutils версии 6.8);
  • cp -u -p до этого времени не удавалось предотвратить дублирование жёстких ссылок для каждой актуальной копии файла в пути назначения, то есть, если s/a и s/b являются жёсткими ссылками и файл dst/s/a актуален, cp -up s dst скопирует s/b в dst/s/b вместо того, чтобы просто создать ссылку с dst/s/b на dst/s/a (видимо, эта ошибка существует с самого начала);
  • использование памяти утилитами rm, du, chmod, chgrp, chown, chcon больше не пропорционально числу файлов в каталоге, соответственно, если ранее работа с каталогом, содержащим 4 миллиона файлов, могла потребовать примерно 1 гигабайт оперативной памяти, то теперь требуется лишь около 30 мегабайт;
  • pr -T более не игнорирует параметр LAST_PAGE — позицию, где нужно остановиться (ошибка появилась в textutils-1.19q);
  • split --number l/... более не создаёт посторонних файлов (ошибка из coreutils-8.8);
  • timeout теперь отправляет сигналы командам, создающим свои группы процессов, и нормально работает при запуске вместе с дочерним процессом (ошибка добавлена в версии 7.0 coreutils);
  • unexpand -a теперь выравнивает правильно, если за пробелами следовал символ табуляции, поскольку в этом случае пробелы отбрасывались, приводя к нарушению выравнивания — введена проверка, не следует ли символ табуляции за пробелами (ошибка появилась в coreutils-5.3.0).

Изменения в поведении:

  • cp -au при явном указании --preserve=links теперь может замещать более новые файлы в каталоге назначения, чтобы отображать жёсткие ссылки из источника;
  • chmod, chown и chgrp теперь отображают оригинальные атрибуты, когда указываются опции -v и -c.

Новая функциональность:

  • date теперь обрабатывает строки в формате ISO 8601 с «T» в качестве символа-разделителя, такие как «2004-02-29T16:21:42» или «2004-02-29T16:21:42.333-07:00» (с указанием часового пояса и долей секунды);
  • md5sum, sha1sum, sha224sum, sha384sum и sha512sum с опциями --strict --check теперь возвращают ненулевой результат (выдают ошибку) при любой некорректной строке на входе, а не ограничиваются просто предупреждением;
  • split --filter=CMD позволяет пропустить вывод команды через фильтр CMD; CMD в свою очередь может использовать значение переменной окружения $FILE, которая содержит имя выходного файла во время каждого запуска CMD, например, если мы хотим разбить файл на три приблизительно равные части и сжать их, то теперь это может быть сделано командой split -n3 --filter='xz > $FILE.xz' big (обратите внимание, что кавычки должны быть одинарными, а не двойными);
  • timeout принимает новую опцию --foreground для поддержки команд, запускаемых не напрямую из командной строки, если команда интерактивна или должна получать сигналы из терминала.

Улучшения:

  • cp -p теперь копирует тривиальные NFSv4 ACLs на Solaris 10 (ранее эта команда ошибочно применила бы нетривиальные ACL к файлу назначения);
  • благодаря улучшениям в gnulib, cp и ls теперь поддерживают ACL в системе HP-UX 11.11;
  • df теперь поддерживает дисковые разделы величиной более 4TiB в MacOS X 10.5 и новее и AIX 5.2 и новее;
  • join --check-order теперь выводит сообщение «join: FILE:LINE_NUMBER: bad_line» для неотсортированного файла, а не просто «join: file 1 is not in sorted order»;
  • shuf гораздо более эффективно выводит небольшие подмножества больших перестановок, например, `shuf -i1-$((2**32-1)) -n2' больше не потребляет память в непомерных количествах;
  • stat -f теперь распознаёт файловые системы GPFS, MQUEUE и PSTOREFS;
  • timeout теперь поддерживает доли секунды для задания интервалов.

Отказ от изменений:

  • в cp не будет добавлен индикатор прогресса, эта функциональность признана излишней, а тем, кому такой индикатор необходим, рекомендовано использовать программу rsync.

Исходный код

>>> Сообщение на Саванне

★★★★★

Проверено: svu ()
Последнее исправление: Zhbert (всего исправлений: 6)
Ответ на: комментарий от geekless

> Надо еще выводить текущий обрабатываемый файл и текущую позицию в нём, чтобы строить отдельный прогрессбар для файла.

Хм. Та строка итак под 80 символов, наверное, это придется писать отдельной строкой. Как-то так:

processed: 24 directories, 1584 files, 18953496 bytes written, 75 seconds
current: 1485 bytes of `testdir/READ ME!.txt'

Но тут всё немного хитрее. Во-первых, имя файла должно быть последним в строке вывода, чтобы фронтенду было легче выделить его из строки. Во-вторых, в имени файла в юниксах могут быть почти любые символы, включая символы перевода строки, например, и их надо экранировать. К счастью, в cp уже есть код для вывода имени файла, который умеет экранировать символы (тот, что спрашивает «cp: overwrite `testfile'?»), им, вероятно, и придется пользоваться, for consistency.

anonymous
()
Ответ на: комментарий от geekless

Вот только не знаю куда вам его слать, поэтому запощу прямо здесь.

Накладывается как обычно: из директории с configure даем команду

patch -p1 <cp_progress__coreutils-8.13.patch

file: cp_progress__coreutils-8.13.patch

Издевательства над кодом выглядят следующим образом:

diff -Naur a/lib/full-write.c b/lib/full-write.c
--- a/lib/full-write.c	2011-04-24 21:21:45.000000000 +0400
+++ b/lib/full-write.c	2011-09-17 23:28:54.000000000 +0400
@@ -48,6 +48,8 @@
 # define ZERO_BYTE_TRANSFER_ERRNO ENOSPC
 #endif
 
+size_t full_bytes_counter;
+
 /* Write(read) COUNT bytes at BUF to(from) descriptor FD, retrying if
    interrupted or if a partial write(read) occurs.  Return the number
    of bytes transferred.
@@ -73,6 +75,7 @@
       total += n_rw;
       ptr += n_rw;
       count -= n_rw;
+      full_bytes_counter += n_rw;
     }
 
   return total;
diff -Naur a/lib/full-write.h b/lib/full-write.h
--- a/lib/full-write.h	2011-04-24 21:21:45.000000000 +0400
+++ b/lib/full-write.h	2011-09-17 23:28:54.000000000 +0400
@@ -22,6 +22,7 @@
 extern "C" {
 #endif
 
+extern size_t full_bytes_counter;
 
 /* Write COUNT bytes at BUF to descriptor FD, retrying if interrupted
    or if partial writes occur.  Return the number of bytes successfully
diff -Naur a/src/copy.c b/src/copy.c
--- a/src/copy.c	2011-07-28 14:38:27.000000000 +0400
+++ b/src/copy.c	2011-09-18 09:09:26.000000000 +0400
@@ -119,6 +119,69 @@
 static char const *top_level_src_name;
 static char const *top_level_dst_name;
 
+/* Statistics related declarations. */
+#define PROGRESS_CUR	progress.page[progress.current]
+#define PROGRESS_ACT	progress.page[progress.current ^ 1]
+
+static struct
+{
+  struct
+  {
+    char src_name[PATH_MAX+1], dst_name[PATH_MAX+1];
+    size_t size;
+  } page[2];
+  int current;
+  unsigned dirs, files;
+  unsigned long long total_size;
+} progress = {0};
+
+void
+progress_sig (int sig)
+{
+    fprintf (stderr,
+             "processed: %u directories, %u files, %llu bytes written. "
+             "copying: %s to %s. %ld out of %ld bytes copied.\n",
+             progress.dirs, progress.files, progress.total_size,
+             quote(PROGRESS_ACT.src_name), quote(PROGRESS_ACT.dst_name),
+             full_bytes_counter, PROGRESS_ACT.size);
+}
+
+void
+progress_init ()
+{
+  memset (&progress, 0, sizeof (progress));
+  full_bytes_counter = 0;
+}
+
+void
+progress_next (const char* src_name, const char* dst_name)
+{
+  PROGRESS_CUR.size = -1;
+
+  strncpy (PROGRESS_CUR.src_name, src_name, PATH_MAX);
+  strncpy (PROGRESS_CUR.dst_name, dst_name, PATH_MAX);
+
+  progress.current ^= 1;
+
+  ++progress.files;
+  progress.total_size += full_bytes_counter;
+
+  full_bytes_counter = 0;
+}
+
+void
+progress_set_size (size_t size)
+{
+  PROGRESS_ACT.size = size;
+  full_bytes_counter = 0;
+}
+
+void
+progress_advance_dir ()
+{
+  ++progress.dirs;
+}
+
 /* Set the timestamp of symlink, FILE, to TIMESPEC.
    If this system lacks support for that, simply return 0.  */
 static inline int
@@ -590,6 +653,8 @@
   struct cp_options non_command_line_options = *x;
   bool ok = true;
 
+  progress_advance_dir ();
+
   name_space = savedir (src_name_in);
   if (name_space == NULL)
     {
@@ -991,6 +1056,8 @@
     {
       typedef uintptr_t word;
 
+      progress_set_size (src_open_sb.st_size);
+
       /* Choose a suitable buffer size; it may be adjusted later.  */
       size_t buf_alignment = lcm (getpagesize (), sizeof (word));
       size_t buf_alignment_slop = sizeof (word) + buf_alignment - 1;
@@ -1565,6 +1632,8 @@
   bool dest_is_symlink = false;
   bool have_dst_lstat = false;
 
+  progress_next (src_name, dst_name);
+
   if (x->move_mode && rename_succeeded)
     *rename_succeeded = false;
 
diff -Naur a/src/copy.h b/src/copy.h
--- a/src/copy.h	2011-07-28 14:38:27.000000000 +0400
+++ b/src/copy.h	2011-09-17 23:28:54.000000000 +0400
@@ -285,4 +285,7 @@
 bool chown_failure_ok (struct cp_options const *) _GL_ATTRIBUTE_PURE;
 mode_t cached_umask (void);
 
+void progress_sig (int);
+void progress_init ();
+
 #endif
diff -Naur a/src/cp.c b/src/cp.c
--- a/src/cp.c	2011-07-28 14:38:27.000000000 +0400
+++ b/src/cp.c	2011-09-18 01:49:35.000000000 +0400
@@ -21,6 +21,7 @@
 #include <sys/types.h>
 #include <getopt.h>
 #include <selinux/selinux.h>
+#include <signal.h>
 
 #include "system.h"
 #include "argmatch.h"
@@ -918,6 +919,8 @@
   char *target_directory = NULL;
   bool no_target_directory = false;
 
+  sigignore (SIGUSR1);
+
   initialize_main (&argc, &argv);
   set_program_name (argv[0]);
   setlocale (LC_ALL, "");
@@ -1166,6 +1169,9 @@
 
   hash_init ();
 
+  progress_init ();
+  sigset (SIGUSR1, progress_sig);
+
   ok = do_copy (argc - optind, argv + optind,
                 target_directory, no_target_directory, &x);
A-234 ★★★★★
()
Ответ на: комментарий от A-234

Из функции progress_set_size обнуление full_bytes_counter можно удалить, это было необходимо ранее но в текущей реализации full_bytes_counter и так обнуляется в progress_next который отрабатывает первым.

A-234 ★★★★★
()
Ответ на: комментарий от anonymous

Та строка итак под 80 символов, наверное, это придется писать отдельной строкой.

Зачем? PATH_MAX и так > 80, не будете же вы имена файлов разбивать.

К счастью, в cp уже есть код для вывода имени файла, который умеет экранировать символы (тот, что спрашивает «cp: overwrite `testfile'?»), им, вероятно, и придется пользоваться, for consistency.

Да, вы правы абсолютно и спасибо за подсказку :)

A-234 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.