• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Dumping input to NSTask
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Dumping input to NSTask


  • Subject: Re: Dumping input to NSTask
  • From: "Louis C. Sacha" <email@hidden>
  • Date: Thu, 15 Jul 2004 04:12:14 -0700

Hello...

After messing around with this a bit, I discovered that I was wrong about NSTask automatically closing the write end of the pipe used as the standard input for the task when the task is launched, so you don't need to write all of the input data to the pipe before launching the task. I'm not really sure how that got stuck in my head, but it didn't make sense once I stopped to think through how things would have to work (and would be a really bad idea if the input data size was more than the pipe buffer size).


I'm pretty sure that the reason you are having problems with the particular executable you are running with NSTask is that it reads data until it recieves the endOfData signal, which never happens because the file descriptor is not closed.

I hope that there is a better way to accomplish it, but one (very unsupported) workaround would be to do this after you finish writing all of your data to the standard input pipe:

(you will need to #include "unistd.h")

NSFileHandle *input = [[yourTask standardInput] fileHandleForWriting];
close([input fileDescriptor]);
[input setValue:[NSNumber numberWithUnsignedShort:1] forKey:@"_flags"];

This manually closes the fileDescriptor of the NSFileHandle, and then changes the flag that NSFileHandle uses to determine if it is supposed to close the file descriptor when the NSConcreteFileHandle instance is dealloc'ed.

I don't know if doing this has any negative effects on any of the other objects involved, and it relies on the internal implementation details of a private concrete subclass, so I wouldn't rely on it continuing to work in the future. If creating a temporary file is an acceptable option, that might be a better way to go.


And here's the fixed version of my little summary of running a task:

1) Create the instance of NSTask used for running the task, and set the basic things like path, arguments, etc...

2) Create input and output pipes if you need to send input or get output, and use the NSTask setInput: and setOutput: instance methods so that they will be connected to your task.

**3) Launch the task.

**4) If you need to send input get the NSFileHandle from the NSPipe for the input, and write the data to it.
**4b) ...(optionally, close the file descriptor if the tool requires it)...

5) Wait until the task finishes or check for available data using a timer or the notifications, and get your output from the output pipes's NSFileHandle. If the size of the output is more than the pipe buffer size (8k ?) you will need to keep checking / reading the available data to make space in the buffer.

6) When the task is finished, you can check the result code from the tool using the terminationStatus instance method, but you need to be sure the task is actually done (using isRunning if you didn't use waitUntilExit) before you call it.


Hope that helps,

Louis
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.


  • Follow-Ups:
    • Re: Dumping input to NSTask
      • From: John Timmer <email@hidden>
References: 
 >Re: Dumping input to NSTask (From: John Timmer <email@hidden>)

  • Prev by Date: Re: Open Recent Menu Item
  • Next by Date: Starting a command line application
  • Previous by thread: Re: Dumping input to NSTask
  • Next by thread: Re: Dumping input to NSTask
  • Index(es):
    • Date
    • Thread