Access data from terminal - c++

I have to write a program that intercepts data from terminal and i have to parse it. After processing when the data, i have to parse it before it goes to stdout.
I can't use tee or commands like prog > file 2>&1 as the program is going to be interactive.
For example :
If the user types ls in the terminal i have to parse it then it should go operating system and then when I get the result after processing I ll have to again parse it before it's displayed in the terminal.
I did my research and I think I can achieve it through pseudo terminal interfaces ( pty ).
Please let me know if there is a better way to achieve it.
I am using cpp and bash and the platform is *nix.
Update:
I can also use libexpect from expect.

I am not sure what do you mean here - you mean interactive program as "working in another terminal communicating with user" or even displaying GUI?
How does it specify the terminal? It is probably important what is program layout here (which program starts which).
If your application uses GUI to communicate with user, then I would simply do it this way:
start bash with sdtin and stdout attached to pipes,
your program reads & writes to it's end's of those pipes, parses data, and reads/writes on it's own stdin&stdout - so it appears on it's terminal.
If you mean controlling different terminal than your application's, it gets though since system generally does not expect program operating on multiple terminals. I don't think it's possible to filter communication between terminal and already working application attached to it. Starting another process spawning another terminal might be an option - to have basically two terminals working in sync. But then you will have to synchronize both processes by some other means (named pipes, network connection or some other IPC).
If you provide more detail on your program I might provide more directed help.
PS Don't tell me that you are writing some terminal keylogger ')
EDIT:
Your program is probably GUI based then - what i would recommend would be something similar to answer linked by banuj.
Best option will probably be to create three pipes, then fork, and in child process assign corresponding ends of pipes to stdin, stdout and stderr. Then child process should exec into shell - probably bash, although I am not sure if other shells would sound better if read out loud ;) Main process will be able to read/write other ends of mentioned pipes, parsing both inputs and outputs to bash and programs it runs.
You could also exec directly to commands user specifies, but that forces you to take over tedious job of a shell - managing current directory, environment variables, job control and so on.
Using above method might however cause some trouble - some programs (usually in security related contexts - eg. su(do) asking for password) will try to bypass stdin/stdout anyway and read directly from terminal device. I am not sure what can you do in such case - programing your own terminal emulator would be an option, but I don't know if you want to go this deep into system programming for this.
If you want some code snippet's, if you don't know how to do above, just ask ;)

Related

Linux C++, make application open terminal and run on it

I'm testing this on a basic Hello World C++ application.
Since I can see the std output only if running the application from terminal, I would like to let the application open its terminal by itself (when started by double clicking it), then execute the rest of the code on it.
I've already tried:
system("gnome-terminal");
just at the beginning of main() function.
The terminal opens but nothing gets displayed. I guess it's because it is opened on another thread... ?
So is there another way?
Two problems:
You didn't create any method to communicate with the terminal. If you need bidirectional communication, you could create two pipes, one to go from your program to the terminal and one to go from the terminal to your program.
The way you called system causes your program to wait for gnome-terminal to exit. You need to put an & on the end. In practice, you probably don't want to use system. You'll need to hook the pipes up in-between the fork and the exec, so you shouldn't use system in the first place. Then you can just not wait.
If you want to be ugly, you can use the /proc/self/fd/X mechanism. For example, in theory this could work:
system("gnome-terminal < /proc/self/fd/%d > /proc/self/fd/%d &",
terminal_fd_in, terminal_fd_out);
Just make sure the descriptors are not set to close on exec.

Open the terminal and execute commands via C programming

Does someone know how to open the terminal and execute several commands using a C program ?
I have a program in C and another sets of commands executed by the terminal. I need to combine them into one program in C.
I'm using Ubuntu 10.04.
Thanks!
Your question may be somewhat misleading.
Because you want to run all the terminal commands in the c-code, perhaps you actually have only textual input / output with these commands. If so, you probably do not need the terminal.
I use popen when the output of the (terminal) program is a text stream. It is probably the easiest to use. As an example:
...
const char* cmndStr = "ls -lsa";
FILE* pipe = popen(cmndStr, "r");
...
The popen instruction executes the command in the cmndStr, and any text written to the commands (ls -lsa) standard output, is redirected into the pipe, which is then available for your C program to read in.
popen opens a separate process (but without a terminal to work in, just the pipe)
'Fork' is another way to launch a separate process, with some control over the launched processes' std i/o, but again, I think not a terminal.
On the other hand, if your output is not a simple text stream, maybe you can get by with a output-only dedicated terminal screen to accommodate special output activity. For instance, when I work with ncurses:
I manually open a terminal in the conventional way, and in the terminal
issue the command "tty" to find out the device name, and
issue a "cd" to set the focus to the working dir.
dmoen#C5:~$ tty
/dev/pts/1
dmoen#C5:~$ cd work
dmoen#C5:~/work$
Then I start my program (in a different tty), and let the program know which device I want it to use for the special output (i.e. /dev/pts/1 ) ... I typically use command line parameters to tell my program which pts or extra terminals I want it to use, but environment variables, pipes, in/out redirection, and other choices exist.
I have not tried (lately) to launch a terminal (as suggested by smrt28), except in shell. I believe this will work, but I do not see how the output from the terminal command (ls in the example) would be delivered back to your program. popen trivially delivers a text stream.
A long time ago, I used a device called 'pty' which works like a terminal, but I don't remember how to connect it usefully.
There is a set of 'exec' commands ... see man exec. To connect them back to your program, you will probably work with files, or perhaps redirecting i/o. Too many choices to list here.
And also, maybe you can connect these commands with your c program using shell pipes.
Check "man xterm", parameter -e. Then, in C, you can:
system("xterm -e ls")

Is it possible to send command to console window in which my program is running?

I know the system() function but that creates it's own environment so every variable set here isn't forwarded to main console. I wonder is it possible to send command as it would be written by the user or as it would be executed by *.bat file ?
The reason I need this is that I look for a way to set env variable of parent CMD process. And yes I know that system doesn't want me to do it, but maybe there is a some workaround for that...
Idea is to create app that would set as a variable anything that is send to it via input pipe, like this:
echo Bob| setvar name
so then:
echo %name%
would produce Bob
The whole idea is to make easier setting a variable from any program output (I know how to do it with for command) with taking account of peculiarities with special batch characters like ^!% since these are allowed in file names. It would make simpler many cmd scripts.
You can certainly run programs in the same console window as your program. That's the default behavior for CreateProcess. MSDN has more details on what happens between related processes sharing a console. You'll probably want to wait for the child process to terminate before continuing to run your own program.
However, that won't help with your real goal. The window where a program runs has absolutely nothing to do with the environment variables of any of its ancestor processes. You'll have to look elsewhere for a solution to your real problem.

Is there a way to send some procesess with known pid in background?

