|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #69163 fopen(__DIR__, 'r') succeeds
Submitted: 2015-03-02 19:16 UTC Modified: 2016-10-12 16:04 UTC
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: salsi at icosaedro dot it Assigned:
Status: Open Package: Streams related
PHP Version: Irrelevant OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Bug Type:
From: salsi at icosaedro dot it
New email:
PHP Version: OS:


 [2015-03-02 19:16 UTC] salsi at icosaedro dot it
On Linux, opening a directory succeeds; subsequent reads always returns string("") and feof() is true, no warnings.

Test script:
$f = fopen(__FILE__, 'r');
for($i=0; $i<3; $i++){
	echo "feof is "; var_dump(feof($f));
	echo "fread returns "; var_dump(fread($f, 10));

Actual output:
resource(5) of type (stream)                                                                         
feof is bool(false)                                                                                  
fread returns string(10) "<?php                                                                      
feof is bool(false)                                                                                  
fread returns string(10) "r_reportin"                                                                
feof is bool(false)                                                                                  
fread returns string(10) "g(PHP_INT_"  

Expected result:
Expected output:
E_WARNING: cannot open directory


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2015-03-02 20:22 UTC] salsi at icosaedro dot it
ERRATA/CORRIGE. In my test script, the line

    $f = fopen(__FILE__, 'r');

should contain a directory, for example:

    $f = fopen(__DIR__, 'r');
    $f = fopen('.', 'r');
    $f = fopen('..', 'r');

Thanks to Richard Gray for signaling this bug in my report.

ADDENDUM. Under Windows Vista fopen() fails on a directory, as it should.
 [2015-03-04 01:05 UTC]
-Status: Open +Status: Feedback
 [2015-03-04 01:05 UTC]
"A Linux system, just like UNIX, makes no difference between a file and a directory, since a directory is just a file containing names of other files."

From the manual:

Note: This function may also succeed when filename is a directory. If you are unsure whether filename is a file or a directory, you may need to use the is_dir() function before calling fopen().

Are you sure this actually should be treated as a bug?
 [2015-03-05 09:25 UTC] salsi at icosaedro dot it
-Status: Feedback +Status: Open
 [2015-03-05 09:25 UTC] salsi at icosaedro dot it
Currently the libc fopen() function under Linux (and probably under any Unix-like OS) succeeds by opening a directory for reading, although nothing can be read and the EOF condition is immediately set. This is a legacy, very old behavior of the unices a modern application language as PHP is should not comply with anymore.

Under Windows the same attempt immediately fails.

My proposal is to make the PHP fopen() function behave in more consistent, cross-OS uniform and safer way by rejecting such an attempt atomically from inside PHP itself using a C code similar to this one, that detects the actual type of the opened file:

    FILE * f;
    struct stat fileinfo;

    //f = fopen(__FILE__, "r"); // works
    f = fopen("/", "r"); // --> displays "Ia a directory (PHP specific restriction)”
    //f = fopen("/root", "r"); // displays "Permission denied"
    //f = fopen("/dev/sda5", "r"); // displays "Permission denied"
    if( f == NULL ){
        printf("%s\n", strerror(errno));
        return 1;
    if( fstat(fileno(f), &fileinfo) < 0 ){
        printf("%s\n", strerror(errno));
        return 1;
    if( S_ISDIR(fileinfo.st_mode) ){
        printf("Ia a directory (PHP specific restriction)");
        return 1;
    // OK

In this way the manual page becomes simpler by removing ambiguous warnings and suggestions nobody applies anyway (never seen is_dir() after fopen() in a PHP program).

Opening a directory for writing already gives error, so there is nothing to fix here:

    $f = fopen("/", "w");
    –-> E_WARNING: fopen(/): failed to open stream: Is a directory

Changed "Bug Type" from "Bug" to "Feature/Change request", which seems more appropriate.
 [2016-10-12 16:04 UTC]
-Type: Bug +Type: Feature/Change Request
 [2016-10-12 16:04 UTC]
> Changed "Bug Type" from "Bug" to "Feature/Change request", […]

… and after previewing the comment, the bug tracker did reset to
"bug" again – annoying bug.
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Jul 18 14:01:29 2024 UTC