如何使用 lseek 创建带孔的文件?
Posted
技术标签:
【中文标题】如何使用 lseek 创建带孔的文件?【英文标题】:How to create files with holes using lseek? 【发布时间】:2014-08-14 10:42:36 【问题描述】:我正在学习如何使用 lseek 在文件中创建漏洞。
这是我目前写的代码……
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string.h>
int main()
int fd;
char name[20] = "Harry Potter";
// Creating a file
if( (fd = open( "book.txt", O_RDWR | O_CREAT , S_IWRITE | S_IREAD ) < 0 ))
printf("\ncreat error");
// Seeking 100th byte, from the begining of the file
if ( lseek(fd, 100, SEEK_SET) == -1 )
if (errno != 0)
perror("lseek");
// Writing to the 100th byte, thereby creating a hole
if( write(fd, name, sizeof(char)*strlen(name)) != sizeof(char)*strlen(name) )
if (errno != 0)
perror("write");
// closing the file
if ( close(fd) == -1 )
if (errno != 0)
perror("close");
return 0;
当我编译并执行这段代码时,我得到一个 lseek 错误,并且名称“哈利波特”没有被插入到文件中。这是我执行上述代码时的输出:
lseek: Illegal seek
Harry Potter
我什至试图捕捉所有错误。 请进一步帮助我。
【问题讨论】:
据我所知,你不能越过文件的末尾,如果你想打一个洞,你应该写 0 个字节......一个“洞”是文件系统所做的不考虑有效... ;) open、lseek、write、close 函数是 POSIX(不在标准 C 中),因此您可以添加该标签。 @LeonardoBernardini 除了“据我所知”部分之外,您写的任何内容都不真实——考虑一下您不知道,也没有费心去寻找out ...只需阅读 lseek 手册页就会告诉您,正如 OP 试图做的那样,通过查找过去的写入数据会在文件中创建漏洞......但是有一点语法错误;看我的回答。 我的错误和道歉,我几乎可以肯定这是不可行的...... @Shao:Windows C 也支持它们,只是对标题进行了微小的更改。 【参考方案1】:if( (fd = open( "book.txt", O_RDWR | O_CREAT , S_IWRITE | S_IREAD ) < 0 ))
如果打开成功则将 fd 设置为 0,如果打开失败则设置为 1。因为您将它设置为 0,也就是您的控制台,所以它是写“哈利波特”的地方,而不是磁盘。而且你不能在终端上寻找。你想要的
if( (fd = open( "book.txt", O_RDWR | O_CREAT , S_IWRITE | S_IREAD )) < 0 )
还有
a) 系统调用失败后无需检查 errno != 0。
b) 你应该在出错时退出而不是失败。
c) sizeof(char) 始终为 1,因此无需乘以它。
d) main 应该有一个原型,例如,int main(void)
【讨论】:
很好看。我想这就是为什么一些编译器会警告嵌入式赋值... @david.pfx 对我来说并不难发现......当我看到哈利波特出现在终端机上时,我 99% 确定我会发现这个优先错误。并且 OP 使用的编译器会发出这样的警告,只要 OP 会要求它(例如,gcc -Wall)。 有趣的是,0 是标准输入的文件描述符,而不是输出。在触发错误的 Windows 上。 @david.pfx 是的,在 fd 0 上看到输出是违反直觉的,但是从古代 UNIX 编程开始的 IIRC,终端以读/写方式打开,然后 fd 被复制以产生 0, 1 和 2。这允许向 stdin 发送提示,即使 stdout 和 stderr 被重定向(现在有 /dev/tty )。 @JimBalter 谢谢。我还会记得提到的另外 4 点。我有检查任何类型大小的习惯,所以这就是我做 sizeof(char) 的原因。我这样做是因为我认为 sizeof(char) 在不同的系统上可能会有所不同。以上是关于如何使用 lseek 创建带孔的文件?的主要内容,如果未能解决你的问题,请参考以下文章