Linux-APUE中对mmap函数的实例中,为什么需要设置输出文件的长度,特别是还调用一个write函数?
...
...
/* set size of output file */
if (lseek(fdout, statbuf.st_size - 1, SEEK_SET) == -1)
err_sys("lseek error");
if (write(fdout, "", 1) != 1)
err_sys("wrtie error");
...
...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
lseek设置offset不会直接使文件变大,还有调用其他函数,见manpage:
其实原因APUE在这个例子前 有说明:
"Since the starting offset of the mapped file is tied to the system's virtual memory page size, what happens if the length of the mapped region isn't a multiple of the page size? Assume that the file size is 12 bytes and that the system's page size is 512 bytes. In this case, the system normally provides a mapped region of 512 bytes, and the final 500 bytes of this region are set to 0. We can modify the final 500 bytes, but any changes we make to them are not reflected in the file. Thus, we cannot append to a file with mmap. We must first grow the file, as we will see in Figure 14.32."
具体到这个例子来说, 如果输入文件比输出文件 长,
比如输入文件内容 ABCDEFG, 输出文件 abcd.
那么如果去掉 lseek/write那两行代码, 则运行程序后, 输出文件 内容 为 ABCD. EFG不会被拷贝到输出文件中.
更新
实际上, 如果仔细看一下APUE的说明的话, 我们可以做一个更有趣的实验.
比如我的freebsd8, page size为4096. 现在 建一个 /tmp/in.txt 大小为4100(大于page size), 建/tmp/out.txt, 大小为10.
重复APUE上面的代码(去掉 lseek/write那两行代码), 得到 Segmentation fault: 11.
按照APUE上来推论, out.txt 的mapped region应该是 一个page size 4096; 向其拷贝4100个字节 导致内存越界了.