tgun926
tgun926

Reputation: 1633

Exit a loop when stdin is EOF in C?

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

Answers (3)

edmz
edmz

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

Julien Fouilh&#233;
Julien Fouilh&#233;

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

unwind
unwind

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

Related Questions