Необходимо создать тест, который будет проверять корректность работы функций из glibc, оперирующих длинными именами файлов в системе NTFS. Проверяемые функции:creat(),open(), fopen(), stat(), unlink(), readdir(), opendir(),
*** Bug 9615 has been marked as a duplicate of this bug. ***
Написано приложение, тестирующее вышеприведенные функции glibc на корректность работы с длинными именами в системе ntfs: git.eter:/people/reprofy/public/glibc_vlfn_test.git Вывод программы с длинным именем в параметре(150 русских символов): [root@host-35 testfilenames]# ../glibc_vlfn_test ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя creat_test: creat() testing, trying to creat ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя: creat_test: file ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя is created with descriptor = 3 open_test: open() testing, trying to open ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя: open_test: file ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя is opened with descriptor = 4 stat_test: stat() testing, trying to take stat info from ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя: stat_test: file ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя is stated, it's inode:157 read_open_dir_test: File is found filename = ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя, filename length = 300 unlink_test: unlink() testing, trying to unlink file ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя: unlink_test: file ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя is unlinked creat_test: creat() testing, trying to creat ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя: creat_test: file ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя is created with descriptor = 5 fopen_test: fopen() testing, trying to open ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя: fopen_test: file ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя is opened remove_test: remove() testing, trying to remove file ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя: remove_test: file ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя is removed Как видно из вывода, все функции работают с длинным русским именем в системе ntfs. Для системы rsfs: [root@host-35 rsfs]# ./glibc_vlfn_test creat_test: creat() testing, trying to creat ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя: crear_test: creat() error: : File name too long creat_test: can't creat file ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя open_test: open() testing, trying to open ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя: open_test: open() error: : File name too long open_test: can't open file ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя stat_test: stat() testing, trying to take stat info from ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя: stat_test: stat() error: : File name too long stat_test: can't take stat info from file ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя read_open_dir_test: File isn't found unlink_test: unlink() testing, trying to unlink file ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя: unlink_test: unlink() error: : File name too long unlink_test: can't unlink file ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя creat_test: creat() testing, trying to creat ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя: crear_test: creat() error: : File name too long creat_test: can't creat file ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя fopen_test: fopen() testing, trying to open ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя: fopen_test: fopen() error: : File name too long fopen_test: can't open file ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя remove_test: remove() testing, trying to remove file ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя: remove_test: remove() error: : File name too long remove_test: can't remove file ещеболеедлинноеоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимя
После добавления еще нескольких функций для проверки и улучшения вида выводимой информации, последняя приняла вид для ntfs: [root@host-35 ntfs]# ./glibc_vlfn_test creat_test: working access_test: working chmod_test: working open_test: working stat_test: working read_open_dir_test: working unlink_test: working creat_test: working symlink_test: working chmod_test: working fopen_test: working truncate_test: working link_test: working remove_test: working mkdir_test: working rmdir_test: working для rsfs: [root@host-35 rsfs]# ./glibc_vlfn_test crear_test: creat() error: File name too long access_test: access() error: File name too long chmod_test: chmod() error: File name too long open_test: open() error: File name too long stat_test: stat() error: File name too long read_open_dir_test: File isn't found unlink_test: unlink() error: File name too long crear_test: creat() error: File name too long symlink_test: working chmod_test: chmod() error: File name too long fopen_test: fopen() error: File name too long truncate_test: truncate() error: File name too long link_test: link() error: File name too long remove_test: remove() error: File name too long mkdir_test: mkdir() error: File name too long rmdir_test: rmdir() error: File name too long
Добавлен подсчет ошибок(ntfs): [root@host-35 ntfs]# ./glibc_vlfn_test creat_test: working access_test: working chmod_test: working open_test: working stat_test: working read_open_dir_test: working unlink_test: working creat_test: working symlink_test: working chmod_test: working fopen_test: working truncate_test: working link_test: working remove_test: working mkdir_test: working rmdir_test: working Errors: 0 Осталось разобраться почему в некоторых случаях не выводятся сообщения о некоторых функциях.
Новый репозиторий с программой : git.eter:/people/reprofy/public/glibc_tests.git
В планах исправить test, чтобы он давал компактный и информативный результат
Исправлен вывод тестовой программы.
Исправлен вид вывода, теперь правильность теста осуществляется в макросе,а не вкаждой функции.
Теперь вывод всех функций через макрос. Проблема - как определять в макросе длину создаваемого имени, убрать предупреждения warning: ISO C forbids braced-groups within expressions.
Теперь тестируются два граничных варианта(1023 и 1024 байта соответственно)
Убраны предупреждения о необъявленных функциях: int lstat(const char *file_name, struct stat *buf); int truncate(const char *path, off_t length); int symlink(const char *topath, const char *frompath); Проблема была в том, что данных функций нет в стандарте ISO C99. Решение : исправление опции сборки --std=c99 на --std=gnu99. Другой путь решения - включение __STRICT_ANSI__. Убраны предупреждения warning: ISO C forbids braced-groups within expressions. Решено путем исключения скобок и точек с запятой. Последовательные операции теперь перечислены через запятую.
Взял тест: $ git clone git.eter:/people/reprofy/packages/verylongfilenames.git Запустил: $ ./test 1 Request for more parameters $ ./test -h 2 Wrong parameter $ ./test --help 2 Wrong parameter Наверное, разумно писать, что за параметр ты хочешь увидеть? $ ./test 100 2 <<<< Что за 2? File is created. Descriptor = 3 <<<< Вот совсем не интересно, какой дескриптор. Интересно, какое у него имя. Причём, полученный из дексриптора: http://stackoverflow.com/questions/1188757/getting-filename-from-file-descriptor-in-c Its length = 100 <<<< Чья длина? <<<< Было сгенерировано название файла? Давайте покажем его. File with Russian name isn't created, it's length 259 bytes File isn't found <<<<< Отдельно тестируем с русскими буквами и латиницей? Тогда давайте в них будет одинаковое количество символов. Limits: Limits.h _POSIX_NAME_MAX not defined <<<<<<< файл не может называться с большой буквы. Limits.h NAME_MAX not defined <<<<<< Наверное, надо разобраться? У тебя ни одна константа не определена. Limits.h _XOPEN_NAME_MAX not defined Limits.h _POSIX_PATH_MAX not defined Limits.h PATH_MAX not defined Limits.h _XOPEN_PATH_MAX not defined Limits.h _POSIX_NO_TRUNC=1 fpathconf output: Error of calling fpathconf, descriptor = -1 pathconf output: Error of calling pathconf, path = оченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдлинноеимяоченьдли257 <<<<< и вдруг в конце тестов вылезло какое-то имя fpathconf output: Error of calling fpathconf, descriptor = -1 pathconf output: PATH_MAX=4096 Вот статья на тему PATH_MAX в GNU/Hard: http://www.gnu.org/software/hurd/community/gsoc/project_ideas/maxpath.html Вот здесь ещё некоторая информация, в том числе для других систем, стоит добавить проверку. http://www.opennet.ru/man.shtml?topic=realpath&category=3&russian=0
(В ответ на comment #3) > git.eter:/people/reprofy/public/glibc_vlfn_test.git > После добавления еще нескольких функций для проверки и улучшения вида > выводимой информации, последняя приняла вид для ntfs: Хотелось бы так же задавать длину имени файла. Нужно обязательно добавить генератор имени, не надо его задавать константой. Также не понял, почему теста получилось два, может быть, достаточно одного?
(В ответ на comment #13) > (В ответ на comment #3) > > git.eter:/people/reprofy/public/glibc_vlfn_test.git ... > > Хотелось бы так же задавать длину имени файла. > Нужно обязательно добавить генератор имени, не надо его задавать константой. > > Также не понял, почему теста получилось два, может быть, достаточно одного? Мы когда-то решили, что не стоит мучаться с генератором, а задать два имени константами. Поэтому и два теста - они проверяют граничные значение: само граничное значение и значение, большее на единицу. Первый тест считается пройденным, если оговоренные функции glibc выполняются успешно, второй, если они выполняются с ошибкой. Видимо, достигнут этап, когда необходимо использовать генератор имени?
(В ответ на comment #14) ... > Мы когда-то решили, что не стоит мучаться с генератором, а задать два имени > константами. Поэтому и два теста - они проверяют граничные значение: само > граничное значение и значение, большее на единицу. Первый тест считается > пройденным, если оговоренные функции glibc выполняются успешно, второй, если > они выполняются с ошибкой. > Видимо, достигнут этап, когда необходимо использовать генератор имени? Вопрос: есть ли задание длины имени при запуске теста? Да, давай всё же сделаем задание и генерацию пары имён: чистой латиницы и русских букв, чтобы иметь ясную картину.
Добавил генераторы русских и английских имен, парсер строки параметров. Все лежит здесь : /people/reprofy/public/testfilenames.git Так же, надо обратить внимание на генерацию этих самых имен - добавлять в конец генерируемых имен завершающий ноль.
Завершающий ноль добавлен. В glibc_vlfn_test теперь можно генерировать имя заданной длины латиницей либо кириллицей. Код функций перемещен в отдельный файл, а определения - в соответствующие заголовочные. Добавлена опция "-l", которая задает длину имени файла, предполагаемое ограниечение на длину в системе.
Добавлена поддержка bsd-систем. [guest@ ~/testfilenames]$ ./test -r 10 Generated name : пьюйтжяэсц File is created with name: пьюйтжяэсц File is found; filename = пьюйтжяэсц, filename length = 20 Limits: limits.h _POSIX_NAME_MAX = 14 limits.h NAME_MAX = 255 limits.h _XOPEN_NAME_MAX = 255 limits.h _POSIX_PATH_MAX = 256 limits.h PATH_MAX = 1024 limits.h _XOPEN_PATH_MAX = 1024 limits.h _POSIX_NO_TRUNC=1 fpathconf output: _PC_NAME_MAX=255 pathconf output: _PC_NAME_MAX=255 fpathconf output: _PC_PATH_MAX=1024 pathconf output: _PC_PATH_MAX=1024
В testfilenames исправлено определение BSD-подобных операционных систем.
Откладываем задачи, к которым не обращались более 100 дней.