objective c - Clang NSTask with streams -


never-mind "why?","useless?", , "don't bother" comments. want compile program inside program using clang. can create nstask , set arguments , work if file exists, (ie. no stream), , writes physical file. haven't been able use streams both input , output. know both clang , gcc allow compiling stdin if use -xc , - options unable implement feature using pipes. not sure how redirect clang's output file handle or stream.

here code have compiles , generates correct output in outfile

task = [[nstask alloc] init];  nspipe* outputpipe = [[nspipe alloc] init]; [task setstandardoutput:outputpipe ]; [task setstandarderror: [task standardoutput]];  nspipe* inpipe = [nspipe pipe]; [task setstandardinput:inpipe];   [task setlaunchpath:@"/usr/bin/clang"]; nsstring* outfile= [nsstring stringwithformat:@"%@.out",[[filename lastpathcomponent] stringbydeletingpathextension]];  //[data writetofile:@"file.c" atomically:yes]; [task setarguments:[nsarray arraywithobjects:filename,@"-s",@"-o",outfile,nil]];   [[nsnotificationcenter defaultcenter] addobserver:self                                           selector:@selector(getdata:)                                               name: nsfilehandlereadcompletionnotification                                             object: [[task standardoutput] filehandleforreading]];  [[[task standardoutput] filehandleforreading] readinbackgroundandnotify];  [task launch]; 

i have tried using input stream:

/* on pipe creation*/ dup2([[inpipe filehandleforreading] filedescriptor], stdin_fileno); nsfilehandle* curinputhandle = [inpipe filehandleforwriting]; /* tried before launch , after, no output sits */  [curinputhandle writedata:[nsdata datawithcontentsoffile:filename]]; 

sometimes, assume when pipe closes while nstask still in existance output file created , run. makes me think clang waiting stdin close. there way close pipe when data has been read?

for output have tried use nspipe's filehandleforwriting parameter of -o, gives error of [nsconcretepipe filesystemrepresentation] unrecognized selector. have tried creating file handle file descriptor of stdout same error. don't know of command line argument redirects it. i've tried using | redirect haven't been able work. if there unix magic redirect can dup stdout anywhere want.

so there way close pipe when data read? , redirect clangs output? if there other way accomplish same thing easier or cleaner open implementation. on these 2 items great.

it not clear me problem or you've tried. however, if going read output pipe on main thread using notifications , wish write pipe 1 option write pipe in thread. code below, based on code, using gcd. simplicity in example binary deposited in /tmp:

// send simple program clang using gcd task - (void)providestdin:(nsfilehandle *)stdinhandle {    dispatch_queue_t aqueue = dispatch_get_global_queue(dispatch_queue_priority_default, 0);    dispatch_async(aqueue, ^{       [stdinhandle writedata:[@"int main(int argc, char **argv)\n" datausingencoding:nsutf8stringencoding]];       [stdinhandle writedata:[@"{\n" datausingencoding:nsutf8stringencoding]];       [stdinhandle writedata:[@"   write(1, \"hello\\n\", 6);\n" datausingencoding:nsutf8stringencoding]];       [stdinhandle writedata:[@"}\n" datausingencoding:nsutf8stringencoding]];       [stdinhandle closefile];   // sent code, close file (pipe in case)    }); }  // read output clang , dump console - (void) getdata:(nsnotification *)notifcation {    nsdata *dataread = [[notifcation userinfo] objectforkey:nsfilehandlenotificationdataitem];    nsstring *textread = [[nsstring alloc] initwithdata:dataread encoding:nsutf8stringencoding];    nslog(@"read %3ld: %@", (long)[textread length], textread); }  // invoke clang using nstask, reading output via notifications // , providing input via async gcd task - (void)applicationdidfinishlaunching:(nsnotification *)anotification {    nstask *task = [nstask new];     nspipe *outputpipe = [nspipe new];    [task setstandardoutput:outputpipe];    [task setstandarderror:outputpipe];    nsfilehandle *outputhandle = [outputpipe filehandleforreading];     nspipe* inpipe = [nspipe pipe];    [task setstandardinput:inpipe];     [task setlaunchpath:@"/usr/bin/clang"];     [task setarguments:[nsarray arraywithobjects:@"-o", @"/tmp/clang.out", @"-xc",@"-",nil]];     [[nsnotificationcenter defaultcenter] addobserver:self                                              selector:@selector(getdata:)                                                  name:nsfilehandlereadcompletionnotification                                                object:outputhandle];     [outputhandle readinbackgroundandnotify];     [task launch];    [self providestdin:[inpipe filehandleforwriting]]; } 

Comments

Popular posts from this blog

django - How can I change user group without delete record -

java - Need to add SOAP security token -

java - EclipseLink JPA Object is not a known entity type -