@@ -17,14 +17,20 @@ #include #include #include #include + +#ifndef _WIN32 +# include +# include +#endif #import "OFFile.h" #import "OFString.h" #import "OFArray.h" +#import "OFThread.h" #import "OFAutoreleasePool.h" #import "OFExceptions.h" #import "macros.h" #ifdef _WIN32 @@ -52,10 +58,14 @@ #define DIR_MODE DEFAULT_MODE | S_IXUSR | S_IXGRP | S_IXOTH OFFile *of_stdin = nil; OFFile *of_stdout = nil; OFFile *of_stderr = nil; + +#ifndef _WIN32 +static OFMutex *mutex; +#endif static int parse_mode(const char *mode) { if (!strcmp(mode, "r")) return O_RDONLY; @@ -96,10 +106,18 @@ of_stdin = [[OFFileSingleton alloc] initWithFileDescriptor: 0]; of_stdout = [[OFFileSingleton alloc] initWithFileDescriptor: 1]; of_stderr = [[OFFileSingleton alloc] initWithFileDescriptor: 2]; } + +#ifndef _WIN32 ++ (void)initialize +{ + if (self == [OFFile class]) + mutex = [[OFMutex alloc] init]; +} +#endif + fileWithPath: (OFString*)path mode: (OFString*)mode { return [[[self alloc] initWithPath: path @@ -285,14 +303,53 @@ #endif } #ifndef _WIN32 + (void)changeOwnerOfFile: (OFString*)path - toOwner: (uid_t)owner - group: (gid_t)group + toOwner: (OFString*)owner + group: (OFString*)group { - if (chown([path cString], owner, group)) + uid_t uid = -1; + gid_t gid = -1; + + if (owner == nil && group == nil) + @throw [OFInvalidArgumentException newWithClass: self + selector: _cmd]; + + [mutex lock]; + + @try { + if (owner != nil) { + struct passwd *pw; + + if ((pw = getpwnam([owner cString])) == NULL) + @throw [OFChangeFileOwnerFailedException + newWithClass: self + path: path + owner: owner + group: group]; + + uid = pw->pw_uid; + } + + if (group != nil) { + struct group *gr; + + if ((gr = getgrnam([group cString])) == NULL) + @throw [OFChangeFileOwnerFailedException + newWithClass: self + path: path + owner: owner + group: group]; + + gid = gr->gr_gid; + } + } @finally { + [mutex unlock]; + } + + if (chown([path cString], uid, gid)) @throw [OFChangeFileOwnerFailedException newWithClass: self path: path owner: owner group: group]; }