简体   繁体   中英

What is the default mode for open() calls with O_CREAT and how to properly set it while opening/creating files

I am trying to recreate the basic functionality of fopen() using the I/O system calls. I am somehow suppose to "set the default mode for open() calls with O_CREAT" however am unsure how to go about this. It's not perfect but this is what I've got so far.

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 will be the file descriptor returned by the open call. I think the rest is self-explanatory.

It compiles but I'm getting a "segmentation fault" error when I try to run it. This function also fails to open a new file and associate a file descriptor to it.

I think the segmentation error might be somewhere in here:

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;
}

Where I'm trying to recreate fputc.

Here is the MYFILE struct:

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;

The file permissions should probably be 0644, or maybe 0666 (or maybe 0640/0660 to deny others access while allowing your group access), regardless of whether you're creating the file for reading or writing. You should not normally include execute permission (and you don't). I'd be willing to support fewer permissions for group (no write for group seems good to me). You can even make a file readonly for every other process while the current process has write permission with 0444 or tighter permissions. But the standard will use 0666 and let the umask remove permissions.

You might note that your code leaks if you fail to open the file. You should free(fp); before the return on the error path.

Note that you have not set all the fields in your structure, and neither has malloc() , so you have random junk in those fields. Curiously, there isn't a buffer in sight, even though there's a buffer size.


This code works for me. It cleans up, marginally, your myfopen() function, but otherwise, it runs without crashing. I think your problem is in other code.

#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 != '\0')
            myfputc(*src++, fp);
    }
    return 0;
}

Result:

$ ls -l test.txt
-rw-r-----  1 jleffler  staff  10 Feb 15 19:11 test.txt
$ cat test.txt
The text!
$ 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM