capcom
capcom

Reputation: 3337

Leaving an infinite while loop in C

I have a loop that constantly reads from my serial port. The loop is infinite, so the only way I know of stopping the program is by using Ctrl+C. The problem with this solution, which I suspect is causing other problems as well, is that when I use Ctrl+C, my program ends abruptly. At the end of the program, I close the connection to the file descriptor of the serial port I am accessing, but I don't think my program ever reaches that because of me using the Ctrl+C command, which just stops the program exactly where it is.

Is there a way for me to create the infinite while loop, and exit when I want, but at the same time, maintain the capability to execute the code beneath it?

Upvotes: 4

Views: 19608

Answers (5)

m0skit0
m0skit0

Reputation: 25873

Use a variable that controls the while loop, e.g. while(running). Just set this variable asynchronously to false to exit the loop.

Example:

volatile int running = 1;
while(running) {
    /* Your code */
}

So another code, let's say a callback function, does this

running = 0;

You can set this callback to intercept SIG_TERM (which is Ctrl-C by default) or any signal of your choice (except SIG_KILL which is not sent to the process).

Upvotes: 0

Art
Art

Reputation: 20402

Try this and see what happens:

#include <unistd.h>
#include <stdio.h>
#include <signal.h>

volatile sig_atomic_t stop;

void
inthand(int signum)
{
    stop = 1;
}

int
main(int argc, char **argv)
{
    signal(SIGINT, inthand);

    while (!stop)
        pause();
    printf("exiting safely\n");

    return 0;
}

Ctrl-C sends a signal (SIGINT) to your process. The default action for the process is to exit when it gets it, but you can catch the signal instead and handle it gracefully.

Upvotes: 12

Zoneur
Zoneur

Reputation: 1099

You could do something like this:

sig_atomic_t volatile g_running = TRUE;

void sig_handler(int signum)
{
  if (signum == SIGINT)
    g_running = FALSE;
}

int main()
{
  signal(SIGINT, &sig_handler);
  while (g_running)
  {
    //your code
  }
  //cleanup code
}

This will catch the SIGINT signal generated by pressing CTRL-C and break the loop by setting g_running to FALSE. Your cleanup code is then executed

Upvotes: 6

Krishnabhadra
Krishnabhadra

Reputation: 34285

Using ctrl + C actually interrupts your program. To avoid that

1) Use a variable and check its state in every iteration of loop.

int  shouldExit  = 0;

----
----
---
while (your_condition){
  if(shouldExit == 1) {
     break;
  }

  // Your loop logic here
}

Then assynchronously set the variable

shouldExit = 1 

when you want to exit.

Upvotes: 0

tempidope
tempidope

Reputation: 873

Instead of the infinite while loop, create a while loop which listens/reads to boolean value in a particular file. You can edit the file to quit the loop.

Upvotes: 0

Related Questions