Skip to content
Snippets Groups Projects
Select Git revision
  • a2215124bb8cc8744f1a81dc9dcb776184161195
  • master default protected
  • pymilter-1.0.4
  • pymilter-1.0.3
  • pymilter-1.0.2
  • pymilter-1.0.1
  • pymilter-1_0
  • milter-0_8_18
  • pymilter-0_9_8
  • pymilter-0_9_7
  • pymilter-0_9_6
  • pymilter-0_9_5
  • pymilter-0_9_4
  • pymilter-0_9_2
  • pymilter-0_9_1
  • pymilter-0_9_0
  • pymilter-0_8_12
  • pymilter-0_8_11
  • pymilter-0_8_10
  • pymilter-0_8_9
  • milter-0_8_8
  • milter-0_8_7
22 results

plock.py

Blame
  • plock.py 1.70 KiB
    # Author: Stuart D. Gathman <stuart@bmsi.com>
    # Copyright 2001 Business Management Systems, Inc.
    # This code is under the GNU General Public License.  See COPYING for details.
    
    import os
    from time import sleep
    
    class PLock(object):
      "A simple /etc/passwd style lock,update,rename protocol for updating files."
      def __init__(self,basename):
        self.basename = basename
        self.fp = None
    
      def lock(self,lockname=None,mode=0660,strict_perms=False):
        "Start an update transaction.  Return FILE to write new version."
        self.unlock()
        if not lockname:
          lockname = self.basename + '.lock'
        self.lockname = lockname
        try:
          st = os.stat(self.basename)
          mode |= st.st_mode
        except OSError: pass
        u = os.umask(0002)
        try:
          fd = os.open(lockname,os.O_WRONLY+os.O_CREAT+os.O_EXCL,mode)
        finally:
          os.umask(u)
        self.fp = os.fdopen(fd,'w')
        try:
          os.chown(self.lockname,-1,st.st_gid)
        except:
          if strict_perms:
    	self.unlock()
    	raise
        return self.fp
    
      def wlock(self,lockname=None):
        "Wait until lock is free, then start an update transaction."
        while True:
          try:
            return self.lock(lockname)
          except OSError:
            sleep(2)
    
      def commit(self,backname=None):
        "Commit update transaction with optional backup file."
        if not self.fp:
          raise IOError,"File not locked"
        self.fp.close()
        self.fp = None
        if backname:
          try:
    	os.remove(backname)
          except OSError: pass
          os.link(self.basename,backname)
        os.rename(self.lockname,self.basename)
    
      def unlock(self):
        "Cancel update transaction."
        if self.fp:
          try:
            self.fp.close()
          except: pass
          self.fp = None
          os.remove(self.lockname)