Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
 Аватар для kordax
4 / 4 / 2
Регистрация: 08.06.2014
Сообщений: 89

Виснет вызов readdir при рекурсивном поиске по директориям

20.12.2014, 20:12. Показов 1278. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет.

Пытаюсь написать аналог walk Python, но извращённый
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#ifndef WALK_H
#define WALK_H
 
#endif // WALK_H
 
#include <stdlib.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include "list.h"
#include <errno.h>
#include <error.h>
 
void walk(fslist* list, char *root) // Функцию буду запускать рекурсивно.
{
    DIR* cur_dir_ptr;
    struct dirent* entry;
    fsnode *node = (fsnode*) malloc(sizeof(node));
    cur_dir_ptr = opendir(root);
    if(cur_dir_ptr == NULL)
    {
        if(errno == EACCES) perror(strerror(EACCES));
        if(errno == ENOTDIR) perror(strerror(ENOTDIR));
        if(errno == EBADF) perror(strerror(EBADF));
        if(errno == EMFILE) perror(strerror(EMFILE));
        if(errno == ENFILE) perror(strerror(ENFILE));
        if(errno == ENOENT) perror(strerror(ENOENT));
        if(errno == ENOMEM) perror(strerror(ENOMEM));
    }
    [B]while (entry = readdir(cur_dir_ptr))[/B]
    {
        if(errno == EBADF) perror(strerror(EBADF));
        char temp[_POSIX_PATH_MAX] = {0};
        strcpy(temp, root);
        if(entry->d_name[0] != 46)
        {
            if(entry->d_type == DT_REG) // Обрабатываем файл
            {
                node->type = "FIL";
                //strcpy(current, root);
                strcat(temp, "/");
                strcpy(node->path, strcat(temp, entry->d_name));
                fs_pushback(list, node); //Добавляем в список наш файл
                puts(node->path);
            }
            if(entry->d_type == DT_DIR) // Обрабатываем директорию
            {
                node->type = "DIR";
                //strcpy(current, root);
                strcat(temp, "/");
                strcpy(node->path, strcat(temp, entry->d_name));
                fs_pushback(list, node); //Добавляем в список наш файл
                puts(node->path);
                walk(list, temp);
            }
        }
    }
 
    closedir(cur_dir_ptr);
    return;
}
Как видно, функция работает рекурсивно, считывая все директории и папки в подпапках и т.д.
Функция работает до определённого момента:
/home/kordax/test
/home/kordax/test/9
/home/kordax/test/10
/home/kordax/test/10/test.php
/home/kordax/test/10/included
/home/kordax/test/10/included/346346.php Виснет здесь.
Виснет на таком вызове:
while (entry = readdir(cur_dir_ptr))

Я попробывал сделать STRACE и вот что вижу:
Bash
1
2
3
4
5
6
7
8
9
10
11
12
openat(AT_FDCWD, "/home/kordax/test/10/included", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 5
getdents(5, /* 3 entries */, 32768)     = 80
write(1, "/home/kordax/test/10/included/34"..., 41/home/kordax/test/10/included/346346.php
) = 41
futex(0x24ec594, FUTEX_WAIT_PRIVATE, 2, NULL) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
futex(0x24ec594, FUTEX_WAIT_PRIVATE, 2, NULL) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
futex(0x24ec594, FUTEX_WAIT_PRIVATE, 2, NULL) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
futex(0x24ec594, FUTEX_WAIT_PRIVATE, 2, NULL^CProcess 15260 detached
 <detached ...>
Вижу что всё открывается, получаются entries (т.е. элементы), далее происходит запись и тут самое интересное.
Я ещё не знаю как работают семафоры в ядре, но вижу вызов futex, который как я понимаю и пытается что-то починить или остановить из-за какого-то лимита.
Что это может быть?
Слишком много дескрипторов или что-нибудь ещё?

Подскажите пожалуйста линуксоиды, у меня очень мало опыта в программировании.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
20.12.2014, 20:12
Ответы с готовыми решениями:

Браузер виснет при поиске антивируса, установка антивируса невозможна (зависает намертво)
Предыстория: Искал crack для одной программы и нашёл что искал на ютубе. Просмотров было несколько сот тысяч, очень много лайков,...

Браузер виснет при поиске антивируса, установка антивируса невозможна (зависает намертво)
Предыстория: Искал crack для одной программы и нашёл что искал на ютубе. Просмотров было несколько сот тысяч, очень много лайков,...

Ошибка при рекурсивном вызове
На третьем вызове функции вылазит ошибка об отсутсвии инциализации переменой j, дебаг говорит, что после второго захода в функци j внезапно...

2
Эксперт С++
 Аватар для schdub
3073 / 1411 / 425
Регистрация: 19.01.2009
Сообщений: 3,894
20.12.2014, 21:01
Цитата Сообщение от kordax Посмотреть сообщение
C
1
fsnode *node = (fsnode*) malloc(sizeof(node));
kordax, имхо должно быть
C
1
fsnode *node = (fsnode*) malloc(sizeof(fsnode));
Добавлено через 8 минут
Цитата Сообщение от kordax Посмотреть сообщение
C
1
2
3
4
strcat(temp, "/");
strcpy(node->path, strcat(temp, entry->d_name));
fs_pushback(list, node); //Добавляем в список наш файл puts(node->path);
walk(list, temp);
нужно:
C
1
2
3
4
5
strcat(temp, "/");
strcat(temp, entry->d_name);
strcpy(node->path, temp);
fs_pushback(list, node); //Добавляем в список наш файл puts(node->path);
walk(list, temp);
1
 Аватар для kordax
4 / 4 / 2
Регистрация: 08.06.2014
Сообщений: 89
20.12.2014, 22:51  [ТС]
Пипец, ты как тестировщик все баги отловил у меня))
Наконец-то моя поделка заработало, спасибо бро.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.12.2014, 22:51
Помогаю со студенческими работами здесь

Stack overflow при рекурсивном вызове функции
Есть такая функция, которая вызывается в начальной точке квадрата из единичек в двухмерном массиве, ее задача пройти и пометить все...

Посчитать количество итераций при рекурсивном вызове функции
void hoarSort(int* arrPtr, int first_element, int last_element, int lenght_array, int etheration) { int i = first_element, j =...

При рекурсивном запросе к другим dns-серверам получаю отказ
Поднял сервер на Windows 2012 r2, установил компоненты DHCP, DNS, AD. При настройке каждого компонента проверял работоспособность: DHCP...

Виснет программа при компиляции, степовер не работает, так же виснет
Виснет программа при компиляции, степовер не работает, так же виснет. Программа - простейший калькулятор. ...

Как передать целочисленный параметр в функцию по ссылке при рекурсивном вызове?
void consonant_count(trie*root,trie*parent,int amount_of_consonant,bool found,int *c) { ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru