Launching the process and writing to it directly through Cocoa doesn't leave any zombie processes:
Code:
task = CocoaMessage(0,CocoaMessage(0,0,"NSTask alloc"),"init")
CocoaMessage(0,task,"setLaunchPath:$",@"/bin/echo")
writePipe = CocoaMessage(0,0,"NSPipe pipe")
writeHandle = CocoaMessage(0,writePipe,"fileHandleForWriting")
CocoaMessage(0,task,"setStandardInput:",writePipe)
CocoaMessage(0,task,"launch")
string = CocoaMessage(0,0,"NSString stringWithString:$",@"111")
string = CocoaMessage(0,string,"dataUsingEncoding:",#NSUTF8StringEncoding)
CocoaMessage(0,writeHandle,"writeData:",string)
CocoaMessage(0,writeHandle,"closeFile")
CocoaMessage(0,task,"release")
UPD: I'm aware that passing an argument and writing to stdin are two different things, i just wasn't sure what #PB_Program_Write does under the hood so i decided it would make sense to write a full writing procedure on Cocoa.