PageRenderTime 29ms CodeModel.GetById 14ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/Lib/posixfile.py

http://unladen-swallow.googlecode.com/
Python | 237 lines | 209 code | 1 blank | 27 comment | 2 complexity | aa549d3066e1ed38264c0478a78fbc1a MD5 | raw file
  1"""Extended file operations available in POSIX.
  2
  3f = posixfile.open(filename, [mode, [bufsize]])
  4      will create a new posixfile object
  5
  6f = posixfile.fileopen(fileobject)
  7      will create a posixfile object from a builtin file object
  8
  9f.file()
 10      will return the original builtin file object
 11
 12f.dup()
 13      will return a new file object based on a new filedescriptor
 14
 15f.dup2(fd)
 16      will return a new file object based on the given filedescriptor
 17
 18f.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
 37f.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"""
 55import warnings
 56warnings.warn("The posixfile module is deprecated; "
 57                "fcntl.lockf() provides better locking", DeprecationWarning, 2)
 58
 59class _posixfile_:
 60    """File wrapper class that provides extra POSIX file routines."""
 61
 62    states = ['open', 'closed']
 63
 64    #
 65    # Internal routines
 66    #
 67    def __repr__(self):
 68        file = self._file_
 69        return "<%s posixfile '%s', mode '%s' at %s>" % \
 70                (self.states[file.closed], file.name, file.mode, \
 71                 hex(id(self))[2:])
 72
 73    #
 74    # Initialization routines
 75    #
 76    def open(self, name, mode='r', bufsize=-1):
 77        import __builtin__
 78        return self.fileopen(__builtin__.open(name, mode, bufsize))
 79
 80    def fileopen(self, file):
 81        import types
 82        if repr(type(file)) != "<type 'file'>":
 83            raise TypeError, 'posixfile.fileopen() arg must be file object'
 84        self._file_  = file
 85        # Copy basic file methods
 86        for maybemethod in dir(file):
 87            if not maybemethod.startswith('_'):
 88                attr = getattr(file, maybemethod)
 89                if isinstance(attr, types.BuiltinMethodType):
 90                    setattr(self, maybemethod, attr)
 91        return self
 92
 93    #
 94    # New methods
 95    #
 96    def file(self):
 97        return self._file_
 98
 99    def dup(self):
100        import posix
101
102        if not hasattr(posix, 'fdopen'):
103            raise AttributeError, 'dup() method unavailable'
104
105        return posix.fdopen(posix.dup(self._file_.fileno()), self._file_.mode)
106
107    def dup2(self, fd):
108        import posix
109
110        if not hasattr(posix, 'fdopen'):
111            raise AttributeError, 'dup() method unavailable'
112
113        posix.dup2(self._file_.fileno(), fd)
114        return posix.fdopen(fd, self._file_.mode)
115
116    def flags(self, *which):
117        import fcntl, os
118
119        if which:
120            if len(which) > 1:
121                raise TypeError, 'Too many arguments'
122            which = which[0]
123        else: which = '?'
124
125        l_flags = 0
126        if 'n' in which: l_flags = l_flags | os.O_NDELAY
127        if 'a' in which: l_flags = l_flags | os.O_APPEND
128        if 's' in which: l_flags = l_flags | os.O_SYNC
129
130        file = self._file_
131
132        if '=' not in which:
133            cur_fl = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0)
134            if '!' in which: l_flags = cur_fl & ~ l_flags
135            else: l_flags = cur_fl | l_flags
136
137        l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFL, l_flags)
138
139        if 'c' in which:
140            arg = ('!' not in which)    # 0 is don't, 1 is do close on exec
141            l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFD, arg)
142
143        if '?' in which:
144            which = ''                  # Return current flags
145            l_flags = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0)
146            if os.O_APPEND & l_flags: which = which + 'a'
147            if fcntl.fcntl(file.fileno(), fcntl.F_GETFD, 0) & 1:
148                which = which + 'c'
149            if os.O_NDELAY & l_flags: which = which + 'n'
150            if os.O_SYNC & l_flags: which = which + 's'
151            return which
152
153    def lock(self, how, *args):
154        import struct, fcntl
155
156        if 'w' in how: l_type = fcntl.F_WRLCK
157        elif 'r' in how: l_type = fcntl.F_RDLCK
158        elif 'u' in how: l_type = fcntl.F_UNLCK
159        else: raise TypeError, 'no type of lock specified'
160
161        if '|' in how: cmd = fcntl.F_SETLKW
162        elif '?' in how: cmd = fcntl.F_GETLK
163        else: cmd = fcntl.F_SETLK
164
165        l_whence = 0
166        l_start = 0
167        l_len = 0
168
169        if len(args) == 1:
170            l_len = args[0]
171        elif len(args) == 2:
172            l_len, l_start = args
173        elif len(args) == 3:
174            l_len, l_start, l_whence = args
175        elif len(args) > 3:
176            raise TypeError, 'too many arguments'
177
178        # Hack by davem@magnet.com to get locking to go on freebsd;
179        # additions for AIX by Vladimir.Marangozov@imag.fr
180        import sys, os
181        if sys.platform in ('netbsd1',
182                            'openbsd2',
183                            'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
184                            'freebsd6', 'freebsd7', 'freebsd8',
185                            'bsdos2', 'bsdos3', 'bsdos4'):
186            flock = struct.pack('lxxxxlxxxxlhh', \
187                  l_start, l_len, os.getpid(), l_type, l_whence)
188        elif sys.platform in ('aix3', 'aix4'):
189            flock = struct.pack('hhlllii', \
190                  l_type, l_whence, l_start, l_len, 0, 0, 0)
191        else:
192            flock = struct.pack('hhllhh', \
193                  l_type, l_whence, l_start, l_len, 0, 0)
194
195        flock = fcntl.fcntl(self._file_.fileno(), cmd, flock)
196
197        if '?' in how:
198            if sys.platform in ('netbsd1',
199                                'openbsd2',
200                                'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
201                                'bsdos2', 'bsdos3', 'bsdos4'):
202                l_start, l_len, l_pid, l_type, l_whence = \
203                    struct.unpack('lxxxxlxxxxlhh', flock)
204            elif sys.platform in ('aix3', 'aix4'):
205                l_type, l_whence, l_start, l_len, l_sysid, l_pid, l_vfs = \
206                    struct.unpack('hhlllii', flock)
207            elif sys.platform == "linux2":
208                l_type, l_whence, l_start, l_len, l_pid, l_sysid = \
209                    struct.unpack('hhllhh', flock)
210            else:
211                l_type, l_whence, l_start, l_len, l_sysid, l_pid = \
212                    struct.unpack('hhllhh', flock)
213
214            if l_type != fcntl.F_UNLCK:
215                if l_type == fcntl.F_RDLCK:
216                    return 'r', l_len, l_start, l_whence, l_pid
217                else:
218                    return 'w', l_len, l_start, l_whence, l_pid
219
220def open(name, mode='r', bufsize=-1):
221    """Public routine to open a file as a posixfile object."""
222    return _posixfile_().open(name, mode, bufsize)
223
224def fileopen(file):
225    """Public routine to get a posixfile object from a Python file object."""
226    return _posixfile_().fileopen(file)
227
228#
229# Constants
230#
231SEEK_SET = 0
232SEEK_CUR = 1
233SEEK_END = 2
234
235#
236# End of posixfile.py
237#