1、编写一个程序,使用标准文件I/O系统调用(open()和lseek())和off_t数据类型来创建大文件。在编译程序时,将_FILE_OFFSET_BITS宏设置为64,并进行测试以证明可以成功创建大文件。
以下是修改后的程序:
#define _FILE_OFFSET_BITS 64
#include <sys/stat.h>
#include <fcntl.h>
#include "tlpi_hdr.h"
int
main(int argc, char *argv[])
{
int fd;
off_t off;
if (argc != 3 || strcmp(argv[1], "--help") == 0)
usageErr("%s pathname offset\n", argv[0]);
fd = open(argv[1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
if (fd == -1)
errExit("open");
off = atoll(argv[2]);
if (lseek(fd, off, SEEK_SET) == -1)
errExit("lseek");
if (write(fd, "test", 4) == -1)
errExit("write");
exit(EXIT_SUCCESS);
}
编译命令:
cc -D_FILE_OFFSET_BITS=64 modified_large_file.c -o modified_large_file
测试命令:
./modified_large_file x 10111222333
之后使用
ls -l x
查看文件大小,验证是否成功创建大文件。
2、编写一个程序,使用O_APPEND标志打开一个现有文件进行写入,然后在写入一些数据之前将文件指针定位到文件开头。数据会出现在文件的什么位置?为什么?
数据会出现在文件末尾。因为使用 O_APPEND 标志打开文件时,内核会保证每次写操作都从文件末尾开始,即使在写操作之前使用 lseek 将文件偏移量设置到文件开头,写操作仍会忽略该偏移量,将数据追加到文件末尾。
3、本练习旨在展示使用O_APPEND标志打开文件所保证的原子性为何必要。编写一个程序,该程序最多接受三个命令行参数:$ atomic_append 文件名 字节数 [x]。该程序应打开指定的文件名(必要时创建它),并通过一次写入一个字节的方式向文件追加字节数指定的字节。默认情况下,程序应使用O_APPEND标志打开文件,但如果提供了第三个命令行参数(x),则应省略O_APPEND标志,而是在每次写入之前执行lseek(fd, 0, SEEK_END)调用。同时运行该程序的两个实例,不使用x参数,向同一个文件写入100万个字节:$ atomic_append f1 1000000 & atomic_append f1 1000000。对不同的文件重复相同的步骤,但这次指定x参数:$ atomic_append f2 1000000 x & atomic_append f2 1000000 x。使用ls -l列出文件f1和f2的大小,并解释差异。
-
源代码发行版中
fileio/atomic_append.c文件提供了解决方案。 -
运行程序后结果示例如下:
bash $ ls -l f1 f2 -rw------- 1 mtk users 2000000 Jan 9 11:14 f1 -rw------- 1 mtk users 1999962 Jan 9 11:14 f2
- 因为
lseek()和write()组合不是原子操作,程序的一个实例有时会覆盖另一个实例写入的字节,所以文件f2的字节数少于 200 万。
4、具有以下用户 ID 的进程是否具有特权?请解释你的答案。实际用户 ID = 0,有效用户 ID = 1000,保存的用户 ID = 1000,文件系统用户 ID = 1000
严格来说,这样的进程没有特权,因为其有效用户 ID 非零。但是,无特权进程可以使用 setuid() 、 setreuid() 、 seteuid() 或 setresuid() 调用将其有效用户 ID 设置为与实际用户 ID 或保存的用户 ID 相同的值。因此,该进程可以使用这些调用之一重新获得特权。

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



