Re: file locking (was Re: fcntl example)

Jaap Vermeulen (jaap@sequent.com)
Mon, 16 May 1994 16:11:39 -0700

| Yeah! I am much in favor of a (somewhat)platform-independent implementation
| in the standard distribution. Good Work!

Thank you.

| Is posixfile in the distribution? I haven't seen it referred to before
| and I do not see it in the 1.0.1 or 1.0.2 distributions. I do have the

No. I included it at the end of this message (I posted it some time
ago). If it's useful enough Guido could pick it up?

| of interface. But sometimes it is much easier to simply do an f.readlines()
| on an open file object. The interface proposed here would allow for both.
| Please leave it in!

Posixfile is a class wrapper around the Python file object. It
implements all methods that a file object has. However, some builtin
code, such as marshal.dump(), requires the argument to be a file
object.

Of course, it would be more portable if the marshal.dump() routine just
required a fileno() method from the second object and use that for its
output. A change like that would allow posixfile or socket instances
to be passed in as well. (Guido?)

-Jaap-

--
Jaap Vermeulen					+--------------------------+
						| Sequent Computer Systems |
	Internet : jaap@sequent.com		| Beaverton, Oregon	   |
	Uucp	 : ...uunet!sequent!jaap	+--------------------------+

------- Shar archive of posixfile.py #! /bin/sh # This is a shell archive. Remove anything before this line, then feed it # into a shell via "sh file" or similar. To overwrite existing files, # type "sh file -c" # # Wrapped by <jaap@eng1> on Mon May 16 16:10:45 PDT 1994 # # This archive contains: # posixfile.py echo "If this archive is complete, you will see the following message:" echo ' "shar: End of archive."' exitcode=0 if test -f 'posixfile.py' -a "${1}" != "-c"; then echo "shar: Will not clobber existing file 'posixfile.py'" exitcode=1 else echo "shar: Extracting 'posixfile.py' (4554 characters)" sed 's/^X//' > posixfile.py << 'END_OF_FILE' X# X# Start of posixfile.py X# X X# X# Extended file operations X# X# f = posixfile.open(filename, mode) X# X# f.file() X# will return the original builtin file object X# X# f.dup() X# will return a new file object based on a new filedescriptor X# X# f.dup2(fd) X# will return a new file object based on the given filedescriptor X# X# f.flags(mode) X# will turn on the associated flag (merge) X# mode can contain the following characters: X# X# (character representing a flag) X# a append only flag X# c close on exec flag X# n no delay flag X# s synchronization flag X# (modifiers) X# ! turn flags 'off' instead of default 'on' X# = copy flags 'as is' instead of default 'merge' X# ? return a string in which the characters represent the flags X# that are set X# X# note: - the '!' and '=' modifiers are mutually exclusive. X# - the '?' modifier will return the status of the flags after they X# have been changed by other characters in the mode string X# X# f.lock(mode [, len [, start [, whence]]]) X# will (un)lock a region X# mode can contain the following characters: X# X# (character representing type of lock) X# u unlock X# r read lock X# w write lock X# (modifiers) X# | wait until the lock can be granted X# ? return the first lock conflicting with the requested lock X# or 'None' if there is no conflict. The lock returned is in the X# format (mode, len, start, whence, pid) where mode is a X# character representing the type of lock ('r' or 'w') X# X# note: - the '?' modifier prevents a region from being locked; it is X# query only X# X Xclass _posixfile_: X # X # Internal routines X # X def __repr__(self): X return repr(self._file_) X X def __del__(self): X self._file_.close() X X # X # Initialization routines X # X def open(self, name, mode): X import __builtin__ X X self._name_ = name X self._mode_ = mode X self._file_ = __builtin__.open(name, mode) X # Copy basic file methods X for method in self._file_.__methods__: X setattr(self, method, getattr(self._file_, method)) X return self X X # X # New methods X # X def file(self): X return self._file_ X X def dup(self): X import posix X X try: ignore = posix.fdopen X except: raise AttributeError, 'dup() method unavailable' X X return posix.fdopen(posix.dup(self._file_.fileno()), self._mode_) X X def dup2(self, fd): X import posix X X try: ignore = posix.fdopen X except: raise AttributeError, 'dup() method unavailable' X X posix.dup2(self._file_.fileno(), fd) X return posix.fdopen(fd, self._mode_) X X def flags(self, which): X import fcntl, FCNTL X X l_flags = 0 X if 'n' in which: l_flags = l_flags | FCNTL.O_NDELAY X if 'a' in which: l_flags = l_flags | FCNTL.O_APPEND X if 's' in which: l_flags = l_flags | FCNTL.O_SYNC X X if '=' not in which: X cur_fl = fcntl.fcntl(self._file_.fileno(), FCNTL.F_GETFL, 0) X if '!' in which: l_flags = cur_fl & ~ l_flags X else: l_flags = cur_fl | l_flags X X l_flags = fcntl.fcntl(self._file_.fileno(), FCNTL.F_SETFL, l_flags) X X if 'c' in which: X arg = ('!' not in which) # 1 is close X l_flags = fcntl.fcntl(self._file_.fileno(), FCNTL.F_SETFD, arg) X X if '?' in which: X which = '' X l_flags = fcntl.fcntl(self._file_.fileno(), FCNTL.F_GETFL, 0) X if FCNTL.O_APPEND & l_flags: which = which + 'a' X if fcntl.fcntl(self._file_.fileno(), FCNTL.F_GETFD, 0) & 1: X which = which + 'c' X if FCNTL.O_NDELAY & l_flags: which = which + 'n' X if FCNTL.O_SYNC & l_flags: which = which + 's' X return which X X def lock(self, how, *args): X import struct, fcntl, FCNTL X X if 'w' in how: l_type = FCNTL.F_WRLCK X elif 'r' in how: l_type = FCNTL.F_WRLCK X elif 'u' in how: l_type = FCNTL.F_UNLCK X else: raise TypeError, 'no type of lock specified' X X if '|' in how: cmd = FCNTL.F_SETLKW X elif '?' in how: cmd = FCNTL.F_GETLK X else: cmd = FCNTL.F_SETLK X X l_whence = 0 X l_start = 0 X l_len = 0 X X if len(args) == 1: X l_len = args[0] X elif len(args) == 2: X l_len, l_start = args X elif len(args) == 3: X l_len, l_start, l_whence = args X elif len(args) > 3: X raise TypeError, 'too many arguments' X X flock = struct.pack('hhllhh', l_type, l_whence, l_start, l_len, 0, 0) X flock = fcntl.fcntl(self._file_.fileno(), cmd, flock) X X if '?' in how: X l_type, l_whence, l_start, l_len, l_sysid, l_pid = \ X struct.unpack('hhllhh', flock) X if l_type != FCNTL.F_UNLCK: X if l_type == FCNTL.F_RDLCK: X return 'r', l_len, l_start, l_whence, l_pid X else: X return 'w', l_len, l_start, l_whence, l_pid X X# X# Public routine to obtain a posixfile object X# Xdef open(name, mode): X return _posixfile_().open(name, mode) X X# X# End of posixfile.py X# END_OF_FILE if test 4554 -ne `wc -c < 'posixfile.py'`; then echo "shar: 'posixfile.py' unpacked with wrong size!" exitcode=1 fi # end of 'posixfile.py' fi echo "End of archive." exit $exitcode