Re: Debugging Stdout
Re: Debugging Stdout
- Subject: Re: Debugging Stdout
- From: Alastair Houghton <email@hidden>
- Date: Tue, 4 Oct 2005 14:27:47 +0100
On 4 Oct 2005, at 13:20, Frode wrote:
Hello!
I'm not sure but maybe your problem is that bytes piped to another
tool's input is consumed by that input and not copied to your data-
available notification (NSFileHandleReadCompletionNotification/
NSFileHandleReadToEndOfFileCompletionNotification) other than the
last EOF-notification? I don't know if there is any other way than
creating another piped NSTask in your debugging code, where you
execute an own implemented tool, say "broadcast_stdin" with
arguments specifiying destination outputs. For example, in the
shell it would look like
#original command: ls -R / | less -RSe
ls -R / | broadcast_stdin /dev/stdout myfile.txt | less -RSe
Rather than having to write a "broadcast_stdin" program, you might
consider
"tee" (see man tee):
ls -R / | tee myfile.txt | less -RSe
Similarly for the debugging problem, you could interpose a tee task
in the pipeline; instead of
NSTask *a, *b;
NSPipe *pipe = [NSPipe pipe];
[a setStandardOutput:[pipe fileHandleForWriting]];
[b setStandardInput:[pipe fileHandleForReading]];
...
[a launch];
[b launch];
you might write
NSTask *a, *tee, *b;
NSPipe *pipe_in = [NSPipe pipe], *pipe_out = [NSPipe pipe];
[a setStandardOutput:[pipe_in fileHandleForWriting]];
[tee setStandardInput:[pipe_in fileHandleForReading]];
[tee setStandardOutput:[pipe_out fileHandleForWriting]];
[b setStandardInput:[pipe_out fileHandleForReading]];
...
[tee setLaunchPath:@"/usr/bin/tee"];
...
[a launch];
[tee launch];
[b launch];
It should be obvious enough how to conditionalise it so it is
equivalent to the first form when you don't want to debug the data
going through the pipe.
As far as the original question (why a C program might behave
differently than a Perl program), the following things spring to mind:
1. Is the C program using buffered I/O? (See the man page for
"setvbuf".) If so, it may simply be that you aren't seeing the
output because the C program hasn't flushed standard out. You *can*
have this problem with Perl as well if you don't tell it not to
buffer output, but it's likely to happen at a different frequency.
2. Are you sure the C program is outputting to standard out and not
standard error? If it turns out to be the latter, you can just add
[a setStandardError:[pipe_in fileHandleForWriting]];
to the code above. (Yes, it's OK to set both standard out and
standard error to point to the same place.)
3. Particularly if the C program is normally run as a daemon, it may
play silly tricks like closing all of its file handles and
redirecting them to particular devices. If that's the problem,
there's normally a switch to stop programs from doing these sorts of
things.
4. Another possibility is that the C program is checking for a
terminal and only outputs the things you want to see if it's attached
to a terminal (as opposed to a pipe). If you're in that situation
and you can't find a way to tell the C program otherwise, you'll need
to use a pty rather than a pipe.
Chances are it's problem (1), not (2), (3) or (4), especially if you
wrote the C program yourself.
(The code above isn't supposed to be a model example of how to do
things... calling variables "a" and "b" isn't usually a very good
plan, except possibly in mathematical algorithms.)
Kind regards,
Alastair.
--
http://www.alastairs-place.net
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden