Search code examples
cnamed-pipesfifomkfifo

How to keep program unclosed after ctr+c in named pipe?


I have 2 programs. One is server one is client. The Client sending string to the server, the server is swapping the string and return to the client. the problems I have is when I pressing ctr+c the program(client) closed.(I'm using threads because I have been asking for.)

So how can I keep the program unclosed after ctr+c?

when clicking enter this is the right result and waiting for the server.
when clicking enter this is the right result

when entering ctl+c the program closed and cannot running server.c

when entering ctl+c the program closed.

The client.

    #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#define MAX_BUF 1024
// client
int main()
{
  int fd;
  char *myfifo = "myfifo";
  char str[MAX_BUF];

  printf("Input string: ");
  fgets(str, MAX_BUF, stdin);
  str[strlen(str) - 1] = '\0';

  if (mkfifo("myfifo", 0777) == -1)
  {
    if (errno != EEXIST)
    {
      printf("Could not create fifo file\n");
      return 1;
    }
  }

  /* create the FIFO (named pipe) */
  fd = open(myfifo, O_WRONLY);
  if (fd == -1)
    return 2;
  if (write(fd, str, MAX_BUF) == -1)
    return 3;
  close(fd);

  fd = open(myfifo, O_RDONLY);
  read(fd, str, MAX_BUF);
  printf("%s\n", str);
  /* remove the FIFO */
  unlink(myfifo);

  return 0;
}

The server

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#include <pthread.h>

#define MAX_BUF 1024
// server

// creatring struct for saving data
typedef struct thread_data
{
  char str[MAX_BUF];
  int result;

} thread_data;
// the
void *routine(void *arg)
{
  int fd[2];
  char *myfifo = "myfifo";
  thread_data *tdata = (thread_data *)arg;
  if (!(strcmp(tdata->str, "exit")))
    tdata->result = 1; // is exit
  else
    tdata->result = 0; // not exit
  if (tdata->result == 1)
  {
    fd[1] = open(myfifo, O_WRONLY);
    write(fd[1], "Done", sizeof(MAX_BUF));
    close(fd[1]);
  }
  else
  {
    char string[MAX_BUF] = {0};
    char c = 0;
    int length = 0, i = 0;

    length = strlen(tdata->str);
    printf("\nBefore Swap : %s\n", tdata->str);

    for (i = 0; i < length / 2; i++)
    {
      c = tdata->str[i];
      tdata->str[i] = tdata->str[length - 1 - i];
      tdata->str[length - 1 - i] = c;
    }
    printf("\nAfter Swap String : %s\n", tdata->str);
    fd[1] = open(myfifo, O_WRONLY);
    write(fd[1], tdata->str, sizeof(MAX_BUF));
    close(fd[1]);
  }
  pthread_exit(NULL);
}

int Calculation()
{
  int fd[2];
  // fd[0] read
  // fd[1] write
  char *myfifo = "myfifo";
  char buf[MAX_BUF];

  /* open, read, and display the message from the FIFO */
  fd[0] = open(myfifo, O_RDONLY);
  if(fd[0]==-1)
  return 4;
  if(read(fd[0], buf, MAX_BUF)==-1)
  return 5;
  close(fd[0]);

  // res
  int result;
  thread_data tdata;
  strcpy(tdata.str, buf);

  pthread_t t1;
  if (pthread_create(&t1, NULL, &routine, (void *)&tdata) != 0)
  {
    return 1;
  }
  if (pthread_join(t1, NULL) != 0)
  {
    return 2;
  }
}

int main()
{
  int res = Calculation();
  return res;
}

Solution

  • To avoid closing a program you should capture and manage the signal sent by CTRL + C, that is SIGINT, I have modified the code so that it captures the signal CTRL + C

    #include  <signal.h> 
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <sys/stat.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <time.h>
    #define MAX_BUF 1024
    // client
    
    int main()
    {
       signal(SIGINT,SIG_IGN); // Register signal handler for ignoring the signal
      int fd;
      char *myfifo = "myfifo";
      char str[MAX_BUF];
    
      printf("Input string: ");
      fgets(str, MAX_BUF, stdin);
      str[strlen(str) - 1] = '\0';
    
      if (mkfifo("myfifo", 0777) == -1)
      {
        if (errno != EEXIST)
        {
          printf("Could not create fifo file\n");
          return 1;
        }
      }
    
      /* create the FIFO (named pipe) */
      fd = open(myfifo, O_WRONLY);
      if (fd == -1)
        return 2;
      if (write(fd, str, MAX_BUF) == -1)
        return 3;
      close(fd);
    
      fd = open(myfifo, O_RDONLY);
      read(fd, str, MAX_BUF);
      printf("%s\n", str);
      /* remove the FIFO */
      unlink(myfifo);
    
      return 0;
    }