LINUX.ORG.RU

Читаем заголовочные файлы 
#ifndef __USE_FILE_OFFSET64
    __off_t st_size;                    /* Size of file, in bytes.  */
#else
    __off64_t st_size;                  /* Size of file, in bytes.  */
#endif

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

Виноват. Нужно использовать stat64, а если _FILE_OFFSET_BITS == 64, то stat64 и stat то же самое.

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

Нет, анонимоус про lseek в тему написал, так как это один из способов получить размер файла. Но если файл большой, то для этого необходимо тоже макросы определять!!!

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

Тип off_t, который возвращает lseek 32-х разрядный. А stat64 в поле st_size возвращает какую-то чепуху. Как же все-таки получить правильный размер файла больше чем 4G?

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

посмотри при помощи strace kak ето делают другие

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

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

Рискну предложить такой способ:

#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)
# define BLKGETSIZE64 _IOR(0x12, 114, uint64_t)
#endif

static count_t file_len(aal_device_t *device)
{
uint64_t size;
off_t max_off = 0;

if (!device)
return INVAL_BLK;

#ifdef BLKGETSIZE64
if ((int)ioctl(*((int *)device->entity), BLKGETSIZE64, &size) >= (int)0) {
uint32_t block_count;

size = (size / 4096) * 4096 / device->blksize;
block_count = size;

if ((uint64_t)block_count != size) {
aal_fatal("The partition size is too big.");
return INVAL_BLK;
}

return (count_t)block_count;
}

#endif

#ifdef BLKGETSIZE
{
unsigned long l_size;

if (ioctl(*((int *)device->entity), BLKGETSIZE, &l_size) >= 0) {
size = l_size;
return (count_t)((size * 512 / 4096) * 4096 /
device->blksize);
}
}

#endif

if ((max_off = lseek(*((int *)device->entity),
0, SEEK_END)) == (off_t)-1)
{
file_error(device);
return INVAL_BLK;
}
return (count_t)(max_off / device->blksize);
}

Как видно из кода это взято из liball. Можно еще наверно в партеде посмотреть. Там тоже должен быть подходящий код.

Banshee
()

Истина в последней инстанции, как говориться

static long cp_new_stat64(struct kstat *stat, struct stat64 *statbuf)
{
struct stat64 tmp;

memset(&tmp, 0, sizeof(tmp));
tmp.st_dev = stat->dev;
tmp.st_ino = stat->ino;
#ifdef STAT64_HAS_BROKEN_ST_INO
tmp.__st_ino = stat->ino;
#endif
tmp.st_mode = stat->mode;
tmp.st_nlink = stat->nlink;
tmp.st_uid = stat->uid;
tmp.st_gid = stat->gid;
tmp.st_rdev = stat->rdev;
tmp.st_atime = stat->atime;
tmp.st_mtime = stat->mtime;
tmp.st_ctime = stat->ctime;
tmp.st_size = stat->size;
tmp.st_blocks = stat->blocks;
tmp.st_blksize = stat->blksize;
return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
}

asmlinkage long sys_stat64(char * filename, struct stat64 * statbuf, long flags)
{
struct kstat stat;
int error = vfs_stat(filename, &stat);

if (!error)
error = cp_new_stat64(&stat, statbuf);

return error;
}

Это из ядра, следовательно для наших целей надо использовать
stat64 сис. вызов и struct stat64 * в качестве аргумента

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

Все оказалосб просто

Нужно скомпилить программу с ключом -D_FILE_OFFSET_BITS=64 -D _GNU_SOURCE. Тогда поле структуры stat st_size будет 8-ми байтовым. И еще. Ни в коем случае не используйте ключ -malign-double. Иначе все системные структуры, у которых есть поля с типами long long и double 'поплывут'

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