I’m working on an app that creates compressed disk images using dd and gzip. I have set up a working pipe between dd and gzip NSTask’s but I cannot figure out how to close the pipe. When the dd process completes, the pipe stays open and gzip continues to wait for more data. How can I close the pipe or the pipe’s fileHandleForWriting so that gzip receives the EOF it needs to terminate successfully?
Here’s a working abridged copy of the app code:
script AppDelegate
property parent : class "NSObject"
property NSPipe : class "NSPipe"
property NSNotificationCenter : class "NSNotificationCenter"
property ddTask : missing value
property gzipTask :missing value
property applicationPipe : missing value
property pipeHandle : missing value
property appTargetFileForWriting : missing value
property theButton : missing value
-- IBOutlets
property theWindow : missing value
on applicationWillFinishLaunching_(aNotification)
-- Insert code here to initialize your application before any files are opened
end applicationWillFinishLaunching_
on buttonClicked_(sender)
log "button click registered"
theButton's setEnabled_(0)
set fileManager to current application's NSFileManager's defaultManager()
try
fileManager's createFileAtPath_contents_attributes_("/tmp/test.img.gz", missing value, missing value)
log "target file created"
on error
log "file creation error"
end try
try
set appTargetFileForWriting to current application's NSFileHandle's fileHandleForWritingAtPath_("/tmp/test.img.gz")
log "target file handle set"
on error
log "error creating file handle"
end try
set ddTask to current application's NSTask's alloc()'s init()
set applicationPipe to NSPipe's pipe()
ddTask's setLaunchPath_("/bin/dd")
ddTask's setArguments_({"bs=4k","count=1000","if=/dev/random"})
ddTask's setStandardOutput_(applicationPipe)
NSNotificationCenter's defaultCenter()'s addObserver_selector_name_object_(me, "ddTerminationHandler:", "NSTaskDidTerminateNotification", ddTask)
set gzipTask to current application's NSTask's alloc()'s init()
gzipTask's setLaunchPath_("/usr/bin/gzip")
gzipTask's setArguments_({"--verbose"})
gzipTask's setStandardInput_(applicationPipe)
gzipTask's setStandardOutput_(appTargetFileForWriting)
NSNotificationCenter's defaultCenter()'s addObserver_selector_name_object_(me, "gzipTaskTerminationHandler:", "NSTaskDidTerminateNotification", gzipTask)
ddTask's |launch|()
gzipTask's |launch|()
end buttonClicked_
on ddTerminationHandler_(aNotification)
log "DD task completed"
--Close pipe here?
NSNotificationCenter's defaultCenter()'s removeObserver_name_object_(me, "NSTaskDidTerminateNotification", missing value)
end ddTerminationHandler_
on gzipTaskTerminationHandler_(aNotification)
log "gzip task completed"
appTargetFileForWriting's closeFile()
theButton's setEnabled_(1)
NSNotificationCenter's defaultCenter()'s removeObserver_name_object_(me, "NSTaskDidTerminateNotification", missing value)
end gzipTaskTerminationHandler_
on applicationShouldTerminateAfterLastWindowClosed_(sender)
return true
end applicationShouldTerminateAfterLastWindowClosed_
on applicationShouldTerminate_(sender)
return current application's NSTerminateNow
end applicationShouldTerminate_
end script
Sorry for the multiple posts. Was having network issues and must have created them trying to refresh the submission page.