目标
我想多次打开一个文件,但是应该只允许每个fd写入特定的范围。
背景
我有一个EEPROM,其中包含多个“分区”,其中每个分区包含不同的信息。
我希望避免一个分区溢出到另一个分区,或者一个分区可以读取其他信息并曲解它们。
我的问题
我想将fcntl和F_OFD_SETLK一起使用,这样我就可以在每个打开的fd上锁定特定的范围。
锁定按预期工作,并试图锁定已经锁定的范围将导致EAGAIN,这是预期的。
对我来说不太明显的是,我可以写到一个被不同的fd锁定的范围。
问题
是否有可能锁定某个文件中的某个范围,使其不能由不同的已打开的fd写入?
如果没有,是否有不同的方法来实现我的目标?
代码:
链接到onlinegdb: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,它是由welt覆盖的hallo。我期望hallo在0x0,welt在0x900。
发布于 2022-06-08 15:39:21
锁有两种形式:强制锁和咨询锁。这些是咨询锁。这意味着他们阻止其他人获得锁。句号。它们不会阻止书写或任何其他形式的修改。
如果不是
,是否有不同的方法来实现我的目标?
不要忽略获得锁的失败。
https://stackoverflow.com/questions/72547365
复制相似问题