thread output into pterm window

Hello,

I want to apply a menu thread in my application which receives and executed
user commands for the application. As it seems inconvenient to mix the
application outputs with the menu outputs and user inputs, I’d like to
separate them in different pterm windows.
Having implemented a menu functionality (in a separate thread inside the
application process), I’m wondering how it was now possible to open a new
pterm window (from the menu thread) and redirect the printf() output
together wirh the inputs for this menu thread to the newly opened pterm
window. Using [system( “pterm &” )] does not work, because I don’t get
access to the new window.

Does anybody have a little hint for me?

Thanks.

Nnamdi

Nnamdi Kohn wrote:

I want to apply a menu thread in my application which receives and executed
user commands for the application. As it seems inconvenient to mix the
application outputs with the menu outputs and user inputs, I’d like to
separate them in different pterm windows.

Is your application a Photon application? If it is, it may be better to
just add a window and put a PtTty or PtTerminal widget in it. This
would give you more control and allow you to add more widgets to the
window. You might even decide to throw away the code that displays the
menu in a terminal, and use Photon widgets to implement a GUI menu…

If, on the other hand, you want your application to be a non-Photon
program that uses its stdin and stdout to talk to the terminal it was
started on, then you have to think about what happens when someone runs
it in text mode. Or in a telnet session, on a machine that may happen
to be running Photon but the person running the telnet is not even in
the same room as the person running the Photon. Do you care about such
situations? Because if you don’t, then you’re relying on Photon anyway,
and turning your application into a full-blown Photon app may make your
job easier, and your app look better.

Having implemented a menu functionality (in a separate thread inside the
application process), I’m wondering how it was now possible to open a new
pterm window (from the menu thread) and redirect the printf() output
together wirh the inputs for this menu thread to the newly opened pterm
window. Using [system( “pterm &” )] does not work, because I don’t get
access to the new window.

Does anybody have a little hint for me?

There are countless possibilities. If you decide to spawn a pterm after
all, you can use a pipe and the -N option to ask pterm to tell you the
path to the pseudo-terminal it’s connected to. You’d need to do
something along the lines of

FILE *menu_fp, *pterm_pipe;
pterm_pipe = popen( “pterm -N1” );
fgets( namebuf, sizeof(namebuf), pterm_pipe );
menu_fp = fopen( namebuf, “r+” );

Of course, you might want to add some error checking to the above. And
if you want to be able to kill the pterm when you’re done, you’ll need
to disassemble the popen() into a separate pipe() call that gives you
the pipe and a spawn() call that gives you the pid. But like I said,
turning your application into a real Photon app with its own widgets
instead of a pterm might make these details cleaner and easier.

Is your application a Photon application?

no, it is an ordinary c-application that uses a simple pterm window for
display/input.

Or in a telnet session, on a machine that may happen
to be running Photon but the person running the telnet is not even in
the same room as the person running the Photon. Do you care about such
situations?

No, but it is not intended to control the central application from an other
computer (e.g. via telnet). The MENU is normally (together with the
application) placed and operated on one machine.

Because if you don’t, then you’re relying on Photon anyway,
and turning your application into a full-blown Photon app may make your
job easier, and your app look better.

I could try this in a second step. I’d like to develop the functions at
first, so that it would be easier to migrate to a Photon environment without
having to remove the errors from both sources (Photon and Application).

FILE *menu_fp, *pterm_pipe;
pterm_pipe = popen( “pterm -N1” );
fgets( namebuf, sizeof(namebuf), pterm_pipe );
menu_fp = fopen( namebuf, “r+” );

I’ve tried it in different ways but the pterm window is always “idle”. What
could the reason be? My problem might be that I don’t know how to exactly
get read/write access to a pterm. I finally want to fprintf( fp1, “…”,
… ) and fgets( buf, sizeof( buf ), fp2 ).

Nnamdi

“Nnamdi Kohn” <nnamdi.kohn@tu-bs.de> wrote in message
news:c8285o$t2p$1@inn.qnx.com

FILE *menu_fp, *pterm_pipe;
pterm_pipe = popen( “pterm -N1” );
fgets( namebuf, sizeof(namebuf), pterm_pipe );
menu_fp = fopen( namebuf, “r+” );

I’ve tried it in different ways but the pterm window is always “idle”.

Do you mean the title bar says “idle”? That’s pterm’s way of telling you
that no process running on the terminal has been found. It’s because with
the -N option, pterm doesn’t start a shell on the terminal. That’s a good
thing – you don’t want a shell running on the terminal and messing with
your output, do you? :slight_smile: Just use the -t option to set a different title.

could the reason be? My problem might be that I don’t know how to exactly
get read/write access to a pterm. I finally want to fprintf( fp1, “…”,
… ) and fgets( buf, sizeof( buf ), fp2 ).

Replace the last line of my example with

fp1 = fopen( namebuf, “w” );
fp2 = fopen( namebuf, “r” );

haven’t managed to get it running. Here are some questioins:

pterm_pipe = popen( “pterm -N1”, “r” );

opens a terminal window but how do I know if the file_descriptor “1” is the
right one?

fgets( namebuf, sizeof(namebuf), pterm_pipe );

fgets() waits until ‘\n’ or MAX_SIZE-1, but “pterm -N1” does not close the
output with an ‘\n’. So fgets() seems to wait forever.

