编译时我收到错误:
cc holetest.c -o holetest
holetest.c: In function ‘test_seek’:
holetest.c:48:19: error: ‘SEEK_HOLE’ undeclared (first use in this function)
holetest.c:48:19: note: each undeclared identifier is reported only once for each function it appears in
holetest.c:51:19: error: ‘SEEK_DATA’ undeclared (first use in this function)
make: *** [holetest] Error 1
如果我删除了SEEK_HOLE和SEEK_DATA,我没有任何问题。
我错过了包含或图书馆吗?
生成文件:
all: holetest
holetest: holetest.c
rm -f holetest
gcc holetest.c -o holetest
holetest.c:
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#define FILENAME "/tmp/partly.sparse"
#define FILE_SIZE (1<<30)
#define START_STRING "start of file\n"
#define START_LEN strlen(START_STRING)
#define END_STRING "\nend of file\n"
#define END_LEN strlen(END_STRING)
#define debug(M, ...) fprintf(stderr, "%i: DEBUG %10.10s:%3.0d: " M "\n", getpid(), __FILE__, __LINE__, ##__VA_ARGS__); fflush(stderr);
#define log_err(M, ...) fprintf(stderr, "%i: ERROR errno:%i %10.10s:%3.0d: " M "\n", getpid(), errno, __FILE__, __LINE__, ##__VA_ARGS__); fflush(stderr);
#define quit_if(COND, ...) do { \
if(COND) { \
log_err(__VA_ARGS__); \
perror(NULL); \
exit(errno); \
} \
} while(0);
int make_partly_sparse(const char *filename, off_t size) {
int r, fd;
fd = open(filename, O_RDWR|O_CREAT, 0755);
quit_if(fd < 1, "unable to create %s", filename);
r = write(fd, START_STRING, START_LEN);
quit_if(r < START_LEN, "unable to write %s", filename);
r = lseek(fd, FILE_SIZE - END_LEN, SEEK_SET);
quit_if(r < 0, "unable to seek %s", filename);
r = write(fd, END_STRING, END_LEN);
quit_if(r < END_LEN, "unable to write %s", filename);
r = close(fd);
quit_if(r < 0, "unable to close %s", filename);
return 0;
}
int test_seek(const char *filename) {
int r, fd;
fd = open(filename, O_RDWR|O_CREAT, 0755);
quit_if(fd < 1, "unable to open %s", filename);
debug("seeking hole at %li", START_LEN);
r = lseek(fd, 0, SEEK_HOLE);
quit_if(r < 0, "unable to seek %s", filename);
quit_if(r != START_LEN, "SEEK_HOLE unsupported %i", r);
r = lseek(fd, 0, SEEK_DATA);
quit_if(r < 0, "unable to seek %s", filename);
quit_if(r != (FILE_SIZE - END_LEN), "SEEK_DATA unsupported %i", r);
r = close(fd);
quit_if(r < 0, "unable to close %s", filename);
return 0;
}
int main(int argc, char *argv[]) {
debug("making sparse file: %s", FILENAME);
make_partly_sparse(FILENAME, FILE_SIZE);
test_seek(FILENAME);
return 0;
}
系统:
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=12.04
DISTRIB_CODENAME=precise
DISTRIB_DESCRIPTION="Ubuntu 12.04.2 LTS"
$ uname -a
Linux tux 3.2.0-45-generic #70-Ubuntu SMP Wed May 29 20:12:06 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
$ grep "ext" /etc/fstab
UUID=be3aacb3-6457-4ba1-92bb-0f63ad514f40 / ext4 errors=remount-ro 0 1
更新
它现在编译但不起作用,SEEK_HOLE跳过洞并寻找到文件的末尾。
$ make
rm -f holetest
gcc -D_GNU_SOURCE holetest.c -o holetest
$ ./holetest
18731: DEBUG holetest.c: 60: making sparse file: /tmp/partly.sparse
18731: DEBUG holetest.c: 47: seeking hole at 14
18731: ERROR errno:0 holetest.c: 50: SEEK_HOLE unsupported 1073741824
Success
$ du /tmp/partly.sparse
8 /tmp/partly.sparse
$ ls -lA /tmp/partly.sparse
-rwxr-xr-x 1 chris chris 1073741824 Aug 16 14:08 /tmp/partly.sparse
答案 0 :(得分:7)
stdio.h
将其定义为;
/* The possibilities for the third argument to `fseek'.
These values should not be changed. */
#define SEEK_SET 0 /* Seek from beginning of file. */
#define SEEK_CUR 1 /* Seek from current position. */
#define SEEK_END 2 /* Seek from end of file. */
#ifdef __USE_GNU
# define SEEK_DATA 3 /* Seek to next data. */
# define SEEK_HOLE 4 /* Seek to next hole. */
#endif
__USE_GNU
是您定义_GNU_SOURCE
时设置的内部符号,这意味着要使用它们,您需要使用-D_GNU_SOURCE
进行编译。
$ gcc test.c
test.c: In function ‘test_seek’:
test.c:48:26: error: ‘SEEK_HOLE’ undeclared (first use in this function)
test.c:48:26: note: each undeclared identifier is reported only once for each function it appears in
test.c:51:26: error: ‘SEEK_DATA’ undeclared (first use in this function)
$ gcc -D_GNU_SOURCE test.c
$
答案 1 :(得分:2)
允许您现在遇到的行为:来自lseek linux manpage:
在最简单的实现中,文件系统可以通过使SEEK_HOLE始终返回文件末尾的偏移量来支持操作,并使SEEK_DATA始终返回偏移量(即,即使offset指向的位置是一个洞,它可以被认为是由零序列组成的数据。
答案 2 :(得分:2)
请注意,lseek联机帮助页
但是,文件系统没有义务报告漏洞,所以 这些操作不是保证映射的机制 实际分配给文件的存储空间。
在3.8 kernel的Linux中添加了对ext4文件系统中的SEEK_HOLE支持,Ubuntu 12.04使用了比这更老的内核 - 你的内核版本是3.2.0-45。