>Objective
我想多次打开一个文件,但每个fd
只允许写入特定范围。
背景
我有一个EEPROM,它包含多个"分区",每个分区保存不同的信息.
我想避免一个分区溢出到另一个分区,或者一个分区可以读取其他信息并误解它们。
我的问题
我想将fcntl
与F_OFD_SETLK
一起使用,以便我可以在每个打开的fd
上锁定特定范围 .
锁定按预期工作,尝试锁定已经锁定的范围将导致EAGAIN
,这是预期的。
对我来说不太明显的是,我可以写入被不同fd
锁定的范围。
问题
是否可以锁定文件中的某个范围,使其无法被其他打开的 fd 写入?
如果没有,是否有其他方法可以实现我的目标?
法典:
链接到在线gdb: https://onlinegdb.com/ewE767rbu
#define _GNU_SOURCE 1
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static void ex(const char *what)
{
perror(what);
exit(1);
}
static void lock_range(int fd, off_t start, off_t len)
{
struct flock ff = {
.l_type = F_WRLCK,
.l_whence = SEEK_SET,
.l_start = start,
.l_len = len,
};
if (fcntl(fd, F_OFD_SETLK, &ff) < 0)
perror("fcntl");
}
static void write_at(int fd, const char *str, off_t offset)
{
if (pwrite(fd, str, strlen(str), offset) < 0)
perror("pwrite");
}
int main()
{
int firstfd = open("/tmp/abc.txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
if (firstfd < 0)
ex("open");
if (ftruncate(firstfd, 0x1000) < 0)
ex("ftruncate");
lock_range(firstfd, 0, 0x800);
lock_range(firstfd, 0, 0x800); // check if I can aquire the lock multiple times
int secondfd = open("/tmp/abc.txt", O_RDWR);
if (secondfd < 0)
ex("open");
lock_range(secondfd, 0, 0x800); // this one fails on purpose
lock_range(secondfd, 0x800, 0);
lock_range(firstfd, 0x801, 1); // and this one fails on purpose
write_at(firstfd, "hallo", 0);
write_at(firstfd, "hallo", 0x900); // this should fail, but doesn't
write_at(secondfd, "welt", 0); // this should fail, but doesn't
write_at(secondfd, "welt", 0x900);
close(firstfd);
close(secondfd);
system("hexdump -C /tmp/abc.txt"); // just for visualization
}
输出:
fcntl: Resource temporarily unavailable
fcntl: Resource temporarily unavailable
00000000 77 65 6c 74 6f 00 00 00 00 00 00 00 00 00 00 00 |welto...........|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000900 77 65 6c 74 6f 00 00 00 00 00 00 00 00 00 00 00 |welto...........|
00000910 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001000
请注意welto
hallo
被welt
覆盖。我期望在0x0
hallo
,在0x900
welt
。
锁有两种形式:强制锁和咨询锁。这些是咨询锁。这意味着它们可以阻止其他人获得锁。时期。它们不会阻止写入或任何其他形式的修改。
如果没有,有没有其他方法来实现我的目标?
不要忽略获取锁的失败。