python-2.5.2/win32/Lib/posixfile.py
changeset 0 ae805ac0140d
equal deleted inserted replaced
-1:000000000000 0:ae805ac0140d
       
     1 """Extended file operations available in POSIX.
       
     2 
       
     3 f = posixfile.open(filename, [mode, [bufsize]])
       
     4       will create a new posixfile object
       
     5 
       
     6 f = posixfile.fileopen(fileobject)
       
     7       will create a posixfile object from a builtin file object
       
     8 
       
     9 f.file()
       
    10       will return the original builtin file object
       
    11 
       
    12 f.dup()
       
    13       will return a new file object based on a new filedescriptor
       
    14 
       
    15 f.dup2(fd)
       
    16       will return a new file object based on the given filedescriptor
       
    17 
       
    18 f.flags(mode)
       
    19       will turn on the associated flag (merge)
       
    20       mode can contain the following characters:
       
    21 
       
    22   (character representing a flag)
       
    23       a       append only flag
       
    24       c       close on exec flag
       
    25       n       no delay flag
       
    26       s       synchronization flag
       
    27   (modifiers)
       
    28       !       turn flags 'off' instead of default 'on'
       
    29       =       copy flags 'as is' instead of default 'merge'
       
    30       ?       return a string in which the characters represent the flags
       
    31               that are set
       
    32 
       
    33       note: - the '!' and '=' modifiers are mutually exclusive.
       
    34             - the '?' modifier will return the status of the flags after they
       
    35               have been changed by other characters in the mode string
       
    36 
       
    37 f.lock(mode [, len [, start [, whence]]])
       
    38       will (un)lock a region
       
    39       mode can contain the following characters:
       
    40 
       
    41   (character representing type of lock)
       
    42       u       unlock
       
    43       r       read lock
       
    44       w       write lock
       
    45   (modifiers)
       
    46       |       wait until the lock can be granted
       
    47       ?       return the first lock conflicting with the requested lock
       
    48               or 'None' if there is no conflict. The lock returned is in the
       
    49               format (mode, len, start, whence, pid) where mode is a
       
    50               character representing the type of lock ('r' or 'w')
       
    51 
       
    52       note: - the '?' modifier prevents a region from being locked; it is
       
    53               query only
       
    54 """
       
    55 
       
    56 
       
    57 class _posixfile_:
       
    58     """File wrapper class that provides extra POSIX file routines."""
       
    59 
       
    60     states = ['open', 'closed']
       
    61 
       
    62     #
       
    63     # Internal routines
       
    64     #
       
    65     def __repr__(self):
       
    66         file = self._file_
       
    67         return "<%s posixfile '%s', mode '%s' at %s>" % \
       
    68                 (self.states[file.closed], file.name, file.mode, \
       
    69                  hex(id(self))[2:])
       
    70 
       
    71     #
       
    72     # Initialization routines
       
    73     #
       
    74     def open(self, name, mode='r', bufsize=-1):
       
    75         import __builtin__
       
    76         return self.fileopen(__builtin__.open(name, mode, bufsize))
       
    77 
       
    78     def fileopen(self, file):
       
    79         import types
       
    80         if repr(type(file)) != "<type 'file'>":
       
    81             raise TypeError, 'posixfile.fileopen() arg must be file object'
       
    82         self._file_  = file
       
    83         # Copy basic file methods
       
    84         for maybemethod in dir(file):
       
    85             if not maybemethod.startswith('_'):
       
    86                 attr = getattr(file, maybemethod)
       
    87                 if isinstance(attr, types.BuiltinMethodType):
       
    88                     setattr(self, maybemethod, attr)
       
    89         return self
       
    90 
       
    91     #
       
    92     # New methods
       
    93     #
       
    94     def file(self):
       
    95         return self._file_
       
    96 
       
    97     def dup(self):
       
    98         import posix
       
    99 
       
   100         if not hasattr(posix, 'fdopen'):
       
   101             raise AttributeError, 'dup() method unavailable'
       
   102 
       
   103         return posix.fdopen(posix.dup(self._file_.fileno()), self._file_.mode)
       
   104 
       
   105     def dup2(self, fd):
       
   106         import posix
       
   107 
       
   108         if not hasattr(posix, 'fdopen'):
       
   109             raise AttributeError, 'dup() method unavailable'
       
   110 
       
   111         posix.dup2(self._file_.fileno(), fd)
       
   112         return posix.fdopen(fd, self._file_.mode)
       
   113 
       
   114     def flags(self, *which):
       
   115         import fcntl, os
       
   116 
       
   117         if which:
       
   118             if len(which) > 1:
       
   119                 raise TypeError, 'Too many arguments'
       
   120             which = which[0]
       
   121         else: which = '?'
       
   122 
       
   123         l_flags = 0
       
   124         if 'n' in which: l_flags = l_flags | os.O_NDELAY
       
   125         if 'a' in which: l_flags = l_flags | os.O_APPEND
       
   126         if 's' in which: l_flags = l_flags | os.O_SYNC
       
   127 
       
   128         file = self._file_
       
   129 
       
   130         if '=' not in which:
       
   131             cur_fl = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0)
       
   132             if '!' in which: l_flags = cur_fl & ~ l_flags
       
   133             else: l_flags = cur_fl | l_flags
       
   134 
       
   135         l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFL, l_flags)
       
   136 
       
   137         if 'c' in which:
       
   138             arg = ('!' not in which)    # 0 is don't, 1 is do close on exec
       
   139             l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFD, arg)
       
   140 
       
   141         if '?' in which:
       
   142             which = ''                  # Return current flags
       
   143             l_flags = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0)
       
   144             if os.O_APPEND & l_flags: which = which + 'a'
       
   145             if fcntl.fcntl(file.fileno(), fcntl.F_GETFD, 0) & 1:
       
   146                 which = which + 'c'
       
   147             if os.O_NDELAY & l_flags: which = which + 'n'
       
   148             if os.O_SYNC & l_flags: which = which + 's'
       
   149             return which
       
   150 
       
   151     def lock(self, how, *args):
       
   152         import struct, fcntl
       
   153 
       
   154         if 'w' in how: l_type = fcntl.F_WRLCK
       
   155         elif 'r' in how: l_type = fcntl.F_RDLCK
       
   156         elif 'u' in how: l_type = fcntl.F_UNLCK
       
   157         else: raise TypeError, 'no type of lock specified'
       
   158 
       
   159         if '|' in how: cmd = fcntl.F_SETLKW
       
   160         elif '?' in how: cmd = fcntl.F_GETLK
       
   161         else: cmd = fcntl.F_SETLK
       
   162 
       
   163         l_whence = 0
       
   164         l_start = 0
       
   165         l_len = 0
       
   166 
       
   167         if len(args) == 1:
       
   168             l_len = args[0]
       
   169         elif len(args) == 2:
       
   170             l_len, l_start = args
       
   171         elif len(args) == 3:
       
   172             l_len, l_start, l_whence = args
       
   173         elif len(args) > 3:
       
   174             raise TypeError, 'too many arguments'
       
   175 
       
   176         # Hack by davem@magnet.com to get locking to go on freebsd;
       
   177         # additions for AIX by Vladimir.Marangozov@imag.fr
       
   178         import sys, os
       
   179         if sys.platform in ('netbsd1',
       
   180                             'openbsd2',
       
   181                             'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
       
   182                             'freebsd6', 'freebsd7',
       
   183                             'bsdos2', 'bsdos3', 'bsdos4'):
       
   184             flock = struct.pack('lxxxxlxxxxlhh', \
       
   185                   l_start, l_len, os.getpid(), l_type, l_whence)
       
   186         elif sys.platform in ('aix3', 'aix4'):
       
   187             flock = struct.pack('hhlllii', \
       
   188                   l_type, l_whence, l_start, l_len, 0, 0, 0)
       
   189         else:
       
   190             flock = struct.pack('hhllhh', \
       
   191                   l_type, l_whence, l_start, l_len, 0, 0)
       
   192 
       
   193         flock = fcntl.fcntl(self._file_.fileno(), cmd, flock)
       
   194 
       
   195         if '?' in how:
       
   196             if sys.platform in ('netbsd1',
       
   197                                 'openbsd2',
       
   198                                 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
       
   199                                 'bsdos2', 'bsdos3', 'bsdos4'):
       
   200                 l_start, l_len, l_pid, l_type, l_whence = \
       
   201                     struct.unpack('lxxxxlxxxxlhh', flock)
       
   202             elif sys.platform in ('aix3', 'aix4'):
       
   203                 l_type, l_whence, l_start, l_len, l_sysid, l_pid, l_vfs = \
       
   204                     struct.unpack('hhlllii', flock)
       
   205             elif sys.platform == "linux2":
       
   206                 l_type, l_whence, l_start, l_len, l_pid, l_sysid = \
       
   207                     struct.unpack('hhllhh', flock)
       
   208             else:
       
   209                 l_type, l_whence, l_start, l_len, l_sysid, l_pid = \
       
   210                     struct.unpack('hhllhh', flock)
       
   211 
       
   212             if l_type != fcntl.F_UNLCK:
       
   213                 if l_type == fcntl.F_RDLCK:
       
   214                     return 'r', l_len, l_start, l_whence, l_pid
       
   215                 else:
       
   216                     return 'w', l_len, l_start, l_whence, l_pid
       
   217 
       
   218 def open(name, mode='r', bufsize=-1):
       
   219     """Public routine to open a file as a posixfile object."""
       
   220     return _posixfile_().open(name, mode, bufsize)
       
   221 
       
   222 def fileopen(file):
       
   223     """Public routine to get a posixfile object from a Python file object."""
       
   224     return _posixfile_().fileopen(file)
       
   225 
       
   226 #
       
   227 # Constants
       
   228 #
       
   229 SEEK_SET = 0
       
   230 SEEK_CUR = 1
       
   231 SEEK_END = 2
       
   232 
       
   233 #
       
   234 # End of posixfile.py
       
   235 #