@@ -34,11 +34,11 @@ #import "OFArray.h" #import "OFDate.h" #import "OFSystemInfo.h" #ifdef OF_HAVE_THREADS -# import "threading.h" +# import "OFMutex.h" #endif #import "OFChangeCurrentDirectoryPathFailedException.h" #import "OFChangeOwnerFailedException.h" #import "OFChangePermissionsFailedException.h" @@ -79,14 +79,14 @@ #define DIR_MODE DEFAULT_MODE | S_IXUSR | S_IXGRP | S_IXOTH static OFFileManager *defaultManager; #if defined(OF_HAVE_CHOWN) && defined(OF_HAVE_THREADS) -static of_mutex_t chownMutex; +static OFMutex *passwdMutex; #endif #if !defined(HAVE_READDIR_R) && !defined(OF_WINDOWS) && defined(OF_HAVE_THREADS) -static of_mutex_t readdirMutex; +static OFMutex *readdirMutex; #endif int of_stat(OFString *path, of_stat_t *buffer) { @@ -136,19 +136,14 @@ * On some systems, this is needed to initialize the file system driver. */ [OFFile class]; #if defined(OF_HAVE_CHOWN) && defined(OF_HAVE_THREADS) - if (!of_mutex_new(&chownMutex)) - @throw [OFInitializationFailedException - exceptionWithClass: self]; + passwdMutex = [[OFMutex alloc] init]; #endif - #if !defined(HAVE_READDIR_R) && !defined(OF_WINDOWS) && defined(OF_HAVE_THREADS) - if (!of_mutex_new(&readdirMutex)) - @throw [OFInitializationFailedException - exceptionWithClass: self]; + readdirMutex = [[OFMutex alloc] init]; #endif defaultManager = [[OFFileManager alloc] init]; } @@ -301,14 +296,12 @@ if ((dir = opendir([path cStringWithEncoding: encoding])) == NULL) @throw [OFOpenItemFailedException exceptionWithPath: path errNo: errno]; # if !defined(HAVE_READDIR_R) && defined(OF_HAVE_THREADS) - if (!of_mutex_lock(&readdirMutex)) - @throw [OFLockFailedException exception]; + [readdirMutex lock]; # endif - @try { for (;;) { struct dirent *dirent; # ifdef HAVE_READDIR_R struct dirent buffer; @@ -350,12 +343,11 @@ objc_autoreleasePoolPop(pool); } } @finally { closedir(dir); # if !defined(HAVE_READDIR_R) && defined(OF_HAVE_THREADS) - if (!of_mutex_unlock(&readdirMutex)) - @throw [OFUnlockFailedException exception]; + [readdirMutex unlock]; # endif } #else void *pool = objc_autoreleasePoolPush(); HANDLE handle; @@ -478,10 +470,24 @@ /* FIXME: We could be more precise on some OSes */ return [OFDate dateWithTimeIntervalSince1970: s.st_ctime]; } #ifdef OF_HAVE_CHMOD +- (mode_t)permissionsOfItemAtPath: (OFString*)path +{ + of_stat_t s; + + if (path == nil) + @throw [OFInvalidArgumentException exception]; + + if (of_stat(path, &s) != 0) + @throw [OFStatItemFailedException exceptionWithPath: path + errNo: errno]; + + return s.st_mode; +} + - (void)changePermissionsOfItemAtPath: (OFString*)path permissions: (mode_t)permissions { if (path == nil) @throw [OFInvalidArgumentException exception]; @@ -498,10 +504,50 @@ errNo: errno]; } #endif #ifdef OF_HAVE_CHOWN +- (void)getOwner: (OFString**)owner + group: (OFString**)group + ofItemAtPath: (OFString*)path +{ + of_stat_t s; + + if (path == nil) + @throw [OFInvalidArgumentException exception]; + + if (of_stat(path, &s) != 0) + @throw [OFStatItemFailedException exceptionWithPath: path + errNo: errno]; + +# ifdef OF_HAVE_THREADS + [passwdMutex lock]; + @try { +# endif + of_string_encoding_t encoding = + [OFSystemInfo native8BitEncoding]; + + if (owner != nil) { + struct passwd *passwd = getpwuid(s.st_uid); + + *owner = [OFString stringWithCString: passwd->pw_name + encoding: encoding]; + } + + if (group != nil) { + struct group *group_ = getgrgid(s.st_gid); + + *group = [OFString stringWithCString: group_->gr_name + encoding: encoding]; + } +# ifdef OF_HAVE_THREADS + } @finally { + [passwdMutex unlock]; + } +#endif +} + - (void)changeOwnerOfItemAtPath: (OFString*)path owner: (OFString*)owner group: (OFString*)group { uid_t uid = -1; @@ -512,13 +558,11 @@ @throw [OFInvalidArgumentException exception]; encoding = [OFSystemInfo native8BitEncoding]; # ifdef OF_HAVE_THREADS - if (!of_mutex_lock(&chownMutex)) - @throw [OFLockFailedException exception]; - + [passwdMutex lock]; @try { # endif if (owner != nil) { struct passwd *passwd; @@ -546,12 +590,11 @@ gid = group_->gr_gid; } # ifdef OF_HAVE_THREADS } @finally { - if (!of_mutex_unlock(&chownMutex)) - @throw [OFUnlockFailedException exception]; + [passwdMutex unlock]; } # endif if (chown([path cStringWithEncoding: encoding], uid, gid) != 0) @throw [OFChangeOwnerFailedException exceptionWithPath: path