Reputation: 1633
How can I break out of this loop?
while(1){
//continuously blink an led
//stop when user hits CTRL+D
}
//do other stuff
I tried while(fgets(s, BUFSIZ, stdin) != NULL)
, but of course it will wait for user input before continuing. I want the code inside the loop to run continuously, and break only the user hits CTRL+D
.
I've done this at a low level with interrupts, but no clue how to do it in a high level environment.
Platform is Raspbian (Kernel 3.10) on Raspberry Pi
Upvotes: 1
Views: 473
Reputation: 8494
As @unwind stated, you may use select.
#include <sys/select.h>
#include <unistd.h>
#include <string.h>
int main()
{
int run = 1, rc;
fd_set fd_list, readfd;
FD_ZERO(&fd_list);
FD_SET(STDIN_FILENO, &fd_list);
while (run)
{
readfd = fd_list;
rc = select(STDIN_FILENO + 1, &readfd, NULL, NULL, NULL);
if (rc == -1)
{
perror("Select error");
return 1;
}
if (FD_ISSET(STDIN_FILENO, &readfd) && read(STDIN_FILENO, &rc, sizeof(rc)) == 0 )
run = 0;
}
return 0;
}
We have told select to monitor for reading just one fd(STDIN_FILENO): the standard input one.
Once the user enters something, select
will alert us of that event; we investigate to know whether that input comes from STDIN_FILENO and if so, we read
from it. If read
returns 0, that means an end-of-file was met.
Upvotes: 1
Reputation: 2658
Maybe this solution transforming Ctrl+D
into Ctrl+C
and Ctrl+C
into Ctrl+D
using term caps may help you : https://stackoverflow.com/a/1516414/1405208.
Ctrl+D
will therefore send the SIGINT
signal. You just have to catch it. You may have to use a global variable though.
volatile sig_atomic_t ctrld_pressed = 0;
void ctrld(int sig)
{
ctrld_pressed = 1;
}
int main()
{
signal(SIGINT, ctrld);
while (!ctrld_pressed)
{
}
}
Upvotes: 1
Reputation: 399753
You can try using select()
if your platform supports it, otherwise you must make the input stream non-blocking ("raw") which again is highly platform-dependent code.
Upvotes: 0