Location: PHPKode > scripts > Database Abstraction Layer > database-abstraction-layer/dbal/safeIO.php
<?php
/*
***************************************************************************
*   Copyright (C) 2007 by Cesar D. Rodas                                  *
*   hide@address.com                                                     *
*                                                                         *
*   Permission is hereby granted, free of charge, to any person obtaining *
*   a copy of this software and associated documentation files (the       *
*   "Software"), to deal in the Software without restriction, including   *
*   without limitation the rights to use, copy, modify, merge, publish,   *
*   distribute, sublicense, and/or sell copies of the Software, and to    *
*   permit persons to whom the Software is furnished to do so, subject to *
*   the following conditions:                                             *
*                                                                         *
*   The above copyright notice and this permission notice shall be        *
*   included in all copies or substantial portions of the Software.       *
*                                                                         *
*   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       *
*   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    *
*   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
*   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR     *
*   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
*   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
*   OTHER DEALINGS IN THE SOFTWARE.                                       *
***************************************************************************
*/
define ('UNLOCK',0);
define ('SHARED',2);
define ('EXCLUSIVE',4);

define('MAX_LOCK_TRY',5);

define('READ',2);
define('APPEND',4);
define('WRITE',5);

class safeIO {
    var $stat;
    
    /* Private vars */
    var $fbased;
    var $Lock;
    var $fp;
    var $filename;
    
    function safeIO() {
        $this->fbased = $this->isRunningOsWin();
        register_shutdown_function("on_exit");
    }
    
    function read($offset) {
        return fread($this->fp, $offset);
    }
    
    function write($str, $length) {
        return fwrite($this->fp, $str, $length);
    }
    
    function seek($offset,$where) {
        return fseek($this->fp,$offset,$where);
    }    
    
    function open($file,$method) {
        $this->filename = $file;
        
        switch ($method) {
            case READ:
                if ( !file_exists($file) )     
                    return false;
                
                $this->fp = fopen($file,"rb");
                if (! $this->sharedLock() ) {
                    $this->close();
                    return false;
                }
                break;
            case APPEND:        
                $this->fp = fopen($file,"ab");
                if (! $this->exclusiveLock() ) {
                    $this->close();
                    return false;
                }
                break;
            case WRITE:
                $this->fp = fopen($file,"ab");
                if (! $this->exclusiveLock() ) {
                    $this->close();
                    return false;
                }
                $this->seek(0,SEEK_SET);
                clearstatcache(); //clean stat cache, important!
                ftruncate($this->fp,0); //truncated
                break;
        }
        $this->stat =  fstat($this->fp);
        return true;
    }
    
    function close() {
        $this->unlock();
        fclose($this->fp);
    }
    
    function exclusiveLock() {
        $i=0;
        while ( !($r=$this->_exclusiveLock()) && $i++ < MAX_LOCK_TRY)
            sleep(1);
        return $r;
    }
    
    function sharedLock() {
        $i=0;
        while ( !($r=$this->_sharedLock()) && $i++ < MAX_LOCK_TRY)
            sleep(1);
        return $r;
    }
    
    
    function isRunningOsWin() {
        return strpos(strtolower(php_uname()),"windows") !== false;
    }
    
    function unlock() {
        if ($this->fbased)
            unlink($this->Lock);
        else
            flock($this->fp,LOCK_UN);
    }
    
    function _sharedLock() {
        global $safeIOLocks;
        if ($this->fbased) {
            if ($this->getLockStatus() == EXCLUSIVE) return false;
            $path = $this->GetNewLockName("read");
            $safeIOLocks[] = $path; /* saves for the end app callback function */
            $this->Lock = $path;
            $fp = fopen($path,"wb");
            $this->FileExistsOrDie($path);
            fclose($fp);
            return true;
        } else return flock($this->fp,LOCK_SH);
    }
    
    function _exclusiveLock() {
        global $safeIOLocks;
        if ($this->fbased) {
            if ($this->getLockStatus() != UNLOCK) return false;        
            $path = $this->GetNewLockName("write");
            $safeIOLocks[] = $path;
            $this->Lock = $path;
            $fp = fopen($path,"wb");
            $this->FileExistsOrDie($path);
            fclose($fp);
            return true;        
        } else return flock($this->fp,LOCK_EX);
    }
    
    function getLockStatus() {
        $r = UNLOCK;
        $path = $this->filename;
        clearstatcache();
        if  (is_file("${path}.*.write"))
            $r = EXCLUSIVE;
        else if  (is_file("${path}.*.read"))
            $r = SHARED;

        return $r;
    }
    
    /*
     *  Generate a new name for the lock file.
     */
    function GetNewLockName($type) {
        $rnd = str_replace(".","",(time()+microtime()));
        return $this->filename.".".$rnd.".${type}";
    }
    
    function  FileExistsOrDie($path) {
        if (!is_file($path)) 
            die("$path couldn't be created!, please see if PHP has write permissions for this file");
    }
    
}
function on_exit() {
	safeIOCleaner();
}

function safeIOCleaner() {
    global $safeIOLocks;
    if (!is_array($safeIOLocks))
        return;
    foreach($safeIOLocks as $value) {
        @unlink($value);
    }
    unset($safeIOLocks);
}
Return current item: Database Abstraction Layer