Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
431 views
in Technique[技术] by (71.8m points)

linux - plain C: opening a directory with fopen()

I have a program which opens a file and checks its length.

FILE* fd = fopen(argv[1], "rb");
fseek(fd, 0, SEEK_END);
size_t flen = ftell(fd);
if (flen == ((size_t)-1)) {
    printf("%s is a directory.
", argv[1]);
    fclose(fd);
    exit(1);
}

Now, at least under Linux, fopen() returns a valid file descriptor when opening a directory. This results in the seek operation returning -1 (or, as size_t is unsigned, 0xFFFFFFFFFFFFFFFF=264-1 on a 64-bit system).

Unfortunately, the condition in the above code (flen == ((size_t)-1)) does not catch that case, neither does flen == 0xFFFFFFFF (EDIT: should be 0xFFFFFFFFFFFFFFFF). printf()-Commands with %x ord %d as format string show that both sides of the comparison should have the same value.

Why does the comparison operator behave in such a strange way, even when both sides are of the same type (size_t)? I am using gcc 4.8.1 as compiler.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

From http://pubs.opengroup.org/onlinepubs/7908799/xsh/fopen.html:

The fopen() function will fail if: 
[EISDIR] The named file is a directory and mode requires write access.

At least on Linux, if you try to fopen("dirname", "wb") you get an EISDIR error. I also tried with a directory with d-------- access rights, and I still get EISDIR (and not EACCES.)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...