C 使用mmap修改文件时出现权限错误

C 使用mmap修改文件时出现权限错误,c,linux,C,Linux,创建了一个修改字节文件的简单mmap程序。 在简单/小文件上以root用户身份运行,出现错误 # ./a.out tmp.txt 92 fd=3 mmap: Permission denied 代码片段 #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <s

创建了一个修改字节文件的简单mmap程序。 在简单/小文件上以root用户身份运行,出现错误

# ./a.out tmp.txt 92
fd=3
mmap: Permission denied
代码片段

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

int main(int argc, char *argv[]) {
    int fd = open(argv[1], O_WRONLY);
    printf("fd=%d\n", fd);
    char *p = mmap(0, 0x1000, PROT_WRITE, MAP_SHARED, fd, 0);
    if (p == MAP_FAILED) {
        perror ("mmap");
        return 1;
    }
    p[0] = 0xde;
    close(fd);
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[]){
int fd=打开(argv[1],仅限O_wr);
printf(“fd=%d\n”,fd);
char*p=mmap(0,0x1000,保护写入,映射共享,fd,0);
如果(p==映射_失败){
佩罗尔(“mmap”);
返回1;
}
p[0]=0xde;
关闭(fd);
返回0;
}
不知道出了什么问题。谢谢

更新1
修复了代码片段中的一个输入错误,我想在那里使用
PROT\u WRITE

从mmap的手册页:

EACCES文件描述符指的是非常规文件。或请求了文件映射,但fd未打开以进行读取。或 已请求映射共享,并设置了保护写入,但未设置fd 以读/写(O_RDWR)模式打开。或PROT_WRITE已设置,但 文件是仅附加的

因此,为了映射一个文件,您需要以读/写模式而不是写模式打开它。这是有意义的,因为需要读取文件的内容来初始化未写入的部分内存


此外,IA-32不允许页面的只写映射,因此在这样的机器上使用
PROT_write
进行映射也会隐式启用
PROT_READ
,因此对于不可读的文件描述符将失败。

来自mmap的手册页:

EACCES文件描述符指的是非常规文件。或请求了文件映射,但fd未打开以进行读取。或 已请求映射共享,并设置了保护写入,但未设置fd 以读/写(O_RDWR)模式打开。或PROT_WRITE已设置,但 文件是仅附加的

因此,为了映射一个文件,您需要以读/写模式而不是写模式打开它。这是有意义的,因为需要读取文件的内容来初始化未写入的部分内存


此外,IA-32不允许页面的只写映射,因此在这样的机器上使用
PROT_write
进行映射也会隐式启用
PROT_READ
,因此对于不可读的文件描述符将失败。

感谢@mch指出,我使用
PROT\u WRITE
更正了代码段,但得到了相同的结果。文件的大小真的是
0x1000
字节吗?这是4096字节。大小实际上是92字节,之所以使用
0x1000
,是因为它是我的Linux上的一个页面大小。tmp.txt拥有什么所有者/用户和权限,以及您作为什么用户运行程序<代码>ls-l tmp.txt;id感谢@mch指出,我使用
PROT_WRITE
更正了代码片段,但得到了相同的结果。文件的大小真的是
0x1000
字节吗?这是4096字节。大小实际上是92字节,之所以使用
0x1000
,是因为它是我的Linux上的一个页面大小。tmp.txt拥有什么所有者/用户和权限,以及您作为什么用户运行程序<代码>ls-l tmp.txt;id