I am new in Linux and system programming .
I Want to write a c program which finds processes whose cpu% usage are more than a specific given value and sends them to background.
anybody can help me !
I really appreciate it
I'm fairly sure that what you're asking is that you want to detect if a process is using X amount of CPU and if so, take it off the CPU for a while. There's a piece of software already that does this: It's called the kernel. I'm not aware of any way to programatically take another process off CPU unless that other program supports an external interface to reduce its load.
Most likely what you really want to do is configure the nice and other scheduler parameters of the running process so the kernel is more like to to take it off CPU when another program needs to do work.
But what underlying problem are you really trying to solve here? Maybe if you tell us that we can offer an alternate solution.
Please look at source code of process managament utilities like:
htop
top (standard unix command)
ps (standard unix command)
IMHO, You can't.
Background management ensures the shell. So, the & is interpreted for example by /bin/bash command. When pressed CTRL-Z, the kernel stopping your current fg-job, and again by your shell you can send it into background.
Youre looking for the way how to remote control the shell what running some program in fg. I don't know any 'remote-controling' way.
Ofc, here are alternative solutions, for example:
use the screen command, and you can recall the specific screen into your terminal, and can manually send process into bg.
or you can use some screen-sharing utility, to overtake a specific terminal and CTRL-Z, bg
or, you can patch bash and adding remote control functionality. ;)
or, here is something what i don't know. ;) - hm, maybe trap some user-signal handling code in the /etc/profile?
You can read a bit about here: http://en.wikipedia.org/wiki/Process_group
Honestly, after a half hour of thinking I don't get any idea why you want remotely (from the another terminal - by its PID) send some processes from the fg into the bg. Give me no sense.
Can you please tell, what you want achieve?
You probably want to reduce process priority, but I not sure it's good idea.
We send process to background generally to free shell's prompt.
The "+" means that the program "is in the foreground process group". I don't believe, however, that this state at all affects the process's scheduling.
However, you can change it with tcsetpgrp.
From the man page: "The function tcsetpgrp() makes the process group with process group ID pgrp the foreground process group on the terminal associated to fd, which must be the controlling terminal of the calling process, and still be associated with its session. Moreover, pgrp must be a (non-empty) process group belonging to the same session as the calling process."
By my reading, you just call this function and make the shell (or some other program) be the foreground process.

Communication with a script from a C++ program

I have a c++ program (very complicated, and lengthy both in code and execution time).
Once in a while this program stops and calls a user-specified shell script.
Before calling the script, my program creates a .out file with current data. I call the script via system() command. The script then reads the .out file, and creates its own script.out file and exits.
Then the system() function call ends, and my program reads and parses the script.out file.
Question: is there a better way to execute communication between my c++ program and a random shell script?
My intent is to have full communication between the two. Script could virtually "ask" the program "What data do you have right now?" and the program would reply with some strict convention. Then the script could say "Add this data...", or "delete all your previous data" etc.etc.
The reason I need this is because the shell script tells the program to modify its data. The exact data that was put in the original .out file. So after the modification is done -- the actual data held by the program does not correspond to the data written in the .out file.
Thanks!
P.S.
I swear I've searched around, but everyone suggests an intermediate file.
There are certainly ways to do that without intermediate files. The most common approach is to use command line arguments for input, and pipes for standard output; others also use pipes for input. The most straight-forward alternative to system then is to use popen.
On a unix-like system? Perhaps pipe (2) will work for you?
From the man page (Mac OS X 10.5 version):
SYNOPSIS
#include <unistd.h>
int pipe(int fildes[2]);
DESCRIPTION
The pipe() function creates a pipe (an object that allows unidirectional
data flow) and allocates a pair of file descriptors. The first descrip-
tor connects to the read end of the pipe; the second connects to the
write end.
You will, of course, have to follow the creation of the pipes with a fork and exec pair. Probably this has already been answered in detail, and now you know what to search on...
It's been a while since I did this, but:
In the main process, before forking the sub-process you call pipe twice. Now you have two pipes and control both ends of both of them.
You fork.
The main process will read from one pipe and write from the other. It doesn't matter which is which, but you need to be clear about this.
The child process will call one of the exec family of function to replace it's image with that of the shell you want to run but first you will use dup2 to replace it's standard input and output with the ends of the two pipes (again, this is where you need to be clear about which pipe is which).
At his point you have two processes, the main process can send things into one pipe ad they will be received on the standard input of the script, and anything the script writes to it's standard output will be sent up the other pipe to the controlling process. So they take turns, just like interacting with the shell.
You can use pipes or (maybe more convenient) sockets - for example frontends to gdb, or expect do that. It would require changes to your shell scripts, and switching from system() to more low-level fork() and exec().
It's rather complicated so please, be more specific about your environment and what you need to clarify.
You are asking the question on Interprocess Communication (IPC).
There are a lot of ways to do that. You can do a simply search and Internet will return you most answers.
If I am not wrong, Google chrome uses a technique called Named Pipe.
Anyway, I think the most "portable way" is probably a file. But if you know you are working on which operating system, you can definitely use most of the IPC techniques.