mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 00:11:26 +00:00
Fixes to permit handlers to do less.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@15932 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
0f92295f75
commit
f4e4d96572
3 changed files with 207 additions and 199 deletions
21
ChangeLog
21
ChangeLog
|
@ -1,3 +1,24 @@
|
|||
i2003-02-11 Willem Rein Oudshoorn <woudshoo@xs4all.nl>
|
||||
|
||||
* Headers/Foundation/NSFileManager.h: Added a little bit to the
|
||||
* documentation of the NSFileManagerHandler protocol.
|
||||
(some documentation markup fixes by RFM also)
|
||||
* Source/NSFileManager.m ([NSFileManager -copyPath:toPath:handler:]):
|
||||
use new private methods to cope with handlers that do not implement
|
||||
the informal protocol. Pass more information to the handler in case
|
||||
of an error.
|
||||
([NSFileManager -removeFileAtPath:handler:]): see above
|
||||
([NSFileManager -movePath:toPath:handler:]): see above
|
||||
([NSFileManager -_copyPath:toPath:handler:]): see above
|
||||
([NSFileManager -_copyFile:toFile:handler:]): see above, also fixed
|
||||
leaking of file descriptors in case of error without a handler.
|
||||
([NSFileManager -_sendToHandler:handlerwillProcessPath:path]):
|
||||
new method
|
||||
([NSFileManager -_proceedAccordingToHandler:handlerforError:
|
||||
errorinPath:path]): new method
|
||||
([NSFileManager -_proceedAccordingToHandler:handlerforError:
|
||||
errorinPath:pathfromPath:fromPathtoPath:toPath]): new method
|
||||
|
||||
2003-02-11 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSFileManager.m: ([+attributesAt:traverseLink:]) check for
|
||||
|
|
|
@ -102,11 +102,41 @@
|
|||
*/
|
||||
@interface NSObject (NSFileManagerHandler)
|
||||
/**
|
||||
* When an error occurs during a copy or move operation, the file manager
|
||||
* <p>When an error occurs during a copy or move operation, the file manager
|
||||
* will send this message to the handler, and will use the return value to
|
||||
* determine whether the operation should proceed. If the method returns
|
||||
* YES then the operation will proceed after the error, if it returns NO
|
||||
* then it will be aborted.
|
||||
* </p>
|
||||
* <p>If the handler does not implement this method it will be treated as
|
||||
* if it returns NO.
|
||||
* </p>
|
||||
* The error dictionary contains the following
|
||||
* <list>
|
||||
* <item><strong>"Error"</strong>
|
||||
* contains a description of the error.
|
||||
* </item>
|
||||
* <item><strong>"Path"</strong>
|
||||
* contains the path that is being processed when
|
||||
* an error occured. If an error occurs during an
|
||||
* operation involving two files, like copying, and
|
||||
* it is not clear which file triggers the error it
|
||||
* will default to the source file.
|
||||
* </item>
|
||||
* <item><strong>"FromPath"</strong>
|
||||
* (Optional) contains the path involved in reading.
|
||||
* </item>
|
||||
* <item><strong>"ToPath"</strong>
|
||||
* (Optional) contains the path involved in writing.
|
||||
* </item>
|
||||
* </list>
|
||||
*
|
||||
* <p>Note that the <code>FromPath</code> is a GNUstep extension.
|
||||
* </p>
|
||||
* <p>Also the <code>FromPath</code> and <code>ToPath</code> are filled
|
||||
* in when appropriate. So when copying a file they will typically
|
||||
* both have a value and when reading only <code>FromPath</code>.
|
||||
* </p>
|
||||
*/
|
||||
- (BOOL) fileManager: (NSFileManager*)fileManager
|
||||
shouldProceedAfterError: (NSDictionary*)errorDictionary;
|
||||
|
@ -115,7 +145,7 @@
|
|||
* The file manager sends this method to the handler immediately before
|
||||
* performing part of a directory move or copy operation. This provides
|
||||
* the handler object with information it can use in the event of an
|
||||
* error, to decide whether p[rocessing should proceed after the error.
|
||||
* error, to decide whether processing should proceed after the error.
|
||||
*/
|
||||
- (void) fileManager: (NSFileManager*)fileManager
|
||||
willProcessPath: (NSString*)path;
|
||||
|
|
|
@ -203,6 +203,25 @@
|
|||
toPath: (NSString*)destination
|
||||
handler: (id)handler;
|
||||
|
||||
/* encapsulates the will Process check for existence of selector. */
|
||||
- (void) _sendToHandler: (id) handler
|
||||
willProcessPath: (NSString*) path;
|
||||
|
||||
/* methods to encapsulates setting up and calling the handler
|
||||
in case of an error */
|
||||
- (BOOL) _proceedAccordingToHandler: (id) handler
|
||||
forError: (NSString*) error
|
||||
inPath: (NSString*) path;
|
||||
|
||||
- (BOOL) _proceedAccordingToHandler: (id) handler
|
||||
forError: (NSString*) error
|
||||
inPath: (NSString*) path
|
||||
fromPath: (NSString*) frompath
|
||||
toPath: (NSString*) toPath;
|
||||
|
||||
|
||||
|
||||
|
||||
@end /* NSFileManager (PrivateMethods) */
|
||||
|
||||
/**
|
||||
|
@ -805,21 +824,15 @@ static NSFileManager* defaultManager = nil;
|
|||
return NO;
|
||||
}
|
||||
|
||||
[handler fileManager: self willProcessPath: destination];
|
||||
[self _sendToHandler: handler willProcessPath: destination];
|
||||
|
||||
if ([self createDirectoryAtPath: destination attributes: attrs] == NO)
|
||||
{
|
||||
if (handler)
|
||||
{
|
||||
NSDictionary* errorInfo
|
||||
= [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
destination, @"Path", _lastError, @"Error", nil];
|
||||
return [handler fileManager: self
|
||||
shouldProceedAfterError: errorInfo];
|
||||
}
|
||||
else
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
return [self _proceedAccordingToHandler: handler
|
||||
forError: _lastError
|
||||
inPath: destination
|
||||
fromPath: source
|
||||
toPath: destination];
|
||||
}
|
||||
|
||||
if ([self _copyPath: source toPath: destination handler: handler] == NO)
|
||||
|
@ -832,21 +845,18 @@ static NSFileManager* defaultManager = nil;
|
|||
NSString *path;
|
||||
BOOL result;
|
||||
|
||||
[handler fileManager: self willProcessPath: source];
|
||||
[self _sendToHandler: handler willProcessPath: source];
|
||||
|
||||
path = [self pathContentOfSymbolicLinkAtPath: source];
|
||||
result = [self createSymbolicLinkAtPath: destination pathContent: path];
|
||||
if (result == NO)
|
||||
{
|
||||
if (handler != nil)
|
||||
{
|
||||
NSDictionary *errorInfo
|
||||
= [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
source, @"Path", destination, @"ToPath",
|
||||
@"cannot link to file", @"Error",
|
||||
nil];
|
||||
result = [handler fileManager: self
|
||||
shouldProceedAfterError: errorInfo];
|
||||
}
|
||||
result = [self _proceedAccordingToHandler: handler
|
||||
forError: @"cannot link to file"
|
||||
inPath: source
|
||||
fromPath: source
|
||||
toPath: destination];
|
||||
|
||||
if (result == NO)
|
||||
{
|
||||
return NO;
|
||||
|
@ -855,7 +865,8 @@ static NSFileManager* defaultManager = nil;
|
|||
}
|
||||
else
|
||||
{
|
||||
[handler fileManager: self willProcessPath: source];
|
||||
[self _sendToHandler: handler willProcessPath: source];
|
||||
|
||||
if ([self _copyFile: source toFile: destination handler: handler] == NO)
|
||||
{
|
||||
return NO;
|
||||
|
@ -923,22 +934,15 @@ static NSFileManager* defaultManager = nil;
|
|||
{
|
||||
/* source and destination are on the same device so we can simply
|
||||
invoke rename on source. */
|
||||
[handler fileManager: self willProcessPath: source];
|
||||
[self _sendToHandler: handler willProcessPath: source];
|
||||
|
||||
if (rename (sourcePath, destPath) == -1)
|
||||
{
|
||||
if (handler)
|
||||
{
|
||||
NSDictionary* errorInfo
|
||||
= [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
source, @"Path",
|
||||
destination, @"ToPath",
|
||||
@"cannot move file", @"Error",
|
||||
nil];
|
||||
if ([handler fileManager: self
|
||||
shouldProceedAfterError: errorInfo])
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
return [self _proceedAccordingToHandler: handler
|
||||
forError: @"cannot move file"
|
||||
inPath: source
|
||||
fromPath: source
|
||||
toPath: destination];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
@ -979,10 +983,8 @@ static NSFileManager* defaultManager = nil;
|
|||
format: @"Attempt to remove illegal path"];
|
||||
}
|
||||
|
||||
if (handler != nil)
|
||||
{
|
||||
[handler fileManager: self willProcessPath: path];
|
||||
}
|
||||
[self _sendToHandler: handler willProcessPath: path];
|
||||
|
||||
cpath = [self fileSystemRepresentationWithPath: path];
|
||||
if (cpath == 0 || *cpath == '\0')
|
||||
{
|
||||
|
@ -1025,26 +1027,9 @@ static NSFileManager* defaultManager = nil;
|
|||
if (unlink(cpath) < 0)
|
||||
#endif
|
||||
{
|
||||
BOOL result;
|
||||
|
||||
if (handler)
|
||||
{
|
||||
NSMutableDictionary *info;
|
||||
|
||||
info = [[NSMutableDictionary alloc] initWithCapacity: 3];
|
||||
[info setObject: path forKey: @"Path"];
|
||||
[info setObject: [NSString stringWithCString:
|
||||
GSLastErrorStr(errno)]
|
||||
forKey: @"Error"];
|
||||
result = [handler fileManager: self
|
||||
shouldProceedAfterError: info];
|
||||
RELEASE(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = NO;
|
||||
}
|
||||
return result;
|
||||
return [self _proceedAccordingToHandler: handler
|
||||
forError: [NSString stringWithCString: GSLastErrorStr (errno)]
|
||||
inPath: path];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1076,26 +1061,9 @@ static NSFileManager* defaultManager = nil;
|
|||
|
||||
if (rmdir([path fileSystemRepresentation]) < 0)
|
||||
{
|
||||
BOOL result;
|
||||
|
||||
if (handler)
|
||||
{
|
||||
NSMutableDictionary *info;
|
||||
|
||||
info = [[NSMutableDictionary alloc] initWithCapacity: 3];
|
||||
[info setObject: path forKey: @"Path"];
|
||||
[info setObject: [NSString stringWithCString:
|
||||
GSLastErrorStr(errno)]
|
||||
forKey: @"Error"];
|
||||
result = [handler fileManager: self
|
||||
shouldProceedAfterError: info];
|
||||
RELEASE(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = NO;
|
||||
}
|
||||
return result;
|
||||
return [self _proceedAccordingToHandler: handler
|
||||
forError: [NSString stringWithCString: GSLastErrorStr (errno)]
|
||||
inPath: path];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2323,21 +2291,13 @@ static SEL swfsSel = 0;
|
|||
{
|
||||
return YES;
|
||||
}
|
||||
if (handler != nil)
|
||||
{
|
||||
NSDictionary *errorInfo
|
||||
= [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
source, @"Path",
|
||||
@"cannot copy file", @"Error",
|
||||
destination, @"ToPath",
|
||||
nil];
|
||||
return [handler fileManager: self
|
||||
shouldProceedAfterError: errorInfo];
|
||||
}
|
||||
else
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
return [self _proceedAccordingToHandler: handler
|
||||
forError: @"cannot copy file"
|
||||
inPath: source
|
||||
fromPath: source
|
||||
toPath: destination];
|
||||
|
||||
#else
|
||||
NSDictionary *attributes;
|
||||
int i;
|
||||
|
@ -2366,20 +2326,11 @@ static SEL swfsSel = 0;
|
|||
GSBINIO|O_RDONLY);
|
||||
if (sourceFd < 0)
|
||||
{
|
||||
if (handler != nil)
|
||||
{
|
||||
NSDictionary *errorInfo
|
||||
= [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
source, @"Path",
|
||||
@"cannot open file for reading", @"Error",
|
||||
nil];
|
||||
return [handler fileManager: self
|
||||
shouldProceedAfterError: errorInfo];
|
||||
}
|
||||
else
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
return [self _proceedAccordingToHandler: handler
|
||||
forError: @"cannot open file for reading"
|
||||
inPath: source
|
||||
fromPath: source
|
||||
toPath: destination];
|
||||
}
|
||||
|
||||
/* Open the destination file. In case of error call the handler. */
|
||||
|
@ -2387,23 +2338,15 @@ static SEL swfsSel = 0;
|
|||
GSBINIO|O_WRONLY|O_CREAT|O_TRUNC, fileMode);
|
||||
if (destFd < 0)
|
||||
{
|
||||
if (handler != nil)
|
||||
{
|
||||
NSDictionary *errorInfo
|
||||
= [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
destination, @"ToPath",
|
||||
@"cannot open file for writing", @"Error",
|
||||
nil];
|
||||
close (sourceFd);
|
||||
return [handler fileManager: self
|
||||
shouldProceedAfterError: errorInfo];
|
||||
}
|
||||
else
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
close (sourceFd);
|
||||
|
||||
return [self _proceedAccordingToHandler: handler
|
||||
forError: @"cannot open file for writing"
|
||||
inPath: destination
|
||||
fromPath: source
|
||||
toPath: destination];
|
||||
}
|
||||
|
||||
/* Read bufsize bytes from source file and write them into the destination
|
||||
file. In case of errors call the handler and abort the operation. */
|
||||
for (i = 0; i < fileSize; i += rbytes)
|
||||
|
@ -2411,45 +2354,28 @@ static SEL swfsSel = 0;
|
|||
rbytes = read (sourceFd, buffer, bufsize);
|
||||
if (rbytes < 0)
|
||||
{
|
||||
if (handler != nil)
|
||||
{
|
||||
NSDictionary *errorInfo
|
||||
= [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
source, @"Path",
|
||||
@"cannot read from file", @"Error",
|
||||
nil];
|
||||
close (sourceFd);
|
||||
close (destFd);
|
||||
return [handler fileManager: self
|
||||
shouldProceedAfterError: errorInfo];
|
||||
}
|
||||
else
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
close (sourceFd);
|
||||
close (destFd);
|
||||
|
||||
return [self _proceedAccordingToHandler: handler
|
||||
forError: @"cannot read from file"
|
||||
inPath: source
|
||||
fromPath: source
|
||||
toPath: destination];
|
||||
}
|
||||
|
||||
wbytes = write (destFd, buffer, rbytes);
|
||||
if (wbytes != rbytes)
|
||||
{
|
||||
if (handler != nil)
|
||||
{
|
||||
NSDictionary *errorInfo
|
||||
= [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
source, @"Path",
|
||||
destination, @"ToPath",
|
||||
@"cannot write to file", @"Error",
|
||||
nil];
|
||||
close (sourceFd);
|
||||
close (destFd);
|
||||
return [handler fileManager: self
|
||||
shouldProceedAfterError: errorInfo];
|
||||
}
|
||||
else
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
close (sourceFd);
|
||||
close (destFd);
|
||||
|
||||
return [self _proceedAccordingToHandler: handler
|
||||
forError: @"cannot write to file"
|
||||
inPath: destination
|
||||
fromPath: source
|
||||
toPath: destination];
|
||||
}
|
||||
}
|
||||
close (sourceFd);
|
||||
close (destFd);
|
||||
|
@ -2480,32 +2406,28 @@ static SEL swfsSel = 0;
|
|||
destinationFile
|
||||
= [destination stringByAppendingPathComponent: dirEntry];
|
||||
|
||||
[handler fileManager: self willProcessPath: sourceFile];
|
||||
[self _sendToHandler: handler willProcessPath: sourceFile];
|
||||
|
||||
if ([fileType isEqual: NSFileTypeDirectory])
|
||||
{
|
||||
if (![self createDirectoryAtPath: destinationFile
|
||||
attributes: attributes])
|
||||
{
|
||||
if (handler)
|
||||
{
|
||||
NSDictionary *errorInfo;
|
||||
|
||||
errorInfo = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
destinationFile, @"Path",
|
||||
_lastError, @"Error", nil];
|
||||
if (![handler fileManager: self
|
||||
shouldProceedAfterError: errorInfo])
|
||||
return NO;
|
||||
}
|
||||
else
|
||||
return NO;
|
||||
if (![self _proceedAccordingToHandler: handler
|
||||
forError: _lastError
|
||||
inPath: destinationFile
|
||||
fromPath: sourceFile
|
||||
toPath: destinationFile])
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[enumerator skipDescendents];
|
||||
if (![self _copyPath: sourceFile
|
||||
toPath: destinationFile
|
||||
handler: handler])
|
||||
toPath: destinationFile
|
||||
handler: handler])
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
@ -2524,24 +2446,14 @@ static SEL swfsSel = 0;
|
|||
if (![self createSymbolicLinkAtPath: destinationFile
|
||||
pathContent: path])
|
||||
{
|
||||
if (handler)
|
||||
{
|
||||
NSDictionary *errorInfo
|
||||
= [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
sourceFile, @"Path",
|
||||
destinationFile, @"ToPath",
|
||||
@"cannot create symbolic link", @"Error",
|
||||
nil];
|
||||
if (![handler fileManager: self
|
||||
shouldProceedAfterError: errorInfo])
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
if (![self _proceedAccordingToHandler: handler
|
||||
forError: @"cannot create symbolic link"
|
||||
inPath: sourceFile
|
||||
fromPath: sourceFile
|
||||
toPath: destinationFile])
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -2561,6 +2473,51 @@ static SEL swfsSel = 0;
|
|||
return YES;
|
||||
}
|
||||
|
||||
- (void) _sendToHandler: (id) handler
|
||||
willProcessPath: (NSString*) path
|
||||
{
|
||||
if ([handler respondsToSelector: @selector (fileManager:willProcessPath:)])
|
||||
{
|
||||
[handler fileManager: self willProcessPath: path];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) _proceedAccordingToHandler: (id) handler
|
||||
forError: (NSString*) error
|
||||
inPath: (NSString*) path
|
||||
{
|
||||
if ([handler respondsToSelector:
|
||||
@selector (fileManager:shouldProceedAfterError:)])
|
||||
{
|
||||
NSDictionary *errorInfo = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
path, @"Path",
|
||||
error, @"Error", nil];
|
||||
return [handler fileManager: self
|
||||
shouldProceedAfterError: errorInfo];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) _proceedAccordingToHandler: (id) handler
|
||||
forError: (NSString*) error
|
||||
inPath: (NSString*) path
|
||||
fromPath: (NSString*) fromPath
|
||||
toPath: (NSString*) toPath
|
||||
{
|
||||
if ([handler respondsToSelector:
|
||||
@selector (fileManager:shouldProceedAfterError:)])
|
||||
{
|
||||
NSDictionary *errorInfo = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
path, @"Path",
|
||||
fromPath, @"FromPath",
|
||||
toPath, @"ToPath",
|
||||
error, @"Error", nil];
|
||||
return [handler fileManager: self
|
||||
shouldProceedAfterError: errorInfo];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end /* NSFileManager (PrivateMethods) */
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue