home *** CD-ROM | disk | FTP | other *** search
- //
- // DAYLockFile.h -- a generic class to simplify keeping an atomic lock file
- // Written by Don Yacktman (c) 1993 by Don Yacktman.
- // Version 1.0. All rights reserved.
- //
- // This is a free object! Contact the author for the latest version.
- // Don Yacktman, 4279 N. Ivy Lane, Provo, UT, 84604
- // e-mail: Don_Yacktman@byu.edu
- //
- // You may use and copy this class freely as long as you
- // comply with the following terms:
- // (1) Do not remove the author's name or any of the
- // copyright notices from this file.
- // (2) If you redistribute an application which uses this
- // object, you must either include the source code for
- // this object with the application or state in your
- // application's documentation that you (a) use this
- // object and (b) where to obtain the source code for
- // the object.
- // (3) In no way shall the author or his employer(s) be held
- // responsible for any damages caused by what this object
- // does or does not do.
- // (4) You have no warranty whatsoever that this object is
- // good for any purpose at all. If you find it useful
- // for something, consider yourself lucky and leave it at that.
- //
-
- #import <daymisckit/daymisckit.h>
- #import <sys/file.h>
- #import <sys/vnode.h>
-
- @implementation DAYLockFile
-
- - init
- {
- id ret = [super init];
- haveLock = NO;
- return ret;
- }
-
- - fileName { return lockFileName; }
- - setFileName:aString
- {
- if (haveLock) [self unlock];
- lockFileName = aString;
- return self;
- }
-
- - lock // atomically create a lock file. returns YES on success
- { // lock file contains the PID of the locking process.
- int lockFileFD; char buffer[16];
- if (!lockFileName || ![lockFileName stringValue])
- return self; // always "have" lock if no lock file used
- if (haveLock) return self; // already been done
- lockFileFD = open([lockFileName stringValue], // file name
- (O_EXCL | O_CREAT | O_RDWR), // error if exists; create if doesn't
- (VREAD | VWRITE)); // mode is owner r/w
- if (lockFileFD < 0) return nil; // error opening the lock file
- sprintf(buffer, "%d", getpid());
- if (write(lockFileFD, buffer, strlen(buffer)) < 0) return nil; // couldn't write
- if (close(lockFileFD)) return nil; // error closing the lock file
- haveLock = YES;
- return self;
- }
-
- - unlock // remove the lock file.
- {
- if (!lockFileName || ![lockFileName stringValue])
- return self; // always "had" lock if no lock file used
- if (!haveLock) return nil;
- if (unlink([lockFileName stringValue])) return nil; // error in unlink()
- haveLock = NO; // the lock was successfully removed.
- return self;
- }
-
- - (BOOL)haveLock { return (haveLock || !lockFileName); }
-
- - copy
- { // copies do not have locks or open logs... only original can!
- id myCopy = [[DAYLockFile alloc] init];
- [myCopy setFileName:lockFileName];
- return myCopy;
- }
-
- - read:(NXTypedStream *)stream
- {
- [super read:stream];
- lockFileName = NXReadObject(stream);
- haveLock = NO;
- return self;
- }
-
- - write:(NXTypedStream *)stream
- {
- [super write:stream];
- NXWriteObject(stream, lockFileName);
- return self;
- }
-
- // NXTransport protocol implementation:
- - encodeUsing:(id <NXEncoding>)portal
- {
- [portal encodeObjectBycopy:lockFileName];
- return self;
- }
-
- - decodeUsing:(id <NXDecoding>)portal
- {
- lockFileName = [portal decodeObject];
- return self;
- }
-
- - encodeRemotelyFor:(NXConnection *)connection
- freeAfterEncoding:(BOOL *)flagp isBycopy:(BOOL)isByCopy
- {
- if (isByCopy) {
- *flagp = NO; // object will copy.
- return self; //encode object (copy it)
- }
- *flagp = NO; // object will copy.
- // super will encode the proxy otherwise
- return [super encodeRemotelyFor:connection
- freeAfterEncoding:flagp isBycopy:isByCopy];
- }
-
- - free
- {
- if (haveLock) [self unlock];
- [lockFileName free];
- return [super free];
- }
-
- @end
-