do while infinite loop stop on keyboard input - C - c

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.

Related

How to make readLine() timeout

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.

C (linux) - Emulate / Skip scanf input

I have a program running 2 threads. The first is waiting for user input (using a scanf), the second is listening for some data over an udp socket. I would like to emulate user input to handle a specific notification with the first thread everytime I recive a specific udp packet. I know I can share variables between threads, so my question is: can I force the scanf to take input from a different thread? Can I skip the scanf in the first thread?
I believe scanf() by definition reads from stdin. Like you said, though, the different threads share memory so it's easy to pass information between them. Maybe have some shared variable and some sort of boolean value indicating whether or not the information has been updated from the thread reading from the network. It all depends on what you're specifically trying to do, but you may want to have some other mechanism for simulation that bypasses the scanf().
Since you've specifically mentioned Linux, I'm going to suggest a novelty here.
You can open (/proc/%d/fd/%d, getpid(), STDIN_FILENO) and write to it. This will actually open the input of the terminal. I wouldn't recommend this for a real program, but then again, scanf shouldn't be used in real programs either.

How to break out of fgets?

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.

How can I have a new thread "take over" stdin?

In a program I am writing, I have a main thread that contains a loop for accepting console input. However, at some point a new thread is created that also tries to read from stdin. There is a variable that indicates that this other thread has started, but fgets is still waiting for input in the main thread, so the first console input entered after the new thread started is erroneously read by the main thread instead of the new thread.
Is there some way to solve this?
One thing I have tried is (in the main thread):
while(foo) {
if(busy) continue;
fgets(input,200,stdin);
if(busy) {
fputs(input,stdin);
} else {
// do whatever was supposed to be done with input intended for main thread
}
}
But I appear to have a misunderstanding of how streams work because the other fgets call does not read the data written via fputs.
Create a boolean variable protected an appropriate synchronization primitive. Initialize it to false. When a thread needs to ask a user a question and get an answer, wait for the variable to become 'false' (as appropriate for the synchronization primitive you chose) and then set it to true. Do all the output and get all the input you need. Then set the variable to 'false' and unblock any threads waiting (as appropriate for the synchronization primitive you chose).
For pthreads, a mutex and condition variable is probably best. For Windows, a critical section and auto reset event is probably best.
Your question does lack some details that may suggest a different answer. How is the user supposed to interact with a program when he can't be sure which of two separate code paths will get the input he types? If he types something and then hits 'enter', which code path it goes to would seem to depend on whether he hits 'enter' before the other thread is ready or not, which would seem to make an unusable program. In almost every realistic case, you will need to prompt the user and then wait for a response and then release input and output together.
For posterity, here is how I solved this.
Instead of having both threads be waiting for console input, I now have only one thread wait for input and delegate the handling of that input to functions specific to the program state.
The snippet above becomes:
while(foo) {
fgets(input,200,stdin);
if(busy) {
busyStuff(input);
} else {
nonBusyStuff(input);
}
}
and no other pthread that has an fgets call is ever created.

read in timed blocking mode

how can i make read (or other equivalent function) be in blocking mode for a specific time from the time that function reach execution
or in other words, to wait for an amount of time in which is trying to read
Maybe alarm could be a viable option for simple cases
A probably better solution would involve blocking on a select (or similar) call with a specified timeout and monitor the file descriptor for reading
Your question is fairly vague, so I can only assume what you mean. I guess you are wanting to attempt to 'read' until a certain deadline or timeout has been reached. In which case, just put the call to the read function inside a while loop which checks the current time against some pre-determined deadline and exits the loop when it has been reached....

Resources