2015-01-18 9 views
0

Мне нужно добавить LFS в процесс C, который использует fseek(). gcc и glibc имеют версии 3.2.3 и 2.5 соответственно.Почему fseeko() не работает с EINVAL?

Я сделал следующие изменения:

  1. добавил CFLAGS += -D_FILE_OFFSET_BITS=64 в Makefile.
  2. Я заменил вызов на fseek() с вызовом на fseeko() (мне также нужна поддержка MSVC6, но по одному шагу за раз).
  3. Я изменил тип второго аргумента на off_t. sizeof() от переменной возвращается 8.

Вот как хороший пример main(), как я могу получить мимо нашего DLP и его выход:

fd = fopen("large_file", "rb"); 
off_t offset = 1ULL << 32; 
rc = fseeko(fd, offset, SEEK_SET); 

rc = -1 sizeof(offset)=8 errno=22 offset=2147483648

+6

Ваш вопрос идеально подходит для включающего в себя [SSCCE] (http://sscce.org/) вместо словесно описания кода и результат. – NPE

+1

Пожалуйста, разместите достаточно кода, чтобы воспроизвести вашу проблему. – fuz

+0

Какую ОС вы наблюдаете за этим? – alk

ответ

0

В приведенной ниже программе, составленной с CFLAGS = -g2 -Wall -D_LARGEFILE64_SOURCE работ здесь (3.13.0-43-родовое # 72-Ubuntu SMP пн 8 декабря 19:35:06 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux)

(составление с CFLAGS = -g2 -Wall -D_FILE_OFFSET_BITS=64 и s/off64_t/off_t/ работает одинаково хорошо)

#include <stdio.h> 
#include <strings.h> 
#include <unistd.h> 

int main(void) 
{ 
off64_t offset ; 
int rc; 
FILE *fp; 

fp = fopen("testfile", "r+b"); 
if (!fp) { 
     perror("fopen"); 
     return 1; 
     } 

offset = 1ull << 32; 
rc = fseeko(fp, offset, 0); 
if (rc < 0) { 
     perror("fseeko"); 
     return 2; 
     } 
rc = fwrite("OMG!", 4, 1, fp); 
fprintf(stderr,"Write(4) : %d\n", rc); 

fclose(fp); 

return 0; 
} 
+0

Это более новая версия glibc. Моя версия не поддерживает fseeko(), я перешел к использованию [lseek64()] (http://linux.die.net/man/3/lseek64). – pseudorandomusername

1

1 << 32 в вашем примере не определено поведение. Вероятно, он вернет 0 или 1. Убедитесь, что перед переносом его нужно преобразовать 1 в подходящий тип. Если unsigned long имеет также 32 бита, то 1UL << 32 ошибочно аналогичным образом.

Избегайте -D_LARGEFILE64_SOURCE и off64_t, так как они просто усложняют ситуацию. Вместо этого используйте только -D_FILE_OFFSET_BITS=64 и используйте off_t, который затем должен быть 64 бит.

+0

На самом деле, я вынужден использовать '-D_LARGEFILE64_SOURCE' из-за версии glibc. – pseudorandomusername