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 import warnings 56 warnings.warn("The posixfile module is deprecated; " 57 "fcntl.lockf() provides better locking", DeprecationWarning, 2) 58 59 class _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 (at] magnet.com to get locking to go on freebsd; 179 # additions for AIX by Vladimir.Marangozov (at] 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 220 def 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 224 def 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 # 231 SEEK_SET = 0 232 SEEK_CUR = 1 233 SEEK_END = 2 234 235 # 236 # End of posixfile.py 237 # 238