Editline with non-blocking input - c++

I use editline library in my program, for user commands input in shell. But becides shell, program have a gui interface, so I need to run editline's readline() function in separate thread, because it blocks until Enter pressed. Is there a way to use readline() function without blocking, so I could avoid separate thread usage?

Why not making the GUI thread run in a different thread and leave the console input in the main thread. You can push events to the GUI thread after reading from command line. It is much simpler in my opinion.
This works of course if your GUI allows you to run it in a different thread than the main one.
LATER EDIT: Couldn't you just create a text control/window and take the input from there? Once you press Enter it clears input - just like typing messages at a console? I believe it is much simpler to have everything in the GUI

Related

How to run multiple shell command at the same time in linux

I am trying to run multiple command in ubuntu using c++ code at the same time.
I used system() call to run multiple command but the problem with system() call is it invoke only one command at a time and rest commands are in waiting.
below I wrote my sample code, may this help you to get what I am trying to do.
major thing is I want to run all these command at a time not one by one. Please help me.
Thanks in advance.
main()
{
string command[3];
command[0]= "ls -l";
command[1]="ls";
command[2]="cat main.cpp";
for(int i=0;i<3;i++){
system(command[i].c_str());
}
}
You should read Advanced Linux Programming (a bit old, but freely available). You probably want (in the traditional way, like most shells do):
perhaps catch SIGCHLD (set the signal handler before fork, see signal(7) & signal-safety(7)...)
call fork(2) to create a new process. Be sure to check all three cases (failure with a negative returned pid_t, child with a 0 pid_t, parent with a positive pid_t). If you want to communicate with that process, use pipe(2) (read about pipe(7)...) before the fork.
in the child process, close some useless file descriptors, then run some exec function (or the underlying execve(2)) to run the needed program (e.g. /bin/ls)
call (in the parent, perhaps after having got a SIGCHLD) wait(2) or waitpid(2) or related functions.
This is very usual. Several chapters of Advanced Linux Programming are explaining it better.
There is no need to use threads in your case.
However, notice that the role of ls and cat could be accomplished with various system calls (listed in syscalls(2)...), notably read(2) & stat(2). You might not even need to run other processes. See also opendir(3) & readdir(3)
Perhaps (notably if you communicate with several processes thru several pipe(7)-s) you might want to have some event loop using poll(2) (or the older select(2)). Some libraries provide an event loop (notably all GUI widget libraries).
You have a few options (as always):
Use threads (C++ standard library implementation is good) to spawn multiple threads which each perform a system call then terminate. join on the thread list to wait for them all to terminate.
Use the *NIX fork command to spawn a new process, then within each child process use exec to execute the desired command (see here for an example of "getting the right string to the right child"). Parent process can use waitpid to determine when all children have finished running, in order to move on with the program.
Append "&" to each of your commands, which'll tell the shell to run each one in the background (specifically, system will start the process in the background then return, without waiting for the result). Not tried this, don't know if it'll work. You can't then wait for the call to terminate though (thanks PSkocik).
Just pointing out - if you run those 3 specific commands at the same time, you're unlikely to be able to read the output as they'll all print text to the terminal at the same time.
If you do require reading the output from within the program (though not mentioned in your question), this is relevant (although it doesn't use system).

How to prevent a process opened with popen() in C++ from receiving SIGINT signal?

I opened a process(GNUplot) from C++ with the popen() function. When I Ctrl+C to terminate the process, GNUplot also receives SIGINT signal. I want to prevent this from happening as it has an unfavorable effect on what I do. (I prefer to handle the signal with my own signal handler function). How do I do that?
I plot using the plot '-' command and iterate through all the values I want to plot. If the gnuplot receives SIGINT in the middle, it might stop plotting in the middle without completing the entire plot. I want it to complete the entire plot. This is the unfavorable effect I have.
popen(3) is running a new shell /bin/sh -c on the command string.
The trap builtin of the shell is handling signals; with an empty first argument it is ignoring it. So you could do
FILE* f = popen("trap '' TERM INT; gnuplot", "w");
BTW, POSIX trap requires the signals to be named without SIG prefix.
But that won't work, since gnuplot itself is explicitly handling signals. There is no way to avoid that outside of gnuplot. But take advantage of the free software nature of gnuplot: download its source code, study it, and patch it to fit your bizarre needs. FWIW, SIGINT and signal appear in several places in the source code of gnuplot-5.0.5.
However, you should consider (instead of using popen) to call the low level system calls explicitly (fork, execve, pipe, dup2, waitpid, signal ...). Read Advanced Linux Programming for details.
I strongly suspect that your question is an XY problem. You don't explain what "unfavorable effect" you actually want to avoid, and I am guessing you might avoid it otherwise.
I plot using the plot '-' command and iterate through all the values I want to plot. If the gnuplot receives SIGINT in the middle, it might stop plotting in the middle without completing the entire plot. I want it to complete the entire plot.
Actually you might set up two or three pipes (one for input, one for output, perhaps one for stderr, as seen on gnuplot side) for gnuplot. You need to go the low level system calls (explicit calls to pipe(2), fork(2) etc etc...). Your program should then have some event loop (probably based upon poll(2)...). And you would send a print "DONE" command to gnuplot after every plot '-' (don't forget to initialize with the appropriate set print '-' or have another pipe for the stderr of gnuplot). Your event loop would then catch that DONE message to synchronize. Read also this.
I had similar problem as you. I'm using tc command with -batch parameter and I need to keep it alive until it exits after reaching limit and is closed. My problem was that I was running two asynchronous popen processes and after throwing an exception, second process was killed. A lot of memory dumps etc. After finding this problem and fixing it I can now handle SIGINT, SIGTERM, ctrl+c without tc proces knowing anything about it. No need for traps or anything similar.

How do I separate input from output in a C++ console application? Can I have two cursors?

I'm coming from C and don't have too much programming knowledge, so bear with me if my idea is nonsense.
Right now, I'm trying to write a simple threaded application with double-buffered console output. I've got a thread which resets the cursor position, draws the buffer and then waits n milliseconds:
gotoxy(0, 0);
std::cout << *draw_buffer;
std::this_thread::sleep_for(std::chrono::milliseconds(33));
This works perfectly well. The buffer is filled independently by another thread and also causes no problems.
Now I want the user to be able to feed the application information. However, my drawing thread always puts the cursor back to the start, so the user input and the application output will interfere. I'm aware there are libraries like curses, but I'd prefer to write this myself, if possible. Unfortunately, I haven't found any solution to this. I guess there is no way to have two console cursors moving independently? How else could I approach this problem?
I think what you will need to do two things:
Create a mutex that controls which thread is writing to stdout.
Change the input mode so that when you invoke getchar, it returns immediately (rather than waiting for the user to press enter). You can then wait for the other thread to release the mutex, then move the cursor and echo the character the user pressed at the appropriate part of the screen.
You can change the input mode using tcsetattr, although this is from termios which is for *nix systems. Since you're using windows, this may not work for you unless you're using cygwin.
maybe check this out: What is the Windows equivalent to the capabilities defined in sys/select.h and termios.h

C++ Alternative to System() for starting multiple command prompts. WINAPI ( No MFC )

I am writing a program which is used to launch different command line applications. The problem is when I run 1 application, command prompt takes control of the program and will not allow me to access my GUI to launch another. I believe this is because System() creates a new process, Then once the command prompt is exited, control is given back to the GUI.
Is there any alternatives that will allow me to Launch several command line programs at once ? like in a thread for example.
Any help on this would be greatly appreciated.
::Dan
Use the CreateProcess function; this create a new process but doesn't wait for it to finish. Instead, you can wait for it yourself using the WaitForSingleObject function.
If you are starting multiple processes you may want to consider using WaitForMultipleObjects which lets you wait for a whole list of processes (and other objects) at once.
See the list of wait functions at the MSDN for more alternatives on how to wait for a process to finish.

is it is possible to run a background process if the window is closed?

I am creating an application in C++ gtk and if I press a button a threading process will start and I need to run the application if the window is closed also is it possible?
Under a Unix system (and since Windows 10), you create another process using the fork() function. To run a program you then use the execve() or similar.
However, that means you need to communicate with that other process using a pipe (see pipe() or pipe2()) or via the network.
Using a thread instead of a process allows you to run in the same memory & process and you can very easily shared everything between multiple threads.
As far as I know, the gtk loop just returns once the user selects the "Close Window" or similar exit function. It would be up for your main() function to make sure that it waits for all the threads to be done before exiting. For threads, this is usually done with a "join()". It will depend on the library you use to run your background process.
Note that in most cases people expect processes to exit whenever they ask the process to exit. Showing a window saying that your process is still running in the background (is busy) is a good idea for a process which runs a GUI. Especially, if you run your process from the console, it would not exit immediately after you closed the window, so letting the user know what's happening is important otherwise they are likely to hit Ctrl-C and kill the whole thing.
If you'd like the main to return but be able to keep the background threads running, it's a tad bit more complicated, but it uses both of the solutions I just mentioned:
create a pipe()
fork() (but no execve())
from within the forked app. (child) open Gtk window, background thread, etc.
when last Gtk window is closed, send message over pipe
parent process receives message and quits immediately
child process still attempts a "join()" to wait for the background thread
This way, the background process with threads created in (3) can continue to run (your function still needs to wait for all the threads to end with the "join()" call), however, the use has a sense of "the app. is done" since it returns to the next line on the prompt in your console even though a background process is still running.
The pipe() and wait on a message on the pipe() is not required if you don't mind having your application always running in the background.
Note: that usage of fork() is most often seen when creating processes that want to run in the background (i.e. services, often called servers under Unix). That's how they get their PPID set to 1.
On Windows, you need to create a Windows/Linux/Mac Service or run the process in background. On Linux you need to create a daemon service or run the process in the background. Services allow to automatically start the process on boot.