Thread: forcing stdout of external program to be line-buffered

  1. #1
    Registered User
    Join Date
    Sep 2006
    Posts
    3

    forcing stdout of external program to be line-buffered

    Hi, first off, this might be platform-dependant, and if so, I need it to work in windows - what I need it for already works in linux, so...

    ok, here's the background... I wrote (as have many others during the last many years) a console-based program that uses ansi escape sequences for prettying up the output, and that's just great - except that windows stopped supporting it in >=NT, and though hacks seem to be able to make NT support it, I've found nothing to re-enable it in XP

    I proceded to write a wrapper program, that could be used like so: app | wrapper; making any app using the sequences able to function in XP too (the wrapper simply translates the sequences into approprate windows function-calls)*

    as it happens, my program, and (I would assume) most others written as console-applications, don't explicitly fflush stdout all that often, simply because it isn't needed in a linebuffered environment - stuff like printing \n or calling getchar() (especially the latter creates a problem) will automatically flush it for you...

    the problem is, that when I pipe the output to my wrapper, the original programs stdout becomes block buffered by default - (then the user probably won't see any output till the app exits, and that's a problem when you require him to input data) in the case of my program, I can easily change that, but I'd like to be able to run any legacy application through my wrapper...

    that said, it seems to me that what I need is either some fancy trick to make the original program run with a linebuffered stdout, or - something in the region of (in posix-terminology) in the simplest form, creating a(nother?) wrapper that forks, execv()'s the original application, and then either somehow from the parent sets the child pid's stdout to linebuffered (setlinebuf()), or having the childs stdout point to a buffer in the parent which is under local control...

    I'm open to alternaive suggestions, but those two were the ones I found most probable as solutions
    Any ideas how I could possibly achieve this?

    Thanks in advance, Christian Sonne

    *=and no, it's not a complete implementation, but most of it works... :-)

    PS: if code-examples for a simple wrapper, and a simple app that demonstrates the problem would be usefull, I'll gladly submit that - they're both trivial, so for now I'll leave them out, so this post doesn't get even longer...

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You can get the ANSI escape sequences to work under any Windows version by having ANSI.SYS present in the path as far as I know. [edit] http://en.wikipedia.org/wiki/ANSI.SYS [/edit]

    The only way I can see your wrapper working is to open a pipe, so that your wrapper can control input and output to the ANSI program. The POSIX (read: Linux) function popen() lets you do this, I think. This can lead to a race condition quite easily (each program is waiting for output of the other), but probably not with your wrapper because of the way it's designed. [edit] http://www.opengroup.org/pubs/online...xsh/popen.html [/edit]
    Last edited by dwks; 09-16-2006 at 06:32 PM.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    3
    Quote Originally Posted by dwks
    You can get the ANSI escape sequences to work under any Windows version by having ANSI.SYS present in the path as far as I know. [edit] http://en.wikipedia.org/wiki/ANSI.SYS [/edit]
    As I said, that was true untill <=NT, but could be hacked into NT still - all my attempts have been unsuccessful in trying the same methods in XP...

    this page also states that it's not supported: http://en.wikipedia.org/wiki/ANSI_escape_code

    Quote Originally Posted by dwks
    The only way I can see your wrapper working is to open a pipe, so that your wrapper can control input and output to the ANSI program. The POSIX (read: Linux) function popen() lets you do this, I think. This can lead to a race condition quite easily (each program is waiting for output of the other), but probably not with your wrapper because of the way it's designed. [edit] http://www.opengroup.org/pubs/online...xsh/popen.html [/edit]
    I'll look into that, but for now, I only really need output from the original program to be piped into the wrapper - nothing needs to go the other way... - in that situation, do you still think popen() is the only way to go?

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I'll look into that, but for now, I only really need output from the original program to be piped into the wrapper - nothing needs to go the other way... - in that situation, do you still think popen() is the only way to go?
    Yes, something needs to go the other way if your legacy program takes any user input. (It doesn't just print something and then exit, does it? The user most likely has to type something.) That being the case, I definitely recommend popen() (or the Win32 equivalent). [edit] I don't know if it's the only way, but it's the only one I'm aware of. [/edit]
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    3
    Quote Originally Posted by dwks
    Yes, something needs to go the other way if your legacy program takes any user input. (It doesn't just print something and then exit, does it? The user most likely has to type something.)
    Well, if you type: originalapp | wrapper
    then originalapp will still recieve any user input on stdin, only stdout for it changes to a block-buffer that's redirected into wrapper... - wrappers stdin will then be the outputstream from originalapp

    technically, ansi escape sequences support sending back information to originalapp's stdin, and if I needed support for that, then you'd be right...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  2. help again with scrolling without wrapping
    By Dukefrukem in forum C Programming
    Replies: 8
    Last Post: 09-21-2007, 12:48 PM
  3. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 12:13 AM
  4. debug to release modes
    By DavidP in forum Game Programming
    Replies: 5
    Last Post: 03-20-2003, 03:01 PM
  5. Validating the contents of a char buffer
    By mattz in forum C Programming
    Replies: 3
    Last Post: 12-09-2001, 06:21 PM