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