c语言 - 使用"fcntl"和"F_OFD_SETLK"锁定文件中的某个范围



>Objective

我想多次打开一个文件,但每个fd只允许写入特定范围。

背景

我有一个EEPROM,它包含多个"分区",每个分区保存不同的信息.
我想避免一个分区溢出到另一个分区,或者一个分区可以读取其他信息并误解它们。

我的问题

我想将fcntlF_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

请注意weltohallowelt覆盖。我期望在0x0hallo,在0x900welt

锁有两种形式:强制锁和咨询锁。这些是咨询锁。这意味着它们可以阻止其他人获得锁。时期。它们不会阻止写入或任何其他形式的修改。

如果没有,有没有其他方法来实现我的目标?

不要忽略获取锁的失败。

相关内容

最新更新