system() call mit Objectiv-C

Um aus einem Cocoa-Programm ein externes Programm aufrufen gibt es mehrere Möglichkeiten. Natürlich kann man den etwas kompizierten Weg über fork etc. gehen. Speziell vfork handelt unter MacOS 10.5 aber scheinbar Shared Memory Resourcen nicht korrekt. Deshalb hier noch einige andere interessante Möglichkeiten, um einen externen Prozess aus einer Anwendung uter MacOS zu starten.

Klassisch per system(3)


Direkt per POSIX call - system(3) - der Rückgabewert ist aber nur ein Byte und entspricht dem gleichen Rückgabewert auf der Konsole (echo $?). Man kann in diesen Fall jedoch nicht auf die Ausgabe des Befehls direkt zugreifen.

const char *buf = "/bin/mkdir -p /tmp/hallo/welt";
system(buf);



Mittels NSTask


In Objectiv-C kann man sich der Klasse NSTask bedienen. Das ist genauso einfach und praktisch wie system(3).

NSString *cmd = @“/bin/mkdir -p /tmp/hallo/welt“;
[[
NSTask launchedTaskWithLaunchPath:@"/bin/sh"
arguments:[NSArray arrayWithObjects:@"-c", cmd, nil]]
waitUntilExit];


Mit Rechten und AuthorizationExecuteWithPrivileges


Will man jedoch einen Prozess mit speziellen Rechten starten, so hilft system(3) und NSTask nicht wirklich weiter. Hier hilft die Klasse SFAuthorization und die Funktion AuthorizationExecuteWithPrivileges().
Speziell wenn man etwas mit Admin-Rechten starten will ist das sehr praktisch. Das SFAuthorization Widget kann man bei Bedarf auch mittels Interface Builder gut platzieren und bekommt dann das aus den Systemsteuerungsapplets bekannte „Schloss-Widget“.

Folgende Methode sollte helfen und ist von der Signatur ähnlich zu NSTask.


- (bool)syscall:(SFAuthorization*)auth command:(NSString*)strCmd arguments:(NSArray*)args
{
AuthorizationRef authRef = [auth authorizationRef];
OSStatus err;
FILE *fd =
NULL;
int argc = [args count];
char **argv = (char **)malloc(sizeof(char *) * (argc + 1));
int i;
for(i=0; i argv[i] = (char *) [[[args objectAtIndex:i] description] UTF8String];
}
argv[i] =
NULL;

err =
AuthorizationExecuteWithPrivileges(
authRef,
[strCmd
UTF8String],
kAuthorizationFlagDefaults,
argv, &fd);
free(*argv);
return (err ==0) ? true : false;
}