使用 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!
$