文件打开:open,出现 EACCES:permission denied

乔望
2023-12-01

今天在 mac 上测试下载服务端的一个图片文件,发现之前能成功创建本地文件的代码,突然出现
拒绝访问的错误,此时文件打开的代码如下:

  int fd = open("./test.jpg", O_RDWR|O_APPEND|O_CREAT);
  int errnum = errno;
  if(fd < 0) {
     LOG(ERROR) << "file ./test.jpg open failed, errno is: " << errnum << ", details: "<< strerror(errnum);
  }

错误内容如下:

 file ./test.jpg open failed, errno is: 13, details: Permission denied;

然后我找出 open 的文档查看,在提到 open 的参数 mode 时,有这句话:

The mode argument must be supplied if O_CREAT or O_TMPFILE is
specified in flags; if it is not supplied, some arbitrary
bytes from the stack will be applied as the file mode.

也就是说如果 flags 中指定了 O_CREAT,则 mode 这个参数不可以省去,否则 open 会从栈中读取未知的值来使用;

从而导致了上述代码这样的现象,可以改成如下的方式打开目标文件:

wfd_ = open("./test.jpg", O_RDWR|O_APPEND|O_CREAT, S_IRWXU|S_IRWXG);

详细梳理下 open 这个接口的使用细节,open 函数原型如下:

 int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

如果 pathname 指定的文件不存在,且 flags 指定了 O_CREAT,则 open 会创建该文件,并返回文件的描述符,如果打开失败,则会返回 -1;

如果 flags 没有指定 O_CREAT 或者 O_TMPFILE , 那么 mode 将被忽略;如果前者指定了,则必须指定 mode 的值;

The mode argument specifies the file mode bits to be
  applied when a new file is created.  If neither O_CREAT
  nor O_TMPFILE is specified in flags, then mode is ignored
  (and can thus be specified as 0, or simply omitted).  The
  mode argument must be supplied if O_CREAT or O_TMPFILE is
  specified in flags; if it is not supplied, some arbitrary
  bytes from the stack will be applied as the file mode.

flags 必须指定下面三个访问模式之一:O_RDONLY, O_WRONLY, or O_RDWR;
对应只读、只写、可读写;

可选的文件创建标签如下:O_CLOEXEC, O_CREAT, O_DIRECTORY, O_EXCL, O_NOCTTY, O_NOFOLLOW, O_TMPFILE, and O_TRUNC, O_APPEND, O_ASYNC,
O_DIRECT, O_DSYNC, O_LARGEFILE, O_NOATIME (since Linux 2.6.8), O_NONBLOCK or O_NDELAY, O_PATH, O_SYNC,

Linux man: open

 类似资料: