@@ -55,26 +55,25 @@ # import "threading.h" #endif #import "OFDate.h" #import "OFSystemInfo.h" -#import "OFChangeDirectoryFailedException.h" -#import "OFChangeFileModeFailedException.h" -#import "OFChangeFileOwnerFailedException.h" +#import "OFChangeCurrentDirectoryPathFailedException.h" +#import "OFChangeOwnerFailedException.h" +#import "OFChangePermissionsFailedException.h" #import "OFCreateDirectoryFailedException.h" -#import "OFDeleteDirectoryFailedException.h" -#import "OFDeleteFileFailedException.h" +#import "OFCreateSymbolicLinkFailedException.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFLinkFailedException.h" #import "OFLockFailedException.h" #import "OFOpenFileFailedException.h" #import "OFOutOfMemoryException.h" #import "OFReadFailedException.h" -#import "OFRenameFileFailedException.h" +#import "OFRemoveFailedException.h" +#import "OFRenameFailedException.h" #import "OFSeekFailedException.h" -#import "OFSymlinkFailedException.h" #import "OFUnlockFailedException.h" #import "OFWriteFailedException.h" #import "autorelease.h" #import "macros.h" @@ -158,12 +157,12 @@ } + (instancetype)fileWithPath: (OFString*)path mode: (OFString*)mode { - return [[(OFFile*)[self alloc] initWithPath: path - mode: mode] autorelease]; + return [[[self alloc] initWithPath: path + mode: mode] autorelease]; } + (instancetype)fileWithFileDescriptor: (int)filedescriptor { return [[[self alloc] @@ -285,11 +284,11 @@ } objc_autoreleasePoolPop(pool); } -+ (OFArray*)filesInDirectoryAtPath: (OFString*)path ++ (OFArray*)contentsOfDirectoryAtPath: (OFString*)path { OFMutableArray *files = [OFMutableArray array]; #ifndef _WIN32 DIR *dir; @@ -355,36 +354,21 @@ [files makeImmutable]; return files; } -+ (void)changeToDirectoryAtPath: (OFString*)path ++ (void)changeCurrentDirectoryPath: (OFString*)path { #ifndef _WIN32 if (chdir([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE])) #else if (_wchdir([path UTF16String])) #endif - @throw [OFChangeDirectoryFailedException + @throw [OFChangeCurrentDirectoryPathFailedException exceptionWithPath: path]; } -#ifdef OF_HAVE_CHMOD -+ (void)changeModeOfFileAtPath: (OFString*)path - mode: (mode_t)mode -{ -# ifndef _WIN32 - if (chmod([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], mode)) -# else - if (_wchmod([path UTF16String], mode)) -# endif - @throw [OFChangeFileModeFailedException - exceptionWithPath: path - mode: mode]; -} -#endif - + (off_t)sizeOfFileAtPath: (OFString*)path { #ifndef _WIN32 struct stat s; @@ -419,13 +403,29 @@ mode: @"r"]; /* FIXME: We could be more precise on some OSes */ return [OFDate dateWithTimeIntervalSince1970: s.st_mtime]; } + +#ifdef OF_HAVE_CHMOD ++ (void)changePermissionsOfItemAtPath: (OFString*)path + permissions: (mode_t)permissions +{ +# ifndef _WIN32 + if (chmod([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + permissions)) +# else + if (_wchmod([path UTF16String], permissions)) +# endif + @throw [OFChangePermissionsFailedException + exceptionWithPath: path + permissions: permissions]; +} +#endif #ifdef OF_HAVE_CHOWN -+ (void)changeOwnerOfFileAtPath: (OFString*)path ++ (void)changeOwnerOfItemAtPath: (OFString*)path owner: (OFString*)owner group: (OFString*)group { uid_t uid = -1; gid_t gid = -1; @@ -442,11 +442,11 @@ if (owner != nil) { struct passwd *passwd; if ((passwd = getpwnam([owner cStringWithEncoding: OF_STRING_ENCODING_NATIVE])) == NULL) - @throw [OFChangeFileOwnerFailedException + @throw [OFChangeOwnerFailedException exceptionWithPath: path owner: owner group: group]; uid = passwd->pw_uid; @@ -455,11 +455,11 @@ if (group != nil) { struct group *group_; if ((group_ = getgrnam([group cStringWithEncoding: OF_STRING_ENCODING_NATIVE])) == NULL) - @throw [OFChangeFileOwnerFailedException + @throw [OFChangeOwnerFailedException exceptionWithPath: path owner: owner group: group]; gid = group_->gr_gid; @@ -471,14 +471,13 @@ } # endif if (chown([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], uid, gid)) - @throw [OFChangeFileOwnerFailedException - exceptionWithPath: path - owner: owner - group: group]; + @throw [OFChangeOwnerFailedException exceptionWithPath: path + owner: owner + group: group]; } #endif + (void)copyFileAtPath: (OFString*)source toPath: (OFString*)destination @@ -521,12 +520,12 @@ #ifdef OF_HAVE_CHMOD if (!override) { struct stat s; if (fstat(sourceFile->_fd, &s) == 0) - [self changeModeOfFileAtPath: destination - mode: s.st_mode]; + [self changePermissionsOfItemAtPath: destination + permissions: s.st_mode]; } #else (void)override; #endif } @finally { @@ -536,11 +535,11 @@ } objc_autoreleasePoolPop(pool); } -+ (void)renameFileAtPath: (OFString*)source ++ (void)renameItemAtPath: (OFString*)source toPath: (OFString*)destination { void *pool = objc_autoreleasePoolPush(); if ([self directoryExistsAtPath: destination]) { @@ -553,40 +552,29 @@ if (rename([source cStringWithEncoding: OF_STRING_ENCODING_NATIVE], [destination cStringWithEncoding: OF_STRING_ENCODING_NATIVE])) #else if (_wrename([source UTF16String], [destination UTF16String])) #endif - @throw [OFRenameFileFailedException + @throw [OFRenameFailedException exceptionWithSourcePath: source destinationPath: destination]; objc_autoreleasePoolPop(pool); } -+ (void)deleteFileAtPath: (OFString*)path -{ -#ifndef _WIN32 - if (unlink([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE])) -#else - if (_wunlink([path UTF16String])) -#endif - @throw [OFDeleteFileFailedException exceptionWithPath: path]; -} - -+ (void)deleteDirectoryAtPath: (OFString*)path -{ -#ifndef _WIN32 - if (rmdir([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE])) -#else - if (_wrmdir([path UTF16String])) -#endif - @throw [OFDeleteDirectoryFailedException - exceptionWithPath: path]; ++ (void)removeItemAtPath: (OFString*)path +{ +#ifndef _WIN32 + if (remove([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE])) +#else + if (_wremove([path UTF16String])) +#endif + @throw [OFRemoveFailedException exceptionWithPath: path]; } #ifdef OF_HAVE_LINK -+ (void)linkFileAtPath: (OFString*)source ++ (void)linkItemAtPath: (OFString*)source toPath: (OFString*)destination { void *pool = objc_autoreleasePoolPush(); if ([self directoryExistsAtPath: destination]) { @@ -604,12 +592,12 @@ objc_autoreleasePoolPop(pool); } #endif #ifdef OF_HAVE_SYMLINK -+ (void)symlinkFileAtPath: (OFString*)source - toPath: (OFString*)destination ++ (void)createSymbolicLinkAtPath: (OFString*)source + destinationPath: (OFString*)destination { void *pool = objc_autoreleasePoolPush(); if ([self directoryExistsAtPath: destination]) { OFString *filename = [source lastPathComponent]; @@ -617,16 +605,33 @@ nil]; } if (symlink([source cStringWithEncoding: OF_STRING_ENCODING_NATIVE], [destination cStringWithEncoding: OF_STRING_ENCODING_NATIVE]) != 0) - @throw [OFSymlinkFailedException + @throw [OFCreateSymbolicLinkFailedException exceptionWithSourcePath: source destinationPath: destination]; objc_autoreleasePoolPop(pool); } + ++ (OFString*)destinationOfSymbolicLinkAtPath: (OFString*)path +{ + char destination[PATH_MAX]; + ssize_t length; + + length = readlink([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + destination, PATH_MAX); + + if (length < 0) + @throw [OFOpenFileFailedException exceptionWithPath: path + mode: @"r"]; + + return [OFString stringWithCString: destination + encoding: OF_STRING_ENCODING_NATIVE + length: length]; +} #endif - init { @try {