使用 O_CREAT 调用 open() 的默认模式是什么以及如何在 opening/creating 文件时正确设置它
What is the default mode for open() calls with O_CREAT and how to properly set it while opening/creating files
我正在尝试使用 I/O 系统调用重新创建 fopen() 的基本功能。我以某种方式假设 "set the default mode for open() calls with O_CREAT" 但是我不确定如何去做。它并不完美,但这是我到目前为止所拥有的。
MYFILE * myfopen(const char * path, const char * mode){
MYFILE *fp = (MYFILE *)malloc(sizeof(MYFILE)); //EDITED
int fd;
switch(mode[0]){
case 'r':
fd=open(path, O_RDONLY | O_CREAT, 0440);
break;
case 'w':
fd=open(path, O_WRONLY | O_CREAT | O_TRUNC, 0220);
break;
default:
fd=open(path, O_RDWR | O_CREAT | O_TRUNC, 0660);
}
if(fd < 0){
return NULL;
}
fp->fileD=fd;
fp->offset=0;
return fp;
}
fileD 将是打开调用返回的文件描述符。我认为其余的是不言自明的。
它可以编译,但是当我尝试 运行 时出现 "segmentation fault" 错误。此函数也无法打开新文件并将文件描述符关联到它。
我认为分段错误可能在此处:
int myfputc(int c, MYFILE * fp){
if(write(fp->fileD, &c, 1) == -1){
return 1;
}
++fp->offset; //how to gain access to the current offset of the stream?
return 0;
}
我正在尝试重新创建 fputc。
这是 MYFILE 结构:
typedef struct {
int fileD; // descriptor
int bufferSz; // buffer size
int bufferCh; // # of bytes in stream
int offset; //current offset position
int errorF; // error flag
int EOFF; // EOF flag
} MYFILE;
文件权限可能应该是 0644,也可能是 0666(或者可能是 0640/0660,以拒绝其他人访问,同时允许您的组访问),无论您创建的文件是用于读取还是写入。您通常不应该包含执行权限(您也没有)。我愿意支持更少的组权限(不写组对我来说似乎很好)。当当前进程具有 0444 或更严格的写权限时,您甚至可以为每个其他进程将文件设置为只读。但标准将使用 0666 并让 umask 删除权限。
您可能会注意到,如果您未能打开该文件,您的代码就会泄漏。您应该在错误路径上的 return 之前 free(fp);
。
请注意,您尚未设置结构中的所有字段,malloc()
也未设置,因此这些字段中存在随机垃圾。奇怪的是,即使有缓冲区大小,也看不到缓冲区。
这段代码对我有用。它稍微清理了您的 myfopen()
函数,但除此之外,它运行时不会崩溃。我认为你的问题出在其他代码中。
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
typedef struct
{
int fileD; // descriptor
int bufferSz; // buffer size
int bufferCh; // # of bytes in stream
int offset; // current offset position
int errorF; // error flag
int EOFF; // EOF flag
} MYFILE;
static
MYFILE *myfopen(const char *path, const char *mode)
{
MYFILE *fp = (MYFILE *)malloc(sizeof(*fp));
int fd;
switch (mode[0])
{
case 'r':
fd = open(path, O_RDONLY | O_CREAT, 0640);
break;
case 'w':
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0640);
break;
default:
fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0640);
break;
}
if (fd < 0)
{
free(fp);
return NULL;
}
fp->fileD = fd;
fp->offset = 0;
fp->bufferSz = 0;
fp->bufferCh = 0;
fp->errorF = 0;
fp->EOFF = 0;
return fp;
}
static
int myfputc(int c, MYFILE *fp)
{
if (write(fp->fileD, &c, 1) == -1)
{
return 1;
}
++fp->offset; // how to gain access to the current offset of the stream?
return 0;
}
int main(void)
{
MYFILE *fp = myfopen("./test.txt", "w");
if (fp != 0)
{
const char *src = "The text!\n";
while (*src != '[=10=]')
myfputc(*src++, fp);
}
return 0;
}
结果:
$ ls -l test.txt
-rw-r----- 1 jleffler staff 10 Feb 15 19:11 test.txt
$ cat test.txt
The text!
$
我正在尝试使用 I/O 系统调用重新创建 fopen() 的基本功能。我以某种方式假设 "set the default mode for open() calls with O_CREAT" 但是我不确定如何去做。它并不完美,但这是我到目前为止所拥有的。
MYFILE * myfopen(const char * path, const char * mode){
MYFILE *fp = (MYFILE *)malloc(sizeof(MYFILE)); //EDITED
int fd;
switch(mode[0]){
case 'r':
fd=open(path, O_RDONLY | O_CREAT, 0440);
break;
case 'w':
fd=open(path, O_WRONLY | O_CREAT | O_TRUNC, 0220);
break;
default:
fd=open(path, O_RDWR | O_CREAT | O_TRUNC, 0660);
}
if(fd < 0){
return NULL;
}
fp->fileD=fd;
fp->offset=0;
return fp;
}
fileD 将是打开调用返回的文件描述符。我认为其余的是不言自明的。
它可以编译,但是当我尝试 运行 时出现 "segmentation fault" 错误。此函数也无法打开新文件并将文件描述符关联到它。
我认为分段错误可能在此处:
int myfputc(int c, MYFILE * fp){
if(write(fp->fileD, &c, 1) == -1){
return 1;
}
++fp->offset; //how to gain access to the current offset of the stream?
return 0;
}
我正在尝试重新创建 fputc。
这是 MYFILE 结构:
typedef struct {
int fileD; // descriptor
int bufferSz; // buffer size
int bufferCh; // # of bytes in stream
int offset; //current offset position
int errorF; // error flag
int EOFF; // EOF flag
} MYFILE;
文件权限可能应该是 0644,也可能是 0666(或者可能是 0640/0660,以拒绝其他人访问,同时允许您的组访问),无论您创建的文件是用于读取还是写入。您通常不应该包含执行权限(您也没有)。我愿意支持更少的组权限(不写组对我来说似乎很好)。当当前进程具有 0444 或更严格的写权限时,您甚至可以为每个其他进程将文件设置为只读。但标准将使用 0666 并让 umask 删除权限。
您可能会注意到,如果您未能打开该文件,您的代码就会泄漏。您应该在错误路径上的 return 之前 free(fp);
。
请注意,您尚未设置结构中的所有字段,malloc()
也未设置,因此这些字段中存在随机垃圾。奇怪的是,即使有缓冲区大小,也看不到缓冲区。
这段代码对我有用。它稍微清理了您的 myfopen()
函数,但除此之外,它运行时不会崩溃。我认为你的问题出在其他代码中。
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
typedef struct
{
int fileD; // descriptor
int bufferSz; // buffer size
int bufferCh; // # of bytes in stream
int offset; // current offset position
int errorF; // error flag
int EOFF; // EOF flag
} MYFILE;
static
MYFILE *myfopen(const char *path, const char *mode)
{
MYFILE *fp = (MYFILE *)malloc(sizeof(*fp));
int fd;
switch (mode[0])
{
case 'r':
fd = open(path, O_RDONLY | O_CREAT, 0640);
break;
case 'w':
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0640);
break;
default:
fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0640);
break;
}
if (fd < 0)
{
free(fp);
return NULL;
}
fp->fileD = fd;
fp->offset = 0;
fp->bufferSz = 0;
fp->bufferCh = 0;
fp->errorF = 0;
fp->EOFF = 0;
return fp;
}
static
int myfputc(int c, MYFILE *fp)
{
if (write(fp->fileD, &c, 1) == -1)
{
return 1;
}
++fp->offset; // how to gain access to the current offset of the stream?
return 0;
}
int main(void)
{
MYFILE *fp = myfopen("./test.txt", "w");
if (fp != 0)
{
const char *src = "The text!\n";
while (*src != '[=10=]')
myfputc(*src++, fp);
}
return 0;
}
结果:
$ ls -l test.txt
-rw-r----- 1 jleffler staff 10 Feb 15 19:11 test.txt
$ cat test.txt
The text!
$