readInBackgroundAndNotify and rsync output
readInBackgroundAndNotify and rsync output
- Subject: readInBackgroundAndNotify and rsync output
- From: Robert DuToit <email@hidden>
- Date: Fri, 28 Jan 2011 17:53:54 -0500
Hi All,
I am relatively new to OBJ-C and have been struggling for several weeks to get Authorization , via BetterAuthorizationSample, to integrate with my project. Basically I am launching rsync via a helper tool and launchd and need to parse the output which is returned to the main app via the BAS response as a file descriptor. I set up a notification using readInBackgroundAndNotify .
This works but parsing the data slows down rsync. If the app freezes for any reason rsycn stops. I am used to using NSTask which works great but can not be used to launch a command via BAS. I don't quite understand the connection here with the main app and rsync since the parent process of rsync seems to be launchd but parsing the file descriptor output in the main app slows rsync. Or maybe this is just the two way nature of file descriptors and output, that you can't put the brakes on the output.
Originally I had the BAS request to launch rsync in a separate thread but couldn't find a way to use that with a readInBackgroundAndNotify Notification so I put the parsing into a loop - however it caused a big spike in cpu and sometimes froze up the UI after a long haul. I have found using readInBackgroundAndNotify doesn't do this but also won't work in a separate thread...
So I guess my question is if anyone has any ideas about either running rsync in a detached way from the helper tool (I thought that is what was happening!) or in the main app being able to read the output independently of rsync so it doesn't affect the performance. This is all within the context of BAS so keep that in mind. Happy to supply more information as needed I am also learning C as I go...
Thanks so much, Rob
//I have left out all the BAS code since it works and there is a lot of it.
//In the main app I get the returned file descriptor from the Helper Tool ( see below) via BAS
rsyncOutDescriptor = [[[response objectForKey:@kBASDescriptorArrayKey] objectAtIndex:0] intValue];
rsyncOutput = [[[NSFileHandle alloc] initWithFileDescriptor:rsyncOutDescriptor] autorelease];
NSNotificationCenter *taskNote = [NSNotificationCenter defaultCenter];
[taskNote removeObserver:self];
[taskNote addObserver:self selector:@selector(readPipe:) name:NSFileHandleReadCompletionNotification object:rsyncOutput];
[rsyncOutput readInBackgroundAndNotify];
// and then read it...
-(void)readPipe:(NSNotification *)aNotification{
NSData *theData = [[aNotification userInfo] objectForKey:NSFileHandleNotificationDataItem];
tempText = [[NSString alloc] initWithData:theData encoding:NSASCIIStringEncoding];
//parse the text and feed into progress text fields and progress indicator...
[rsyncOutput readInBackgroundAndNotify];
[tempText release];
}
//in the Helper Tool this routine launches rsync via execv() the output is returned in the main handler to the main app via the BAS structure - I borrowed this bit from Alex Pretzlav's Yarg open source code for his app "Yarg."
static int runRsync(const char *args, pid_t *pid, aslclient asl, aslmsg aslMsg) {
int child_pid;
int rsyncPipe[2];
char * shArgs[] = {
"sh", "-c", NULL, NULL
};
if (pipe(rsyncPipe) != 0) {
return -1;
}
child_pid = fork();
if (child_pid == 0) { /* Child */
if (dup2(rsyncPipe[1], STDOUT_FILENO) < 0) {
exit(-1);
}
close(rsyncPipe[0]);
if (close(rsyncPipe[1]) != 0) {
exit(-1);
}
shArgs[2] = (char *) args;
setsid();
execv("/bin/sh", shArgs); /* Never returns */
exit(-1);
} else if (child_pid < 0) {
return -1;
}
*pid = child_pid;ild_pid;
close(rsyncPipe[1]);
return rsyncPipe[0];
}_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden