--- a/Unix.st Sat Jul 27 14:20:46 1996 +0200
+++ b/Unix.st Sat Jul 27 15:19:56 1996 +0200
@@ -3524,13 +3524,19 @@
!OperatingSystem class methodsFor:'file locking'!
-lockFD:aFileDescriptor blocking:blockIfLocked
- "set an advisory lock on the file represented by aFileDescriptor.
+lockFD:aFileDescriptor shared:isSharedReadLock blocking:blockIfLocked
+ "set a lock on the file represented by aFileDescriptor.
(such as returned by ExternalStream>>fileDescriptor).
- An advisory lock depends on other accessors to also perform
- the locking operation - if they do not, they can still access the
- file.
+ On some systems, only advisory locks are available -
+ these depends on other accessors to also perform the locking operation.
+ If they do not, they may still access the file
+ (on some systems, locks are mandatory, on others, they are advisory).
+ The isSharedReadLock argument (if true) specifies if multiple readers
+ are to be allowed - if false, they are not.
+ On some systems, all locks are non-exclusive locks.
+
Returns true, if the lock was aquired, false otherwise.
+
Notice, that not all OS's support these locks;
on some, this may simply be a no-op.
Also notice, that some systems block the process, to wait for the lock.
@@ -3542,23 +3548,67 @@
int fd = __intVal(aFileDescriptor);
int lockArg;
-#if defined(LOCK_EX) && defined(LOCK_UN)
- /* BSD 4.3 advisory locks */
+ /*
+ * claus: sigh - each one has a different interface ...
+ */
+#if defined(F_SETLK)
+ {
+ /*
+ * new fcntl(SETLK) interface;
+ * available on SYSV4 and Linux
+ */
+ struct flock flock;
+
+ if (isSharedReadLock == true) {
+ flock.l_type = F_RDLCK;
+ } else {
+ flock.l_type = F_WRLCK;
+ }
+ flock.l_whence = 0;
+ flock.l_start = 0;
+ flock.l_len = 0;
+ lockArg = F_SETLK;
+# if defined(F_SETLKW)
+ if (blockIfLocked == true) {
+ lockArg = F_SETLKW;
+ }
+# endif
+ if (fcntl(fd, lockArg, &flock) != -1) {
+ RETURN (true);
+ }
+ }
+
+#else /* no F_SETLK available */
+
+# if defined(LOCK_EX) && defined(LOCK_UN)
+ /*
+ * BSD 4.3 advisory locks
+ */
lockArg = LOCK_EX;
-# if defined(LOCK_NB)
+# if defined(LOCK_SH)
+ if (isSharedReadLock == true) {
+ lockArg = LOCK_SH
+ }
+# endif
+# if defined(LOCK_NB)
if (blockIfLocked == false) {
lockArg |= LOCK_NB;
}
-# endif
+# endif
if (flock(fd, lockArg) != -1) {
RETURN (true);
}
-#else
-# if defined(F_LOCK) && defined(F_UNLOCK)
- /* SYSV3 advisory locks */
+
+# else /* no flock available */
+
+# if defined(F_LOCK) && defined(F_UNLOCK)
+ /*
+ * SYSV3 advisory locks
+ */
if (lockf(fd, F_LOCK, 0) != -1) {
RETURN (true);
}
+# endif
# endif
#endif
}
@@ -3567,28 +3617,58 @@
!
unlockFD:aFileDescriptor
- "clear an advisory lock on the file represented by aFileDescriptor,
- which was previously aquired by #advisoryLockFD:.
- Return false, if the unlock failed (which only happens when a wrong
- fd is passed).
- Notice, that not all OS's support these locks;
+ "clear a file lock on the file represented by aFileDescriptor,
+ which was previously aquired by #lockFD:.
+ Return false, if the unlock failed
+ (which may happens when a wrong fd is passed,
+ no lock was set previously, or the systsem does not support locks).
+ Notice, that not all OS's support file locks;
on some, this may simply be a no-op."
%{
if (__isSmallInteger(aFileDescriptor)) {
int fd = __intVal(aFileDescriptor);
-#if defined(LOCK_EX) && defined(LOCK_UN)
- /* BSD 4.3 advisory locks */
+ /*
+ * claus: sigh - each one has a different interface ...
+ */
+#if defined(F_SETLK)
+ {
+ /*
+ * new fcntl(SETLK) interface;
+ * available on SYSV4 and Linux
+ */
+ struct flock flock;
+
+ flock.l_type = F_UNLCK;
+ flock.l_whence = 0;
+ flock.l_start = 0;
+ flock.l_len = 0;
+ if (fcntl(fd, F_SETLK, &flock) != -1) {
+ RETURN (true);
+ }
+ }
+
+#else /* no F_SETLK available */
+
+# if defined(LOCK_EX) && defined(LOCK_UN)
+ /*
+ * BSD 4.3 advisory locks
+ */
if (flock(fd, LOCK_UN) != -1) {
RETURN (true);
}
-#else
-# if defined(F_LOCK) && defined(F_UNLOCK)
- /* SYSV3 advisory locks */
+
+# else /* no flock available */
+
+# if defined(F_LOCK) && defined(F_UNLOCK)
+ /*
+ * SYSV3 advisory locks
+ */
if (lockf(fd, F_UNLOCK, 0) != -1) {
RETURN (true);
}
+# endif
# endif
#endif
}
@@ -3597,14 +3677,18 @@
!
supportsFileLocks
- "return true, if the OS supports advisory file locking"
+ "return true, if the OS supports file locking"
%{ /* NOCONTEXT */
-#if defined(LOCK_EX) && defined(LOCK_UN)
+#if defined(F_SETLK)
RETURN (true);
#else
-# if defined(F_LOCK) && defined(F_UNLOCK)
+# if defined(LOCK_EX) && defined(LOCK_UN)
RETURN (true);
+# else
+# if defined(F_LOCK) && defined(F_UNLOCK)
+ RETURN (true);
+# endif
# endif
#endif
%}.
@@ -3613,6 +3697,46 @@
"
OperatingSystem supportsFileLocks
"
+!
+
+supportsNonBlockingFileLocks
+ "return true, if the OS supports nonBlocking file locking
+ (i.e. with immediate return instead of waiting for the lock)"
+
+%{ /* NOCONTEXT */
+#if defined(F_SETLK) && defined(F_SETLKW)
+ RETURN (true);
+#else
+# if defined(LOCK_EX) && defined(LOCK_UN) && defined(LOCK_NB)
+ RETURN (true);
+# endif
+#endif
+%}.
+ ^ false
+
+ "
+ OperatingSystem supportsNonBlockingFileLocks
+ "
+!
+
+supportsSharedLocks
+ "return true, if the OS supports shared (i.e. multiple reader)
+ file locking."
+
+%{ /* NOCONTEXT */
+#if defined(F_SETLK) && defined(F_RDLCK) && defined(F_WRLCK)
+ RETURN (true);
+#else
+# if defined(LOCK_EX) && defined(LOCK_SH) && defined(LOCK_UN)
+ RETURN (true);
+# endif
+#endif
+%}.
+ ^ false
+
+ "
+ OperatingSystem supportsNonBlockingFileLocks
+ "
! !
!OperatingSystem class methodsFor:'file queries'!
@@ -7582,6 +7706,6 @@
!OperatingSystem class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/Attic/Unix.st,v 1.157 1996-07-27 12:20:46 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Attic/Unix.st,v 1.158 1996-07-27 13:19:56 cg Exp $'
! !
OperatingSystem initialize!