fp1 = fopen( namebuf, “w” );
fp2 = fopen( namebuf, “r” );

when I set namebuf to “/dev/ttypa” manually then the file pointers fp1 and
fp2 are set correctly to the opened window (opened with
open( “pterm…”)… ). But when I then fprintf( fp1,…) the output in the
screen is at the same time directed to fd2. So when I read a line with
fgets( …, fd2) it has no effect because the input buffer is already filled
with all the output lines.

Is there an other (maybe simpler) way to do it, so that the output is NOT
piped into the input again?

Nnamdi Kohn <nnamdi.kohn@tu-bs.de> wrote:
NK > haven’t managed to get it running. Here are some questioins:

pterm_pipe = popen( “pterm -N1”, “r” );

NK > opens a terminal window but how do I know if the file_descriptor “1” is the
NK > right one?

popen return a FILE *.
fileno( FILE ) will return a file descriptor


fgets( namebuf, sizeof(namebuf), pterm_pipe );

NK > fgets() waits until ‘\n’ or MAX_SIZE-1, but “pterm -N1” does not close the
NK > output with an ‘\n’. So fgets() seems to wait forever.

fp1 = fopen( namebuf, “w” );
fp2 = fopen( namebuf, “r” );

NK > when I set namebuf to “/dev/ttypa” manually then the file pointers fp1 and
NK > fp2 are set correctly to the opened window (opened with
NK > open( “pterm…”)… ). But when I then fprintf( fp1,…) the output in the
NK > screen is at the same time directed to fd2. So when I read a line with
NK > fgets( …, fd2) it has no effect because the input buffer is already filled
NK > with all the output lines.

NK > Is there an other (maybe simpler) way to do it, so that the output is NOT
NK > piped into the input again?


I don’t think I can help on your other issues.
I hope someone else can.

Nnamdi Kohn wrote:

haven’t managed to get it running. Here are some questioins:

pterm_pipe = popen( “pterm -N1”, “r” );

opens a terminal window but how do I know if the file_descriptor “1” is the
right one?

It’s popen()'s job to make sure that pterm’s file descriptor 1 is the
writable end of the pipe.

fgets( namebuf, sizeof(namebuf), pterm_pipe );

fgets() waits until ‘\n’ or MAX_SIZE-1, but “pterm -N1” does not close the
output with an ‘\n’. So fgets() seems to wait forever.

Oh yeah, I forgot about one detail: popen() spawns a shell, and the
shell spawns pterm, and even though pterm closes its fd, the shell keeps
its fd open, which prevents your fgets() from getting an EOF.

Change the command in the popen() call to “exec pterm -N1”. I just made
a little experiment that confirmed that that fixed the problem. If you
replace the popen() with your own pipe() and spawn() calls like I
suggested before, spawn pterm directly rather than a shell.

fp1 = fopen( namebuf, “w” );
fp2 = fopen( namebuf, “r” );

when I set namebuf to “/dev/ttypa” manually then the file pointers fp1 and
fp2 are set correctly to the opened window (opened with
open( “pterm…”)… ). But when I then fprintf( fp1,…) the output in the
screen is at the same time directed to fd2. So when I read a line with
fgets( …, fd2) it has no effect because the input buffer is already filled
with all the output lines.

I’m not sure if I understand you correctly, but it doesn’t sound like
what should happen.

Is there an other (maybe simpler) way to do it, so that the output is NOT
piped into the input again?

Here’s a little program that works for me. Does it not work for you?

#include <stdio.h>

int main( void ) {
char buf[ 120 ];
FILE *pterm_pipe, *fp1, *fp2;
if ( ( pterm_pipe = popen( “exec pterm -N1”, “r” ) ) == NULL
|| fgets( buf, sizeof(buf), pterm_pipe ) == NULL
|| ( fp1 = fopen( buf, “w” ) ) == NULL
|| ( fp2 = fopen( buf, “r” ) ) == NULL
) {
perror( “Something went wrong” );
return 1;
}
printf( “Opened ‘%s’\n”, buf );
fputs( “Type stuff into this window\n”, fp1 );
while ( fgets( buf, sizeof(buf), fp2 ) ) {
printf( “You typed ‘%s’\n”, buf );
fputs( “I got it, type more or hit Ctrl-D\n”, fp1 );
}
puts( “Got an EOF, exiting” );
return 0;
}

#include <stdio.h

int main( void ) {
char buf[ 120 ];
FILE *pterm_pipe, *fp1, *fp2;
if ( ( pterm_pipe = popen( “exec pterm -N1”, “r” ) ) == NULL
|| fgets( buf, sizeof(buf), pterm_pipe ) == NULL
|| ( fp1 = fopen( buf, “w” ) ) == NULL
|| ( fp2 = fopen( buf, “r” ) ) == NULL
) {
perror( “Something went wrong” );
return 1;
}
printf( “Opened ‘%s’\n”, buf );
fputs( “Type stuff into this window\n”, fp1 );
while ( fgets( buf, sizeof(buf), fp2 ) ) {
printf( “You typed ‘%s’\n”, buf );
fputs( “I got it, type more or hit Ctrl-D\n”, fp1 );
}
puts( “Got an EOF, exiting” );
return 0;
}

thank you. This works perfectly for me.