output to a new terminal - c

Suppose I create a thread from my "main" thread, which aims to monitor and print some variables in "main". But "main" is also generating some output, so I want to print the outputs of these two threads separately. How can I redirect the output of the new thread to a new console other than the one "main" thread is using in my c program?

I would output the monitoring information to a file, then use tail -f filename to display it in my other terminal.
That has the advantage that you can run grep or what-have-you on the output as well.

I would go with writing the data to a log file and then using tail -f log_file.txt from another window to watch it since that way you get to keep a copy of the data, but if you decide that you need to use separate terminals then you can just open the new terminal (tty) like a regular file. The main problem with this is that you probably really want it to open a new terminal window for you as well.
Opening a new terminal window to do something like this is tricky and is different between different terminal emulators. Here is another question about opening new terminals from a make file. You could try doing the same thing from your program or from a script that runs your program and run cat or tail in the new terminal to be your log window.
#!/bin/sh
truncate --size=0 ./logfile.txt
xterm "tail -f ./logfile.txt" 2>&1 > /dev/null &
your_program --log-file=./logfile.txt
I don't currently know of a better way to accomplish this.
Another thing you might want to look into is syslog.

What would you expect to happen in such case (externally)?
If you run a program you are attached to a console. You of course don't have to write output to the console (you can use files), but the console cannot be duplicated obviously.
Isn't using a different file descriptor good enough for you?

Related

How do I copy everything from my terminal to a file including the stdout and the prompt using C?

I know how to get the stdout into a file using dup/dup2 system calls, but how do I get the entire output that would be normally shown on my terminal(including the prompt that says my username along with the $ symbol and the current working directory) to a file?
Yes you can, but this may be difficult in many details (depending on your expert level). For the shell to behave normally (I would mean exactly as in a terminal), then it needs to interact with a terminal (special system object). So you need to create a program that behave like a terminal, this what pseudo-terminals devices (/dev) are intended for. Read documentation about this to implement it but roughly, your application should behave like the user so should be connected to the slave side of the pseudo-terminal, and the shell to the master side of the pseudo-terminal. Then you can easily log real inputs made by the user and catch outputs made by the shell.
Can't comment cause of low reputation.
I would say there is no way to do that inside a code in C. Instead, you could use bash for example to redirect everything to a file, and leave the code in C as it is.
In this way you have all the info you want to save: prompt, current directory, call to the program (including flags), and of course the output of the program.
Well, you can do:
-For bash prompt PS1: Echo expanded PS1 (in case you want it expanded, if not there is a simple way to do it just echong PS1)
- For executed command: https://unix.stackexchange.com/questions/169259/how-to-capture-command-line-input-into-logfile-and-execute-it-at-the-same-time
- Standard output and error output: Redirect stderr and stdout in a Bash script
And that's all you want to capture, I think.
Look up the script command in Unix systems. If you want to capture all keyboard and std in/out for a command, use the script executable. If you want to see how it's done, look up the source.

C: open second custom sized terminal and use it for output

I am writing a program in C that is started simply by the terminal. Now I want to make the program itself open another terminal with a custom size and write its output in there.
I found the command
system("gnome-terminal");
which opens another terminal, but I can't find a function that lets me write into this second terminal. I am using Ubuntu.
If you have any idea, that would be great
The easiest thing would probably be to write the output to a file, say /tmp/tmp96888 (tip: mkstemp) and then do something like
system("gnome-terminal --geometry=40x14 --command 'less /tmp/tmp96888'");
Or, to update continuously from the file:
system("gnome-terminal --geometry=40x14 --command 'tail -f /tmp/tmp96888'");
But if you can, I think the best way is to open a new terminal and run the program itself in it, and just print the output. It's only if you actually need to do things in the original window that you have to bother with a separate output window.

Outputting to multiple terminals

