LINUX.ORG.RU

Работа с файлами > 2.5 Gb


0

0

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

int fd = open64 ("aaa", O_RDWR | O_CREAT | O_TRUNC);

long long int off = fseek64 (fd, 0, SEEK_SET);

И fseek64() не возвращает нулевое значение.


Ответ на: комментарий от Murr

Да, описка, речь о lseek().

int fd = open64 ("aaa", O_RDWR | O_CREAT | O_TRUNC, 0666);

По-прежнему lseek64 (fd, 0, SEEK_SET) возвращает ненулевое значение.

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

Вставь, однако же, две буквы L после нуля, как написано выше.

Если не поможет, то приведи, однако же, значение errno. "Возвращает ненулевое значение" - это детский сад.

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

[root@murmillo tmp]# cat test.c
#include <stdio.h>
#include <fcntl.h>

extern int lseek64(int, long long, int);

main() {
    int fd= open64("aaa", O_RDWR|O_CREAT|O_TRUNC, 0666);
    long long t = lseek64(fd, 0, SEEK_SET);
    printf("%llx\n", t);
}
[root@murmillo tmp]# gcc test.c
[root@murmillo tmp]# ./a.out
0

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

> IMHO, если 0 и 0LL различны, то ты неправильно включаешь заголовки.

IMHO, абсолютно верно.

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

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

Все верно.

К сожалению, 64-битных файловые функции так удачно описаны, что правильно включить заголовки крайне затруднительно. Если кто-нибудь может привести пример (удобно взять вышеприведенную программу и добиться ее работы без явного long long нуля и без явного описания функции), то я буду очень признателен.

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

В info libc описаны макросы, с которыми надо собирать программу.

[root@murmillo tmp]# cat test.c
#define _LARGEFILE64_SOURCE
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>


int main(int argc, char*argv[]) {
    int fd= open64("aaa", O_RDWR|O_CREAT|O_TRUNC, 0666);
    long long t = lseek64(fd, 0, SEEK_SET);
    printf("%llx\n", t);

    return 0;
}
[root@murmillo tmp]# gcc -Wstrict-prototypes test.c
[root@murmillo tmp]# ./a.out
0


Вроде даже работает.

idle:

Да, компиляция с предупреждениями - большое благо. :)

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

>В info libc описаны макросы, с которыми надо собирать программу.

Но даже в этом случае остается предупреждение о неявном объявлении для функций pread64, pwrite64(), lseak64().

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

Tsahes:

В моем примере никаких сообщений нет. Маловероятно, чтобы в наших дистрибутивах так сильно отличались заголовки.

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

[root@bf unknown]# cat test.c
#define _LARGEFILE64_SOURCE
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char*argv[]) {
    int fd= open64("aaa", O_RDWR|O_CREAT|O_TRUNC, 0666);
    long long t = lseek64(fd, 0, SEEK_SET);
    printf("%llx\n", t);
    pwrite64 (fd, &t, 8, lseek64 (fd, 0, SEEK_CUR));
    return 0;
}

[root@bf unknown]# gcc -Wall test.c
test.c: In function `main':
test.c:11: warning: implicit declaration of function `pwrite64'
[root@bf unknown]#

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

Такой вариант очевиден, но все равно хорошо. Молодцы ;)

Может, попробуете теперь без _LARGEFILE64_SOURCE (или объясните мне, почему я должен определять эту штуку своими силами)?

;)

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

> IMHO, если 0 и 0LL различны, то ты неправильно включаешь заголовки.

Недопол. Они _натурально_ различны -- 0LL, as я понимаю, lonl long 0, а 0 -- какой-то другой, так? А в Цэ, где нет приведений, это две оочень большие разницы.

С уважением -- Смоляное Чучелко

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

Tsahes:

Ну на lseek64 то не ругается?
Для pwrite64 нужен еще один define (как это следует из man).

[root@murmillo tmp]# cat test.c
#define _XOPEN_SOURCE 500
#define _LARGEFILE64_SOURCE
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>


int main(int argc, char*argv[]) {
    int fd= open64("aaa", O_RDWR|O_CREAT|O_TRUNC, 0666);
    long long t = lseek64(fd, 0, SEEK_SET);
    pwrite64(fd, "aaa", 3, 0);
    printf("%llx\n", t);

    return 0;
}
[root@murmillo tmp]# gcc -Wall test.c
[root@murmillo tmp]#

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

> А в Цэ, где нет приведений, это две оочень большие разницы.

В C есть приведения. Они определяются типом переменной при присвоении, прототипом при передаче параметров и еще кучей правил для разных контекстов.

Отсутствие прототипа - по сути ошибка.
Но для некоторых компиляторов для IA32 это не слишком актуально, т.к. они всегда расширяет аргументы до 4 байт(в том числе однобайтный char, двухбайтный short и т.д.). Случай с long long - это отличный пример, когда эта ошибка проявляется, т.к. передаются 8 байт, т.е. половина аргумента может уйти в следующий аргумент.

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

> Они _натурально_ различны -- 0LL, as я понимаю, lonl long 0,
> а 0 -- какой-то другой, так?

верно

> А в Цэ, где нет приведений, это две оочень большие разницы.

неверно. в С есть арифметическое приведение типов. пример:
      double x = 1; // x == 1.0

аналогично, если компилятор знает прототип функции, к ее
аргументам применяются те же преобразования, что и при
присваивании, то есть:

      void f(double);
      f(1); // работает как f(1.0)

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

idle:

У меня сетевой червь, который перехватывает твои сообщения, обрабатывает, отправляет их от моего имени на сервер, а потом уже и твои. :)

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

>передаются 8 байт, т.е. половина аргумента может уйти в следующий
>аргумент.

Вернее, наверное, будет произведено преобразование к int. И наоборот следующий аргумент уйдет в половину предыдущего.

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

> А в Цэ, где нет приведений

как это? в C есть неявное привидение типов и так называемая операция integer promotion ..

в случае привидения int типа с меньшим ранком к int типу с большим ранком - значение не изменится ..

то есть писать

long long int i = 0; - корректно .. у long long наивысший ранк из всех intов

но надо учитывать что некоторые преобразования имплементационно зависимы ..

например int i = <number>LL; не совсем корректно, но unsigned int i = <number>LL; корректно

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

Это все здорово.

Но нет ли у общества соображений, как обойтись без #define _LARGEFILE64_SOURCE, или соображений, доказывающих, что и с ним хорошо?

Что будет, например, если часть заголовочных файло в будет включена до этого define, а часть уже после (большом проекте достаточно сложно гарантировать, что такого никогда не случится)?

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

если прототип функции не будет соответствовать реалиям линковки - то просто вызов может делаться неверно - компилер может некорректно формировать стек и функция выдерет неправильно аргументы .. об этом уже сказал Murr

если у тебя нет уверености в том какой прототип будет использоваться - то лучше явно его пропиши в местах где ты пользуешь эту функцию

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