0

I made a program that listen on a specific ipv6 address and a port, which displays what it receives. My program works perfectly; I haven't tested everything yet, but the basic usage works.

I need your advice for this problem: what is the best way to continuously listen?

When I launch the program, I want to stop listening by stopping it with Ctrl+C in the shell. But If I do that, some important code may not be executed. Here is what I have at the end of my main function:

while(1){

        // reception de la chaine de caracteres
        if(recvfrom(sockfd, buf, 1024, 0
                    , (struct sockaddr *) &client, &addrlen) == -1)
        {
          perror("recvfrom");
          close(sockfd);
          exit(EXIT_FAILURE);
        }

        buf[1023] = '\0';

        // print the received char
        printf("%s", buf);
    }


    // close the socket
    close(sockfd);

    return 0;

First, I think that this is passive waiting since the function recvfrom stop the program until it receives something. So using a while is not a problem. The problem is, that close(sockfd) may not be executed.

So I am looking for a simple way to execute some code when the program is stopped. I thought of threads but this may be too complex for this problem.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
oktomus
  • 566
  • 7
  • 28
  • Typically you would handle the signal that is produced by ctrl-c. man signal. – Clarus Nov 04 '16 at 21:25
  • If your program exits, all its file descriptors are closed by the system. If one (or more) of those file descriptors is a socket, that socket is closed. – Jonathan Leffler Nov 04 '16 at 21:30

1 Answers1

1

Yes you can catch the ctrl-c signal and execute code after receiving that signal.

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

void sig_handler(int signo)
{
  if (signo == SIGINT)
    printf("received SIGINT\n");
}

int main(void)
{
  if (signal(SIGINT, sig_handler) == SIG_ERR)
  printf("\ncan't catch SIGINT\n");
  // A long long wait so that we can easily issue a signal to this process
  while(1) 
    sleep(1);
  return 0;
}
madnight
  • 420
  • 3
  • 10
  • 1
    See [How to avoid using `printf()` in signal handlers](http://stackoverflow.com/questions/16891019/how-to-avoid-using-printf-in-a-signal-handler/16891799#16891799). – Jonathan Leffler Nov 04 '16 at 21:31
  • I did it, I created a function in the main to have access to the function close the socket. But now when I stop the program I'm getting this : `recvfrom: Bad file descriptor` which I think comes from the `perror` in the while loop because the recvfrom may also catch the `SIGINT` signal, what do you think ? – oktomus Nov 04 '16 at 22:09
  • 1
    @KevinM It sounds like you're going back into the `recvfrom()` loop after your signal handler runs. You need to exit the program after cleaning up. – Barmar Nov 04 '16 at 22:35