I'm parsing a large log file. I would like to pull out particular messages based on a severity classification (critical, warning, etc). As I am parsing the log I would like to send messages, based on their severity, to a given, spawned, severity-specific, terminal. The terminals should not close when the main program finishes reading the log file. Environment is solaris 10/gcc 3.4.6. I found the following example that captures what I was thinking of, but doesn't quite work (xterm spawns, but no output is sent to it):
#include <stdio.h>
int main()
{
FILE *output;
int i;
output = popen ("xterm", "w");
for (i = 0; i < 10; i++)
fprintf (output, "%d\n", i);
pclose (output);
}
I'm not married to xterm, I simply used it as handy and I do like the ability to title, color and size them. I sort of get that writing to the handle generated by popen is not the same as writing to the terminal's output (just sort of...). This seems like an easy thing to do.
in general, what can be done is:
1) adjust your application so it can accept a parameter that indicates what level of severity to output to stdout.
2) open three terminals from the keyboard
3) run your application in each terminal, giving each execution the appropriate command line parameter
if your going to open the terminals from your application, for 'xterm' and others, the --hold parameter will stop the terminal from closing when you application exits
The idea of the pipe sounds reasonable, but there are a few problems:
you cannot, of course, simply write to a newly-spawned terminal via a pipe. xterm will ignore that; it is the application running within xterm which reads/writes from the pseudo-terminal.
there is no way to scroll back in the messages sent to a given terminal
the suggested writes to the pty device cannot be captured by a program running in the terminal
Rather than sending to a terminal, you might consider getting xless (a simple X application which might already be part of a package, but is simple enough to build), and structuring your output function to do this:
for each message category, open a pipe to xless once
write the message
do not close the pipe
That would give you windows which do not close. Here is a sample screenshot:
The source can be found on ftp.x.org, as noted in the Debian package description.
Thank you all for the great responses, I do appreciate them!
OK, sounds like a slight re-design is called for =) I did a quick prototype and it looks like it will work. Will write the output to separate severity files, then when complete, pop up an xterm for each file, something like
sprintf (Crit, "xterm <yadda yadda> -e sh -c 'cat <crit-log>; <yadda yadda>');
popen (Crit, "r");
Writing to intermediate log files is actually a bonus should they need to be reviewed at a later time without having to go through the large-log-parsing program again.
Thanks again everyone!

(Linux, C) Two threads, two separate text windows in the screen, how to do it?

I have two threads. The main thread and two others created with *pthread_create*, for instance thread_1 and thread_2.
The main thread writes the output in the terminal that i used to run the program. Then, i want to create two new windows, in which thread_1 and thread_2 will write some text.
i tried to use the system call "system()" and run "/bin/bash" but there is no new terminal appearing after that.
now, i am thinking to use some graphic library (g2, SDL...).
i searched the web for some hours and cant find a good solution. All i just need is to output text in independent windows, i don't want any kind of drawings, only text lines.
i am using Linux mint and C language.
Do you need the program to open the other two windows?
If not:
Have each thread write to a separate file.
Manually open two more windows.
Use the bash command 'tail -f' in each of the new windows to display the output of each file.
The closest non-gui solution that comes to mind is ncurses
Thanks for the advices.
I achieved a solution for my problem with the Jay's hint.
It's very simple. i put the program writing the data to a file. (closest to the fifo idea)
then, inside the program i run this:
system("mate-terminal -e --command='tail -f filename.txt'");
and voilá! It creates a new terminal window and runs the command tail -f.
Thanks for your answers, they helped me thinking in that solution. I tried the ncurses but had problems in installing the package and then compiling with the -lncurses flag. I will try ncurses someday, but now the problem is solved.
bye

Recording command line input and output on linux with C

Basically I want to do a program almost like a keylogger. The thing is that I as network admin sometimes I don't remember what I did to a machine on certain case, or same times I make howto's and tutorials for linux. I want to record what have i done.
So basically the idea of this program is:
you type the name of the program, (I call it rat for the moment)
$ rat
Welcome everything from now on will be recorded
recording $ ls
file1 file2 file3
recording $ quit
Bye bye
Everything you do will go out to an xml file. Something like this
<?xml version='1.0' encoding='UTF-8' ?>
<rat>
<command>
<input>ls</input>
<output>file1 file2 file3</output>
<err><err>
</command>
</rat>
i am doing some tests with fp_in = popen( input, "w");
and system, but first with popen i cant change directories and with "system i cant properly manage the input and output.
I was also checking if there is something I can do to bash like a plugin but haven't find any information.
At some points if feels like it I should create another shell (which is way beyond my current abilities) or fork bash sh. But it should been that complicated right.
I am open to suggestion where to start.
I am rusty with C, so I am reading again a lot of basic stuff.
With the xml file, later i was thinking on making a program to store this data and/or editing this data so i can create tutials and howto.
I can think of many ways of expanding this up to using printscreen so all the stored images go to a file you can upload to a server (for the moment i am glad to store the data). It could be a usefull tool.
ps. I do know this can be use for evil things too.
There already exists the script command, which will record all input and output into the terminal, writing it into a transcript. I would recommend just using that, unless you have particular needs that it doesn't meet. Actually, the nicest version of script that I've seen has been the NetBSD version, so you may want to look into that if the Linux version doesn't meet your needs.
If you would like to write it yourself, instead of using system, I would recommend that you use fork/exec to create a single shell process, which you copy all input and output into. To get an idea of how this works, I'd recommend looking at the source code for an existing version of script.
Most shells have a script built-in which will simply record the text in- and out- from the command line. Not quite what you're looking for... To my surprise script is not a built in, which means it is a model for building what you want.
The script command does almost what you want: it simply records the text in- and out- from the command line.
If you make your prompt distinctive (so that you can reliably tell the difference between shell commands and everything else) you can post-process the output of script to achieve your goals. Alternately you can hack script to get it to emit the XML you're looking for.
You can also try approaching this from a different angle. Instead of using a regular shell, connect to the machine using ssh or telnet and run your commands that way. Many ssh/telnet clients (PuTTY, for instance) have an option to log all console input and output during the session. You should be able to post-process this log to generate whatever type of logfile that you need.
Depending on your setup, you might not even have to use a second machine (you should be able to ssh into yourself).

Resources