mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Implement linking
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@16479 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
b283c8d930
commit
0b6406fcc3
6 changed files with 215 additions and 11 deletions
|
@ -8,6 +8,7 @@
|
|||
* Headers/gnustep/base/NSValue.h:
|
||||
* Headers/gnustep/base/Foundation.h:
|
||||
Tidied use of GSCategories.
|
||||
* Source/NSFileManager.m: ([linkPath:toPath:handler:]) implemented.
|
||||
|
||||
2003-04-16 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* Define if SO_REUSEADDR is broken on this system */
|
||||
#undef BROKEN_SO_REUSEADDR
|
||||
|
||||
/* Define if your system terminates the final argument in /proc/10983/cmdline */
|
||||
/* Define if your system terminates the final argument in /proc/$$/cmdline */
|
||||
#undef CMDLINE_TERMINATED
|
||||
|
||||
/* Define if constructors are automatically loaded */
|
||||
|
@ -40,6 +40,9 @@
|
|||
/* Define to 1 if you have the `geteuid' function. */
|
||||
#undef HAVE_GETEUID
|
||||
|
||||
/* Define to 1 if you have the `getgrgid' function. */
|
||||
#undef HAVE_GETGRGID
|
||||
|
||||
/* Define to 1 if you have the `getlogin' function. */
|
||||
#undef HAVE_GETLOGIN
|
||||
|
||||
|
@ -94,6 +97,9 @@
|
|||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define to 1 if you have the `link' function. */
|
||||
#undef HAVE_LINK
|
||||
|
||||
/* Define if your Obj-C compiler calls +load methods before main */
|
||||
#undef HAVE_LOAD_METHOD
|
||||
|
||||
|
|
|
@ -203,6 +203,11 @@
|
|||
toPath: (NSString*)destination
|
||||
handler: (id)handler;
|
||||
|
||||
/* Recursively links the contents of source directory to destination. */
|
||||
- (BOOL) _linkPath: (NSString*)source
|
||||
toPath: (NSString*)destination
|
||||
handler: handler;
|
||||
|
||||
/* encapsulates the will Process check for existence of selector. */
|
||||
- (void) _sendToHandler: (id) handler
|
||||
willProcessPath: (NSString*) path;
|
||||
|
@ -872,10 +877,7 @@ static NSFileManager* defaultManager = nil;
|
|||
return NO;
|
||||
}
|
||||
}
|
||||
if (attrs != nil)
|
||||
{
|
||||
[self changeFileAttributes: attrs atPath: destination];
|
||||
}
|
||||
[self changeFileAttributes: attrs atPath: destination];
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
@ -951,18 +953,109 @@ static NSFileManager* defaultManager = nil;
|
|||
}
|
||||
|
||||
/**
|
||||
* Links the file or directory at source to destination, using a
|
||||
* <p>Links the file or directory at source to destination, using a
|
||||
* handler object which should respond to
|
||||
* [NSObject-fileManager:willProcessPath:] and
|
||||
* [NSObject-fileManager:shouldProceedAfterError:] messages.
|
||||
* </p>
|
||||
* <p>If the destination is a directory, the source path is linked
|
||||
* into that directory, otherwise the destination must not exist,
|
||||
* but its parent directory must exist and the source will be linked
|
||||
* into the parent as the name specified by the destination.
|
||||
* </p>
|
||||
* <p>If the source is a symbolic link, it is copied to the destination.<br />
|
||||
* If the source is a directory, it is copied to the destination and its
|
||||
* contents are linked into the new directory.<br />
|
||||
* Otherwise, a hard link is made from the destination to the source.
|
||||
* </p>
|
||||
*/
|
||||
- (BOOL) linkPath: (NSString*)source
|
||||
toPath: (NSString*)destination
|
||||
handler: (id)handler
|
||||
{
|
||||
// TODO
|
||||
[self notImplemented: _cmd];
|
||||
return NO;
|
||||
#ifdef HAVE_LINK
|
||||
NSDictionary *attrs;
|
||||
NSString *fileType;
|
||||
BOOL isDir;
|
||||
|
||||
if ([self fileExistsAtPath: destination isDirectory: &isDir] == YES
|
||||
&& isDir == YES)
|
||||
{
|
||||
destination = [destination stringByAppendingPathComponent:
|
||||
[source lastPathComponent]];
|
||||
}
|
||||
|
||||
attrs = [self fileAttributesAtPath: source traverseLink: NO];
|
||||
if (attrs == nil)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
[self _sendToHandler: handler willProcessPath: destination];
|
||||
|
||||
fileType = [attrs fileType];
|
||||
if ([fileType isEqualToString: NSFileTypeDirectory] == YES)
|
||||
{
|
||||
/* If destination directory is a descendant of source directory linking
|
||||
isn't possible because of recursion. */
|
||||
if ([[destination stringByAppendingString: @"/"]
|
||||
hasPrefix: [source stringByAppendingString: @"/"]])
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
if ([self createDirectoryAtPath: destination attributes: attrs] == NO)
|
||||
{
|
||||
return [self _proceedAccordingToHandler: handler
|
||||
forError: _lastError
|
||||
inPath: destination
|
||||
fromPath: source
|
||||
toPath: destination];
|
||||
}
|
||||
|
||||
if ([self _linkPath: source toPath: destination handler: handler] == NO)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
else if ([fileType isEqual: NSFileTypeSymbolicLink])
|
||||
{
|
||||
NSString *path;
|
||||
|
||||
path = [self pathContentOfSymbolicLinkAtPath: source];
|
||||
if ([self createSymbolicLinkAtPath: destination
|
||||
pathContent: path] == NO)
|
||||
{
|
||||
if ([self _proceedAccordingToHandler: handler
|
||||
forError: @"cannot create symbolic link"
|
||||
inPath: source
|
||||
fromPath: source
|
||||
toPath: destination] == NO)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (link([source fileSystemRepresentation],
|
||||
[destination fileSystemRepresentation]) < 0)
|
||||
{
|
||||
if ([self _proceedAccordingToHandler: handler
|
||||
forError: @"cannot create hard link"
|
||||
inPath: source
|
||||
fromPath: source
|
||||
toPath: destination] == NO)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
[self changeFileAttributes: attrs atPath: destination];
|
||||
return YES;
|
||||
#else
|
||||
return NO; // Links not supported on this platform
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2477,6 +2570,98 @@ static SEL swfsSel = 0;
|
|||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL) _linkPath: (NSString*)source
|
||||
toPath: (NSString*)destination
|
||||
handler: handler
|
||||
{
|
||||
#ifdef HAVE_LINK
|
||||
NSDirectoryEnumerator *enumerator;
|
||||
NSString *dirEntry;
|
||||
CREATE_AUTORELEASE_POOL(pool);
|
||||
|
||||
enumerator = [self enumeratorAtPath: source];
|
||||
while ((dirEntry = [enumerator nextObject]))
|
||||
{
|
||||
NSString *sourceFile;
|
||||
NSString *fileType;
|
||||
NSString *destinationFile;
|
||||
NSDictionary *attributes;
|
||||
|
||||
attributes = [enumerator fileAttributes];
|
||||
fileType = [attributes fileType];
|
||||
sourceFile = [source stringByAppendingPathComponent: dirEntry];
|
||||
destinationFile
|
||||
= [destination stringByAppendingPathComponent: dirEntry];
|
||||
|
||||
[self _sendToHandler: handler willProcessPath: sourceFile];
|
||||
|
||||
if ([fileType isEqual: NSFileTypeDirectory] == YES)
|
||||
{
|
||||
if ([self createDirectoryAtPath: destinationFile
|
||||
attributes: attributes] == NO)
|
||||
{
|
||||
if ([self _proceedAccordingToHandler: handler
|
||||
forError: _lastError
|
||||
inPath: destinationFile
|
||||
fromPath: sourceFile
|
||||
toPath: destinationFile] == NO)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[enumerator skipDescendents];
|
||||
if ([self _linkPath: sourceFile
|
||||
toPath: destinationFile
|
||||
handler: handler] == NO)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ([fileType isEqual: NSFileTypeSymbolicLink])
|
||||
{
|
||||
NSString *path;
|
||||
|
||||
path = [self pathContentOfSymbolicLinkAtPath: sourceFile];
|
||||
if ([self createSymbolicLinkAtPath: destinationFile
|
||||
pathContent: path] == NO)
|
||||
{
|
||||
if ([self _proceedAccordingToHandler: handler
|
||||
forError: @"cannot create symbolic link"
|
||||
inPath: sourceFile
|
||||
fromPath: sourceFile
|
||||
toPath: destinationFile] == NO)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (link([sourceFile fileSystemRepresentation],
|
||||
[destinationFile fileSystemRepresentation]) < 0)
|
||||
{
|
||||
if ([self _proceedAccordingToHandler: handler
|
||||
forError: @"cannot create hard link"
|
||||
inPath: sourceFile
|
||||
fromPath: sourceFile
|
||||
toPath: destinationFile] == NO)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
[self changeFileAttributes: attributes atPath: destinationFile];
|
||||
}
|
||||
RELEASE(pool);
|
||||
return YES;
|
||||
#else
|
||||
return NO;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void) _sendToHandler: (id) handler
|
||||
willProcessPath: (NSString*) path
|
||||
{
|
||||
|
|
|
@ -47,6 +47,17 @@ main ()
|
|||
}
|
||||
}
|
||||
|
||||
src = [defs stringForKey: @"LinkSrc"];
|
||||
dst = [defs objectForKey: @"LinkDst"];
|
||||
if (src != nil && dst != nil)
|
||||
{
|
||||
if ([mgr linkPath: src toPath: dst handler: handler] == NO)
|
||||
{
|
||||
NSLog(@"Link %@ to %@ failed", src, dst);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
src = [defs stringForKey: @"Remove"];
|
||||
if (src != nil)
|
||||
{
|
||||
|
|
3
configure
vendored
3
configure
vendored
|
@ -8044,7 +8044,8 @@ fi
|
|||
|
||||
|
||||
|
||||
for ac_func in statvfs symlink readlink geteuid getlogin getpwnam getpwuid getgrgid rint
|
||||
|
||||
for ac_func in statvfs link symlink readlink geteuid getlogin getpwnam getpwuid getgrgid rint
|
||||
do
|
||||
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
echo "$as_me:$LINENO: checking for $ac_func" >&5
|
||||
|
|
|
@ -520,7 +520,7 @@ AC_CHECK_HEADERS(sys/stat.h sys/vfs.h sys/statfs.h sys/statvfs.h pwd.h grp.h)
|
|||
AC_CHECK_HEADERS(sys/mount.h sys/types.h windows.h locale.h langinfo.h)
|
||||
saved_LIBS="$LIBS"
|
||||
AC_CHECK_LIB(m, main)
|
||||
AC_CHECK_FUNCS(statvfs symlink readlink geteuid getlogin getpwnam getpwuid getgrgid rint)
|
||||
AC_CHECK_FUNCS(statvfs link symlink readlink geteuid getlogin getpwnam getpwuid getgrgid rint)
|
||||
LIBS="$saved_LIBS"
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue