From:             
Operating system: 
PHP version:      trunk-SVN-2011-01-31 (SVN)
Package:          Filesystem function related
Bug Type:         Bug
Bug description:ftruncate() does not work with user-defined stream wrappers

Description:
------------
Hey :-),



Seems like ftruncate() does not reconized an user-defined stream (with
stream wrapper) as a valid stream. When we use it, it raises the following
error: “Can't truncate this stream!”. All the related subject about
this error on the Web talks about stream wrappers. Thus, it's seem to be
the real problem.

Test script:
---------------
<?php



class StreamWrapper {



    private $_stream     = null;

    private $_streamName = null;

    public  $context     = null;



    public static function realPath ( $path ) {



        return substr($path, 6);

    }



    public function stream_close ( ) {



        if(true === @fclose($this->getStream())) {



            $this->_stream     = null;

            $this->_streamName = null;

        }



        return;

    }



    public function stream_eof ( ) {



        return feof($this->getStream());

    }



    public function stream_flush ( ) {



        return fflush($this->getStream());

    }



    public function stream_lock ( $operation ) {



        return flock($this->getStream(), $operation);

    }



    public function stream_open ( $path, $mode, $options, &$openedPath ) {



        $p = self::realPath($path);



        if(false === $p)

            return false;



        if(null === $this->context)

            $openedPath = fopen(

                $p,

                $mode,

                $options & STREAM_USE_PATH

            );

        else

            $openedPath = fopen(

                $p,

                $mode,

                $options & STREAM_USE_PATH,

                $this->context

            );



        $this->_stream     = $openedPath;

        $this->_streamName = $p;



        return true;

    }



    public function stream_read ( $count ) {



        return fread($this->getStream(), $count);

    }



    public function stream_seek ( $offset, $whence = SEEK_SET ) {



        return fseek($this->getStream(), $offset, $whence);

    }



    public function stream_stat ( ) {



        return fstat($this->getStream());

    }



    public function stream_tell ( ) {



        return ftell($this->getStream());

    }



    public function stream_write ( $data ) {



        return fwrite($this->getStream(), $data);

    }



    public function dir_closedir ( ) {



        if(true === $handle = @closedir($this->getStream())) {



            $this->_stream     = null;

            $this->_streamName = null;

        }



        return $handle;

    }



    public function dir_opendir ( $path, $options ) {



        $p      = self::realPath($path);

        $handle = null;



        if(null === $this->context)

            $handle = @opendir($p);

        else

            $handle = @opendir($p, $this->context);



        if(false === $handle)

            return false;



        $this->_stream     = $handle;

        $this->_streamName = $p;



        return true;

    }



    public function dir_readdir ( ) {



        return readdir($this->getStream());

    }



    public function dir_rewinddir ( ) {



        return rewinddir($this->getStream());

    }



    public function mkdir ( $path, $mode, $options ) {



        if(null === $this->context)

            return mkdir(

                self::realPath($path),

                $mode,

                $options | STREAM_MKDIR_RECURSIVE

            );



        return mkdir(

            self::realPath($path),

            $mode,

            $options | STREAM_MKDIR_RECURSIVE,

            $this->context

        );

    }



    public function rename ( $from, $to ) {



        if(null === $this->context)

            return rename(self::realPath($from), self::realPath($to));



        return rename(self::realPath($from), self::realPath($to),
$this->context);

    }



    public function rmdir ( $path, $options ) {



        if(null === $this->context)

            return rmdir(self::realPath($path));

        

        return rmdir(self::realPath($path), $this->context);

    }



    public function unlink ( $path ) {



        if(null === $this->context)

            return unlink(self::realPath($path));



        return unlink(self::realPath($path), $this->context);

    }



    public function url_stat ( $path, $flags ) {



        if(false === $p = self::realPath($path))

            if($flags & STREAM_URL_STAT_QUIET)

                return array(); // Not sure…

            else

                return trigger_error(

                    'Path ' . $path . ' cannot be resolved.',

                    E_WARNING

                );



        if($flags & STREAM_URL_STAT_LINK)

            return @lstat($p);



        return @stat($p);

    }



    protected function getStream ( ) {



        return $this->_stream;

    }



    protected function getStreamName ( ) {



        return $this->_streamName;

    }

}



stream_wrapper_register('bug', 'StreamWrapper');





var_dump($fd = fopen('bug://Test.txt', 'w+'));



var_dump(fwrite($fd,    'Foobar1' . "\n"));

var_dump(fwrite($fd,    'Foobar2' . "\n"));

var_dump(fwrite($fd,    'Foobar3' . "\n"));

var_dump(ftruncate($fd, 3));



var_dump(fclose($fd));

Expected result:
----------------
Output:



resource(7) of type (stream)

int(8)

int(8)

int(8)

bool(true)

bool(true)



Test.txt:

Foo

Actual result:
--------------
Output:



resource(7) of type (stream)

int(8)

int(8)

int(8)

PHP Warning:  ftruncate(): Can't truncate this stream! in
/Users/hywan/Development/Hoa/Laboratory/Bug/StreamWrapper.php on line 210



Warning: ftruncate(): Can't truncate this stream! in
/Users/hywan/Development/Hoa/Laboratory/Bug/StreamWrapper.php on line 210

bool(false)

bool(true)



Test.txt:

Foobar1

Foobar2

Foobar3

-- 
Edit bug report at http://bugs.php.net/bug.php?id=53888&edit=1
-- 
Try a snapshot (PHP 5.2):            
http://bugs.php.net/fix.php?id=53888&r=trysnapshot52
Try a snapshot (PHP 5.3):            
http://bugs.php.net/fix.php?id=53888&r=trysnapshot53
Try a snapshot (trunk):              
http://bugs.php.net/fix.php?id=53888&r=trysnapshottrunk
Fixed in SVN:                        
http://bugs.php.net/fix.php?id=53888&r=fixed
Fixed in SVN and need be documented: 
http://bugs.php.net/fix.php?id=53888&r=needdocs
Fixed in release:                    
http://bugs.php.net/fix.php?id=53888&r=alreadyfixed
Need backtrace:                      
http://bugs.php.net/fix.php?id=53888&r=needtrace
Need Reproduce Script:               
http://bugs.php.net/fix.php?id=53888&r=needscript
Try newer version:                   
http://bugs.php.net/fix.php?id=53888&r=oldversion
Not developer issue:                 
http://bugs.php.net/fix.php?id=53888&r=support
Expected behavior:                   
http://bugs.php.net/fix.php?id=53888&r=notwrong
Not enough info:                     
http://bugs.php.net/fix.php?id=53888&r=notenoughinfo
Submitted twice:                     
http://bugs.php.net/fix.php?id=53888&r=submittedtwice
register_globals:                    
http://bugs.php.net/fix.php?id=53888&r=globals
PHP 4 support discontinued:          http://bugs.php.net/fix.php?id=53888&r=php4
Daylight Savings:                    http://bugs.php.net/fix.php?id=53888&r=dst
IIS Stability:                       
http://bugs.php.net/fix.php?id=53888&r=isapi
Install GNU Sed:                     
http://bugs.php.net/fix.php?id=53888&r=gnused
Floating point limitations:          
http://bugs.php.net/fix.php?id=53888&r=float
No Zend Extensions:                  
http://bugs.php.net/fix.php?id=53888&r=nozend
MySQL Configuration Error:           
http://bugs.php.net/fix.php?id=53888&r=mysqlcfg

Reply via email to