LINUX.ORG.RU

Фейлится fseek(file, 0, SEEK_END)

 


0

3

Есть несколько файлов на сервере, они читаются демоном на си. Вот так: http://pastebin.com/s7GJg3NJ

Проблема в том что пару раз за час он валится на fseek(..END):

Error while seeking for END ./queries/update_api_sound.sql. (-1)
Error while seeking for END ./queries/update_api_sound.sql. (-1)
Error while seeking for END ./queries/update_api_projector.sql. (-1)
Error while seeking for END ./queries/insert_defstack.sql. (-1)
Error while seeking for END ./queries/insert_defstack.sql. (-1)
Error while seeking for END ./queries/insert_defstack.sql. (-1)
Error while seeking for END ./queries/update_api_playserver.sql. (-1)
Error while seeking for END ./queries/insert_defstack.sql. (-1)
Error while seeking for END ./queries/update_api_projector.sql. (-1)
Error while seeking for END ./queries/update_api_projector.sql. (-1)
Error while seeking for END ./queries/insert_defstack.sql. (-1)
Error while seeking for END ./queries/insert_defstack.sql. (-1)
Error while seeking for END ./queries/update_api_sound.sql. (-1)
Error while seeking for END ./queries/insert_defstack.sql. (-1)
Error while seeking for END ./queries/update_api_sound.sql. (-1)
Error while seeking for END ./queries/update_api_sound.sql. (-1)
Error while seeking for END ./queries/insert_defstack.sql. (-1)
Думали может диск помер, написали тесты:
#include <stdio.h>
#include <string.h>

int main(int argc, char * argv[])
{
        if (!argv[1])
        {
                printf("Set filename\n");
                return 1;
        }

        int i;
        for (i = 0; i < 100000; i++)
        {
                FILE * file;
                file = fopen(argv[1], "rb");
                if (!file)
                {
                        printf("fopen failed\n");
                        return 1;
                }

                if (fseek(file, 0, SEEK_END))
                {
                        printf("fseek failed\n");
                        return 1;
                }

                printf("\r%06d: size = %d", i, ftell(file));

                fclose(file);
        }
        return 0;
}
Даже до 10 000 000 доводили - не фейлится.

В чем может быть проблема?

PrintError(«Error while seeking for END %s. (%d)\n», filename, result);

Воткните еще strerror(errno)

Размер можно узнать функциями *stat, без прыжков по файлу

Deleted
()
Ответ на: комментарий от someoneelsenotme

fseek не выставляет errno

В моем man fseek

Otherwise, -1 is returned and errno is set to indicate the error.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)

> Library implementations are allowed to not meaningfully support SEEK_END (therefore, code using it has no real standard portability

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

На портабилити плевать - на всех серверах стоит одна и та же версия всего

someoneelsenotme
() автор топика

Зачем режим «b» на Linux?

anonymous
()

Во-первых, воткните strerror(errno), как вам посоветовали выше.

Во-вторых, нет смысла перемещать файловый указатель для определения размера. И вообще поточный ввод-вывод вам тут не нужен. Открываете файл open(2), потом stat(2) для определения размера, затем read(2) в цикле (проверяя errno==EINTR) до победного.

Sorcerer ★★★★★
()

Вангую

     [EOVERFLOW]        The resulting file offset would be a value which can‐
                        not be represented correctly in an object of type
                        off_t for fseeko() and ftello() or long for fseek()
                        and ftell().

slovazap ★★★★★
()
Ответ на: комментарий от Sorcerer

А может ли влиять то что много потоков читают этот файл? По идее я ведь только на чтение открываю, ничего не должно влиять, не?

someoneelsenotme
() автор топика
Ответ на: комментарий от someoneelsenotme

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

А может ли влиять то что много потоков читают этот файл?

Они ведь работают с разными дескрипторами? Тогда нет.

Sorcerer ★★★★★
()
Ответ на: комментарий от Sorcerer

второй поток зачем-то закрывает дескриптор.

Там дескриптор существует только в пределах этой функции. Функция в первом сообщении.

someoneelsenotme
() автор топика
Ответ на: комментарий от someoneelsenotme

Там дескриптор существует только в пределах этой функции. Функция в первом сообщении.

Это не мешает «угадать» fd и закрыть его из другого потока.

mashina ★★★★★
()
Ответ на: комментарий от someoneelsenotme

Там дескриптор существует только в пределах этой функции.

Дескрипторы - глобальные, я имею в виду fileno(3). Может у вас существует поток, который, например, периодически закрывает все открытые дескрипторы.

Sorcerer ★★★★★
()
Ответ на: комментарий от Sorcerer

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

someoneelsenotme
() автор топика
Ответ на: комментарий от someoneelsenotme

Предположу, что кончились дескрипторы файлов для этого процесса.

...
FILE * f = fopen(filename, "rb");
...
if (f)
{
   ...

   // Требуется закрыть файловый дескриптор в обязательном порядке,
   // не зависимо от ошибок внутри данного блока кода.
   fclose(f);
};
Vic
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.