首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用“`fcntl`”和`F_OFD_SETLK`锁定文件中的某个范围

使用“`fcntl`”和`F_OFD_SETLK`锁定文件中的某个范围
EN

Stack Overflow用户
提问于 2022-06-08 14:19:00
回答 1查看 55关注 0票数 0

目标

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

背景

我有一个EEPROM,其中包含多个“分区”,其中每个分区包含不同的信息。

我希望避免一个分区溢出到另一个分区,或者一个分区可以读取其他信息并曲解它们。

我的问题

我想将fcntlF_OFD_SETLK一起使用,这样我就可以在每个打开的fd上锁定特定的范围。

锁定按预期工作,并试图锁定已经锁定的范围将导致EAGAIN,这是预期的。

对我来说不太明显的是,我可以写到一个被不同的fd锁定的范围。

问题

是否有可能锁定某个文件中的某个范围,使其不能由不同的已打开的fd写入?

如果没有,是否有不同的方法来实现我的目标?

代码:

链接到onlinegdb:https://onlinegdb.com/ewE767rbu

代码语言:javascript
复制
#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
}

输出:

代码语言:javascript
复制
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。我期望hallo0x0welt0x900

EN

回答 1

Stack Overflow用户

发布于 2022-06-08 15:39:21

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

如果不是

,是否有不同的方法来实现我的目标?

不要忽略获得锁的失败。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72547365

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档