Linux系统编程核心问题解析

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 相同的值。因此,该进程可以使用这些调用之一重新获得特权。

5、如果一个所有用户 ID 都为 X 的进程执行一个用户 ID 为非零值 Y 的 set - user - ID 程序,那么进程凭证设置如下:实际用户 ID = X,有效用户 ID = Y,保存的 set - user - ID = Y(我们忽略文件系统用户 ID,因为它跟踪有效用户 ID)。分别展示使用 setuid()、seteuid()、setreuid() 和 setresuid() 调用执行以下操作的方式:a) 暂停并恢复 set - user - ID 身份(即,将有效用户 ID 切换为实际用户 ID 的值,然后再切换回保存的 set - user - ID 的值)。b) 永久丢弃 set - user - ID 身份(即,确保有效用户 ID 和保存的 set - use

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值