My application basically is a CLI with all the expected features like prompt, history etc., it needs to wait on STDIN for user input. For this I am using readLine system call. I have a created a network socket which is used to send the message read from user to server. My application is single threaded one. Because my application is blocked for user input, the socket created is not responding to keep-alive messages from server. I want to know if there is a way make readLine timeout after some time, so that I will just poll on my network socket and come back to wait on readLine?.
I know there is one solution where I can spawn a thread to take care of network operations. But I dont want to make my app multithreaded.
I am using readLine system call.
libreadline
You provide inconsistent information. What system would that be that has a system call readLine?
If you use libreadline, you are rather calling library functions. But then, according to the GNU Readline Library Function and Variable Index, there is no function readLine, there's only readline. With it you could use either the
Variable: rl_hook_func_t * rl_event_hook
If non-zero, this is the
address of a function to call periodically when Readline is waiting
for terminal input. By default, this will be called at most ten times
a second if there is no keyboard input.
(you'd set it to a function where you poll your network socket and respond to messages)
or the
Alternate Interface
An alternate interface is available to plain readline(). Some applications need to interleave keyboard I/O with file, device, or window system I/O, typically by using a main loop to select() on various file descriptors. To accommodate this need, readline can also be invoked as a `callback' function from an event loop. There are functions available to make this easy.
There's an example program using the alternate interface: Alternate Interface Example.
how about using this? I also tried to find the same solution as this thread.
and those code just works but I'm not sure it has no prob.
if anybody found fault in it or better solution, please let me know it.
int event_hook(){
rl_line_buffer[0] = '\0';
rl_done = 1;
return 0;
}
rl_event_hook = event_hook;
rl_set_keyboard_input_timeout(500000); // in usec
char* line = readline(">"); // returns after 1s. I don't know why it takes double time that I set up.
Related
This is what says on http://invisible-island.net/ncurses/ncurses.faq.html#multithread
If you have a program which uses curses in more than one thread, you will almost certainly see odd behavior. That is because curses relies upon static variables for both input and output. Using one thread for input and other(s) for output cannot solve the problem, nor can extra screen updates help. This FAQ is not a tutorial on threaded programming.
Specifically, it mentions it is not safe even if input and output are done on separate threads. Would it be safe if we further use a mutex for the whole ncurses library so that at most one thread can be calling any ncurses function at a time? If not, what would be other cheap workarounds to use ncurses safely in multi-thread application?
I'm asking this question because I notice a real application often has its own event loop but relies on ncurses getch function to get keyboard input. But if the main thread is block waiting in its own event loop, then it has no chance to call getch. A seemingly applicable solution is to call getch in a different thread, which hasn't caused me a problem yet, but as what says above is actually not safe, and was verified by another user here. So I'm wondering what is the best way to merge getch into an application's own event loop.
I'm considering making getch non-blocking and waking up the main thread regularly (every 10-100 ms) to check if there is something to read. But this adds an additional delay between key events and makes the application less responsive. Also, I'm not sure if that would cause any problems with some ncurses internal delay such as ESCDELAY.
Another solution I'm considering is to poll stdin directly. But I guess ncurses should also be doing something like that and reading the same stream from two different places looks bad.
The text also mentions the "ncursest" or "ncursestw" libraries, but they seem to be less available, for example, if you are using a different language binding of curses. It would be great if there is a viable solution with the standard ncurses library.
Without the thread-support, you're out of luck for using curses functions in more than one thread. That's because most of the curses calls use static or global data. The getch function for instance calls refresh which can update the whole screen—using the global pointers curscr and stdscr. The difference in the thread-support configuration is that global values are converted to functions and mutex's added.
If you want to read stdin from a different thread and run curses in one thread, you probably can make that work by checking the file descriptor (i.e., 0) for pending activity and alerting the thread which runs curses to tell it to read data.
I'm working on a console C/C++ program on linux (centOS7) where some info need to be displayed on top of the terminal screen. While the main thread processes stdin, another thread handles callbacks and displays status on stdout. To avoid clobbering, callback status is only displayed on top of the screen, but the cursor must be returned to the original position.
I tried ANSI save/restore cursor but it doesn't work as pointed out in the link. While this stackoverflow solution works in single-thread, it doesn't work in multi-thread as the two thread would both read stdin. I have tried several methods to disable stdin temporarily while getting current cursor positions, but they all failed:
disable CREAD in termios.c_cflag -- tcsetattr() returns error (invalid parameter)
tcflow(TCIOFF)
dup()
I know ncurses would work, but in my app there are too many stdio functions that I need to replace with ncurses wrappers. Does anyone know how to save/restore cursor position or get current position in multithread env where one thread is reading stdin?
I know ncurses would work, but in my app there are too many stdio functions that I need to replace with ncurses wrappers.
So, you are not interested in fixing the problem, only in papering over it. One approach you can try is
flockfile(stdin);
flockfile(stdout);
flockfile(stderr);
/* Write ("\033[6n") to standard input,
and read the ("\033[" row ";" column "R") response */
funlockfile(stderr);
funlockfile(stdout);
funlockfile(stdin);
See man 3 flockfile() for details. The idea is to grab the C library internal lock for all three standard streams, so that any other thread doing I/O on them will block until we call funlockfile() on that stream.
This does not affect low-level I/O to STDIN_FILENO, STDOUT_FILENO, or STDERR_FILENO in any way.
A comment from rici made me realize that there is actually one approach that does not involve rewriting the original code.
Use a helper process (or thread) to handle all I/O to standard input, standard output, standard error, and the terminal.
Essentially, at the very start of your program, you construct three pipes and an Unix domain datagram socket pair, and create the helper.
(If you use a helper process, you can make it into an external executable, and write it using ncurses, without affecting the parent program.)
The helper is connected via the pipes and the socket pair to the parent process. Parent replaces STDIN_FILENO, STDOUT_FILENO, and STDERR_FILENO descriptors with the pipe ends (closing their respective original descriptors). That way, it can only read from the helper, and write to the helper, not directly to the original streams.
The Unix domain datagram socket pair allows the parent to query the current cursor location (and perhaps do other similar actions) from the helper.
The helper reads from two of the parent pipes and the original standard input, and writes to one of the parent pipe and the original standard output and error. I personally would make the helper pipe ends nonblocking, and use select(), so a single-threaded helper would suffice.
In a comment, you mention that
Existing code uses readline and ansi escape strings for nice terminal display...
You really should put that information into the question, since it is quite important.
The fact that your code base uses readline severely conditions your possibilities, since readline does not actually work with ncurses. In order to convert the program to use ncurses, you would need to recreate those features of readline which you rely upon. There may be additional libraries which can help with that, but I don't know of any.
On the other hand, ncurses is capable of dividing the screen into non-overlapping regions, and scrolling these regions independently. This is exactly what you need for an application which wants to keep status messages in a status line. Since version 5.7, released about a decade ago, ncurses has primitive threads support (on Linux, anyway), and it is possible to assign different "windows" (screen regions) to different threads. man curs_threads provides some information.
Ncurses also provides easy-to-use interfaces which can replace the use of console control sequences.
So that's probably the long-term solution, but it's going to be a fair amount of work. In the meantime, it is just barely possible to do what you want by using features built in to the readline library. Or at least I was able to write a proof-of-concept which successfully maintained a status line while accepting user input from readline. The import aspect of this solution is that readline is (almost) always active; that is, that there is a thread which is in a hard loop calling readline and passing the buffer read to a processing thread. (With my POC implementation, if the thread calling readline also processes input and the input processing takes a significant amount of time, then the status line will not be updated while input processing takes place.)
The key is the rl_event_hook function, which is called periodically by readline (about 10 times per second) while it is waiting for input. My implementation of rl_event_hook looks like this:
/* This function is never called directly. Enable it by setting:
* rl_event_hook = event_hook
* before the first call to readline.
*/
int event_hook(void) {
char* msg = NULL;
pthread_mutex_lock(&status_mutex_);
if (status_line_) {
msg = status_line_;
status_line_ = NULL;
}
pthread_mutex_unlock(&status_mutex_);
if (msg) {
free(saved_msg_);
saved_msg_ = msg; /* Save for redisplay */
/* Return value of `get_cursor` is a pointer to the `R` in the
* input buffer, or NULL to indicate that the status reply
* couldn't be parsed.
*/
char cursor_buf[2 + sizeof "x1b[999;999R"];
char* action = get_cursor(cursor_buf, sizeof cursor_buf - 1);
if (action) {
set_cursor(1, 1);
fputs(msg, stdout);
clear_eol();
*action = 'H';
fputs(cursor_buf, stdout);
}
}
return 0;
}
In order to get a status message to display, you need to lock the mutex and set status_line_ to a dynamically-allocated buffer containing the status line:
/* Set the status message, so that it will (soon) be shown */
void show_status(char* msg) {
pthread_mutex_lock(&status_mutex_);
free(status_line_);
status_line_ = msg;
pthread_mutex_unlock(&status_mutex_);
}
Since readline does not preserve the status line when a newline character is read (and in certain other cases), and nothing will prevent the screen from scrolling when you send output to it, the above code keeps the current status line in saved_msg_ so that it can be redisplayed when necessary:
/* Show the status message again */
void reshow_status(void) {
pthread_mutex_lock(&status_line_mutex_);
msg_ = saved_msg_;
saved_msg_ = NULL;
pthread_mutex_unlock(&status_line_mutex_);
}
That's a pretty messy solution, and about the best that can be said for it is that it mostly works, in an imaginary context which might or might not have anything to do with your actual use case. (It's not perfect. There's at least one race condition, although it doesn't actually get triggered in my test code because the only calls to reshow_status are performed in the thread which calls readline, and so the function is only called if there is no possibility for the event hook to run.
It might also be possible for user input to be interlaced with the console's status return, but I think this will be very rare. My implementation of get_cursor does attempt to deal with the possibility of user input characters arriving after the status request has been sent and before the status reply has been received:
fputs("\x1b[6n", stdout);
int ch;
while((ch = getchar()) != 0x1b) rl_stuff_char(ch);
I didn't test this thoroughly so about all I can say is that it seemed to work. (rl_stuff_char inserts a character into a buffer to be used the next time that readline's input loop runs.)
I am writing a simple instant messaging client & server to get the handle of socket programming.
My client has two threads:
Thread A has a streaming socket connection with the server and
performs a readline in a loop, printing out lines of text it receives
from the server. If the readline returns EOF, the loop exits.
Thread B listens to keyboard input from the user using fgets in a loop. When the user presses enter, it sends the line to the server (so it can forward it to the other client).
When a user presses Ctrl-D, the client sends a special message to the server saying "the client wants to disconnect" at which point the server closes the connection file descriptor for that user. This causes thread A to exit the loop since the readline function returns EOF. Thread A then closes the connection file descriptor and completes.
Meanwhile, thread B is still listening to keyboard input from the user until they hit enter. Ideally, the fgets would break early and let the user know that the other client disconnected.
Is there anyway to do or do I need to use a different input function or library?
Firstly, if you are trying to write socket functions, do not use fgets() or anything else that uses buffered IO, otherwise known as a FILE *. Instead use file descriptors (fd). Generally, every libc function beginning with 'f' is to be avoided. You want read and write.
Secondly, you want to read up on asynchronous I/O with select(), rather than work out how to 'break out' of fgets().
Thirdly, I could give you a tutorial here, or I could tell you to google, or look at http://en.wikipedia.org/wiki/Asynchronous_I/O but really what you want to find is a copy of Stephens (from memory "Advanced Programming in the Unix Environment" is what you want but really you should buy all of them and tape them to your body whilst you sleep in the hope of learning by osmosis).
Fourthly, I know you said you wanted to do this with threads. You can kill a thread with pthread_cancel() if you really want to do that, and restart it. Don't. Do it properly. You don't need threads.
In a Windows environment, fgets is a "blocking" call. Thus, the thread that issues it iwll wait until it has some input.
Not a problem, as long as, fgets enters into an "Alertable Wait" so that the waiting I/O can be cancelled by an ExitThread(0) statement.
Again, in Windows the way to have an ExitThread(0) statement get issued in a thread that is in a wait is to schedule an APC (i.e. QueueUserAPC()) for the thread and have that scheduled method issue the ExitThread() statement.
I just did this for some code I'm writing. I know that an APC will cause a thread to exit, if that thread has issued an alterable wait. I don't know if fgets does this in Windows, that is something you will need to figure out. If not then use an I/O statement that does. Note. In Windows your code can issue an Alertable wait with WaitSingleObjectEx() on the handle of an object when the handle is signaled when I/O is available for the object.
Do an internet search on "MSDN APC" and you will find all kinds of documentation from Microsoft about this.
Pthreads? Use pthread_kill to send a SIGHUP. This will cause fgets to quit with errno set to EINTR. Send it from thread A before it exits to thread B. You might have to play with the signal handlers and masks via pthread_sigmask and sigaction, depending on how fancy you want to get.
Can anyone tell me the use and application of select function in socket programming in c?
The select() function allows you to implement an event driven design pattern, when you have to deal with multiple event sources.
Let's say you want to write a program that responds to events coming from several event sources e.g. network (via sockets), user input (via stdin), other programs (via pipes), or any other event source that can be represented by an fd. You could start separate threads to handle each event source, but you would have to manage the threads and deal with concurrency issues. The other option would be to use a mechanism where you can aggregate all the fd into a single entity fdset, and then just call a function to wait on the fdset. This function would return whenever an event occurs on any of the fd. You could check which fd the event occurred on, read that fd, process the event, and respond to it. After you have done that, you would go back and sit in that wait function - till another event on some fd arrives.
select facility is such a mechanism, and the select() function is the wait function. You can find the details on how to use it in any number of books and online resources.
The select function allows you to check on several different sockets or pipes (or any file descriptors at all if you are not on Windows), and do something based on whichever one is ready first. More specifically, the arguments for the select function are split up into three groups:
Reading: When any of the file descriptors in this category are ready for reading, select will return them to you.
Writing: When any of the file descriptors in this category are ready for writing, select will return them to you.
Exceptional: When any of the file descriptors in this category have an exceptional case -- that is, they close uncleanly, a connection breaks or they have some other error -- select will return them to you.
The power of select is that individual file/socket/pipe functions are often blocking. Select allows you to monitor the activity of several different file descriptors without having to have a dedicated thread of your program to each function call.
In order for you to get a more specific answer, you will probably have to mention what language you are programming in. I have tried to give as general an answer as possible on the conceptual level.
select() is the low-tech way of polling sockets for new data to read or for an open TCP window to write. Unless there's some compelling reason not to, you're probably better off using poll(), or epoll_wait() if your platform has it, for better performance.
I like description at gnu.org:
Sometimes a program needs to accept input on multiple input channels whenever input arrives. For example, some workstations may have devices such as a digitizing tablet, function button box, or dial box that are connected via normal asynchronous serial interfaces; good user interface style requires responding immediately to input on any device. [...]
You cannot normally use read for this purpose, because this blocks the program until input is available on one particular file descriptor; input on other channels won’t wake it up. You could set nonblocking mode and poll each file descriptor in turn, but this is very inefficient.
A better solution is to use the select function. This blocks the program until input or output is ready on a specified set of file descriptors, or until a timer expires, whichever comes first.
Per the documentation for Linux manpages and MSDN for Windows,
select() and pselect() allow a program to monitor multiple file
descriptors, waiting until one or more of the file descriptors become
"ready" for some class of I/O operation (e.g., input possible). A file
descriptor is considered ready if it is possible to perform the
corresponding I/O operation (e.g., read(2)) without blocking.
For simple explanation: often it is required for an application to do multiple things at once. For example you may access multiple sites in a web browser, a web server may want to serve multiple clients simultaneously. One needs a mechanism to monitor each socket so that the application is not busy waiting for one communication to complete.
An example: imagine downloading a large Facebook page on your smart phone whilst traveling on a train. Your connection is intermittent and slow, the web server should be able to process other clients when waiting for your communication to finish.
select(2) - Linux man page
select Function - Winsock Functions
there is any way to run an infinite cycle that stops only on user input from keyboard
without asking every cycle to continue? in a C program
(I'm developing a C chat that read the entries with a for(;;) loop and I need to stop it only when the user want to type and send a message) hi all!
You didn't specify the OS so I will assume some POSIX compliant OS.
You can use select. This can be used to block on a set of file descriptors (in your case, stdin) with a finite timeout or indefinite blocking.
My guess is, since this is a chat program, you would also want to do this on some other file descriptor, like your chat tcp socket. So you can test for input on both with one call.
In case of windows console, you should be able to use GetStdHandle and WaitForSingleObject/WaitForMultipleObjects if select does not work for you.
There are a number of ways of doing this in Windows. Assuming you're using VC++, the easiest way is probably to use _kbhit(). If you want to use the Win32 API directly instead, you could call GetNumberOfConsoleInputEvents() and see whether the return is non-zero.
You could also do an overlapped read, and each time through the loop call WaitForSingleObject with a timeout value of 0. The zero wait means it'll return immediately whether there's input or not. The return value will tell you whether you have any data: WAIT_TIMEOUT means no data has been read yet, and WAIT_OBJECT0 means you have some data waiting to be processed.