开发者

C File Operations: Check opened file pointer access mode

A simple question:

How do I check the access mode of an already opened file pointer?

So say a function is passed an already opened FILE pointer:

    //Pseudo code
    bool PseudoFunction(FILE *Ptr)
    {
        if( ... Insert check for read-only access rights )
        {
            //It's read only access mode
            return true;
        }
       //File pointer is not read-only and thus write operations are permitted
       return false;
    }

What would I use in the if statement to check the FILE pointer had been opened as read-only (or not, as the case may be), without writing to the file, and without relying on the user passing (possibly contradicting) arguments?

System is windows, code::blocks compiler, but for interests of code portability, cross-compatibility preferred.

Note, this isn't asking about file rights, but what access mode has been used by FILE pointer.

SELF-ANSWER [Cannot append a separate answer due to user rights limitations]:

There is a better answer by another poster below that includes the proper #defines

As earlier suggested, it appears the FILE pointer's _flag (as defined under _iobuf) is the key for knowing whether or not a file is read only. Your mileage may vary though, but the same basic concept should be easily adaptable, example code:

#define READ_ONLY_FLAG 1

bool PrintFlagPtr(const char FileName[], const char AccessMode[])
{
    FILE *Ptr = NULL;
    Ptr = fopen(FileName,AccessMode);
    printf("%s: %d ",AccessMode,Ptr->_flag);

    int IsReadOnly = Ptr->_flag;
    fclose(Ptr);
    Ptr = NULL;


    if( (IsReadOnly&READ_ONLY_FLAG) == READ_ONLY_FLAG )
    {
        printf("File is read only!\n");
        return true;
    }

    printf("\n");
    return false;
}

That, when all the different access mode combinations are used with above function, produces an output of:

Output:
w: 2
r: 1 File is read only!
a: 2
wb: 2
rb: 1 File is read only!
ab: 2
w+: 128
r+: 128
a+: 128
开发者_JAVA百科w+b: 128
r+b: 128
a+b: 128

I am curious as to why this was never suggested (or never used), given a cross-compatible front-end function (simply a function with the same name, with declarations depending on platform) passing a const int sourced from the given FILE pointer _flag would be quite a simple and easy solution to the problem.


On Linux (and possibly all UNIX systems) you could use fcntl to get the access mode of the file:

int get_file_status(FILE* f) {
    int fd = fileno(f);
    return fcntl(fd, F_GETFL);
}

Note that the returned value is an integer as combination of flags like O_RDONLY or O_RDWR, not the "r" or "w+" strings. See http://pubs.opengroup.org/onlinepubs/007908799/xsh/open.html for some of these flags.

Not sure about Windows, see On Windows/mingw, what is the equivalent of `fcntl(fd, F_GETFL) | O_ACCMODE`?.


Warning: this answer is specific to Visual Studio 2010.


The stdio.h file that comes with Visual Studio 2010 defines the FILE type like this:

struct _iobuf {
    char *_ptr;
    int   _cnt;
    char *_base;
    int   _flag;
    int   _file;
    int   _charbuf;
    int   _bufsiz;
    char *_tmpfname;
};
typedef struct _iobuf FILE;

When fopening a file with the "rb" mode, it gets the value of 0x00000001.

In the fopen function, some of the flags you're interesed in can be mapped as this:

r    _IOREAD
w    _IOWRT
a    _IOWRT
+    _IORW

These constants are defined in stdio.h:

#define _IOREAD         0x0001
#define _IOWRT          0x0002
#define _IORW           0x0080

The underlying file descriptor contains more info, I haven't dug further yet.


There is no standard way to achieve that.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