Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2007-04

Pipe buffering, accessing C-style stdin/stdout

5 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Ingemar Ragnemalm

Dear list,

I have been struggling for quite a while (that is weeks) to get proper pipe communication with a sublaunched program, using TProcess or straight pipe/fork/exec calls. This is under Mac OSX, but the problem should be similar under any Unix.

The problem is the buffering. Using stdio, the data is stalled until the stdio buffers are full. This is a big problem. Two-way communication is impossible, and the user feedback is delayed.

After a lot of googling and experimenting, I think I have managed to make it work, but only in C code, and I want it to run in Pascal. The key to make it work in C was to call setvbuf at the right time, to set the buffering mode for stdin/stdout. The problem with FPC is that I can't find any straightforward way to either get PFile-style stdin/stdout from the Text-style input/output (surely there is a connection?), or get the C globals.

I have searched through the fpc and Lazarus sources after the definitions and possible solutions, tried all ways I can find, but have not succeeded yet. But surely someone else has ran into this problem?

Shouldn't simply TProcess have unbuffered or line-buffering as default?

/Ingemar

Reply by email

Marco van de Voort
to Ingemar Ragnemalm
Show quoted text 7 lines
After a lot of googling and experimenting, I think I have managed to make it work, but only in C code, and I want it to run in Pascal. The key to make it work in C was to call setvbuf at the right time, to set the buffering mode for stdin/stdout. The problem with FPC is that I can't find any straightforward way to either get PFile-style stdin/stdout from the Text-style input/output (surely there is a connection?)

Yes. PFile _IS_ Text style. PFile is the C wrapper implementing buffer, Text the analogue Pascal buffering. I assume that settextbuf to 0 didn't work?

( http://www.freepascal.org/docs-html/rtl/system/settextbuf.html )

If that doesn't work, you need to go back to the raw unbuffered IO, do a IOCTL if necessary. FPOpen, FPClose, FPWrite, FPRead

Moreover, how does lazarus deal with this?

Reply by email

Vincent Snijders
to Marco van de Voort
Marco van de Voort wrote 17 lines
> After a lot of googling and experimenting, I think I have managed to > make it work, but only in C code, and I want it to run in Pascal. The > key to make it work in C was to call setvbuf at the right time, to set > the buffering mode for stdin/stdout. The problem with FPC is that I > can't find any straightforward way to either get PFile-style > stdin/stdout from the Text-style input/output (surely there is a > connection?) Yes. PFile _IS_ Text style. PFile is the C wrapper implementing buffer, Text the analogue Pascal buffering. I assume that settextbuf to 0 didn't work? ( http://www.freepascal.org/docs-html/rtl/system/settextbuf.html ) If that doesn't work, you need to go back to the raw unbuffered IO, do a IOCTL if necessary. FPOpen, FPClose, FPWrite, FPRead Moreover, how does lazarus deal with this?

I guess Lazarus doesn't care, as long as it gets all the information at the end. There is no bidirectional communication between Lazarus and the compiler.

Vincent

Reply by email

Michael Van Canneyt
to Ingemar Ragnemalm: I have been struggling for quite a while (that is weeks) to get proper pipe communication…
Ingemar Ragnemalm wrote 18 lines
Dear list, I have been struggling for quite a while (that is weeks) to get proper pipe communication with a sublaunched program, using TProcess or straight pipe/fork/exec calls. This is under Mac OSX, but the problem should be similar under any Unix. The problem is the buffering. Using stdio, the data is stalled until the stdio buffers are full. This is a big problem. Two-way communication is impossible, and the user feedback is delayed. After a lot of googling and experimenting, I think I have managed to make it work, but only in C code, and I want it to run in Pascal. The key to make it work in C was to call setvbuf at the right time, to set the buffering mode for stdin/stdout. The problem with FPC is that I can't find any straightforward way to either get PFile-style stdin/stdout from the Text-style input/output (surely there is a connection?), or get the C globals.

The only call which comes close is settextbuf(). If you set it to a smaller value, it will come close to being unbuffered. But performance will suffer from this. You can also call flush() after every write statement.

Show quoted text 5 lines
I have searched through the fpc and Lazarus sources after the definitions and possible solutions, tried all ways I can find, but have not succeeded yet. But surely someone else has ran into this problem? Shouldn't simply TProcess have unbuffered or line-buffering as default?

TProcess does not do any buffering. What is more, it's up to the called application to decide whether it buffers it's output or not, and TProcess does not have any control over that.

Michael.

Reply by email

Ingemar Ragnemalm

Sorry for not replying "in thread", I get the list as digest so I can't "reply" properly.

Show quoted text 7 lines
> The problem with FPC is that I > can't find any straightforward way to either get PFile-style > stdin/stdout from the Text-style input/output (surely there is a > connection?) Yes. PFile _IS_ Text style. PFile is the C wrapper implementing buffer, Text the analogue Pascal buffering. I assume that settextbuf to 0

didn't work?

I have tried that, but nothing good happened. I don't know how to apply that to Input/Output in a TProcess.

If that doesn't work, you need to go back to the raw unbuffered IO, do a IOCTL if necessary. FPOpen, FPClose, FPWrite, FPRead

That's what I have been struggling with (apart from TProcess); pipe, fork, dup, ioctl, read, write. I think I figured out how to access stdin/stdout (by
importing __sF and calculating offsets from the size of FILE - not very portable code) and used that for setvbuf. Can't one get stdin/stdout from Input/Output? They refer to the same buffers after all. Anyway, it doesn't seem to matter for my problem.

TProcess does not do any buffering. What is more, it's up to the called application to decide whether it buffers it's output or not, and TProcess does not have any control over that.

I had information claiming the contrary, that the caller can use setvbuf to control the buffering, and then exec to the other program. However, my attempts to do it are not successful so far, so I think you are quite right.

So I continue with pseudo-terminals. I found that the other day, and that might help. I spent yesterday working on it and the tests look promising, it might be the solution, at least for most Unixes.

/Ingemar

Reply by email