2016-11-04 6 views
1

Проблема: я хочу, чтобы мой единственный обработчик работал по назначению и распечатывал «EXITED NICELY» при нажатии ctrl C. Это назначение, и мы должны использовать обработчики сигналов. Как вы можете видеть, я также экспериментировал с sigaction, но с теми же результатами.Обработчик сигналов Не работает На моем C-сервере HTTP

Текущее поведение: «работа» распечатывается, указывая на то, что обработчик сигнала работает, однако он должен застрять где-то, потому что он не отменяет программу. Хотя, если я нажимаю ctrl c, а затем отправляю HTTP-запрос на сервер, например curl http:/localhost: port/file.name, он будет потом изящно выйти и распечатать мое нужное сообщение. Однако я хотел бы, чтобы это сделало это без меня, чтобы отправить запрос.

Редактировать в дальнейшем исследовании. Я помещаю печать после и до моего вызова. print before будет печатать один раз, а затем accept будет просто удерживать его, пока он не получит соединение. Итак, где проблема, но как мы это исправим?

#include<stdio.h> 
#include<string.h> 
#include<stdlib.h> 
#include<unistd.h> 
#include<sys/types.h> 
#include<sys/stat.h> 
#include<sys/socket.h> 
#include<arpa/inet.h> 
#include<netdb.h> 
#include<signal.h> 
#include<fcntl.h> 
#include "http_common.h" 
#define CONNMAX 1000 
#define BYTES 1024 

char *ROOT; 
int verbose; 
int signalReceived = 1; 
int listenfd, clients[CONNMAX]; 
void error(char *); 

static void clean(int arg) 
{ 
     if(arg == SIGINT) { 
       printf("work\n"); 
       signalReceived = 0; 
       //signal(SIGINT, clean); 
     } 
     else if(arg == SIGHUP) { 
       signalReceived = 0; 
     } 
} 

int main(int argc, char *argv[]) 
{ 
     //struct sigaction act; 
     //memset (&act, '\0', sizeof(act)); 
     //act.sa_handler = clean; 
     //sigemptyset(&act.sa_mask); 
     //act.sa_flags = SA_RESTART; 
     signal(SIGINT, clean); 
     //signal(SIGHUP, clean); 
     //if (sigaction(SIGINT, &act, NULL) == -1) 
     //  printf("doing something\n"); 
     struct sockaddr_in clientaddr; 
     socklen_t addrlen; 
     char c; 
     char PORT[6]; 
     ROOT = getenv("PWD"); 
     strcpy(PORT, "8888"); 
     int slot; 
     while ((c = getopt (argc, argv, "p:v")) != -1) 

       switch (c) { 
       case'v': 
         verbose = 1; 
         break; 
       case'p': 
         strcpy(PORT, optarg); 
         break; 
       case'?': 
         fprintf(stderr, "Wrong arguments given\n"); 
         exit(1); 
       default: 
         exit(1); 
       } 
     printf("Listening on port %s%s%s, root is %s%s%s\n", "\033[92m", PORT, "\033[0m", "\033[92m", ROOT, "\033[0m"); 
     int i = 0; 
     for (i = 0; i < CONNMAX; i++) 
       clients[i] = -1; 
     startServer(PORT, &listenfd); 
     while (signalReceived == 1) { 
       addrlen = sizeof(clientaddr); 
       clients[slot] = accept (listenfd, (struct sockaddr *) &clientaddr, &addrlen); 
       if (clients[slot] < 0) 
         exit(0); 
       else { 
         if (fork() == 0) { 
           respond(slot, verbose, ROOT, clients); 
          exit(0); 
         } 
       } 
       while (clients[slot] != -1) 
         slot = (slot + 1) % CONNMAX; 

     } 
     printf("EXITED NICLEY\n");//ients[slot] = accept (listenfd, (struct sockaddr *) &clientaddr, &addrlen); 
     return 0; 
} 

ответ

1

Вы должны зарегистрировать сигнал с sigaction() и без SA_RESTART флага.

Когда вы зарегистрируете обработчик сигнала с signal(), он установит флаг SA_RESTART. См the glibc manual:

В GNU C Library, устанавливая обработчик сигнала с устанавливает все флаги нуля SA_RESTART, величина которого зависит от настроек, которые вы сделали с siginterrupt исключением. См. «Прерванные примитивы», чтобы узнать, что это значит.

Когда SA_RESTART установлен, то сигнал будет не прерывания (большинство) системные вызовы, но вместо этого перезапустить их. См the signal man page:

Если обработчик сигнала вызывается во время вызова системного вызова или функции библиотеки заблокирована, то либо:

  • вызов автоматически перезапущен после возвращения обработчика сигнала; или
  • сбой вызова с ошибкой EINTR.

Какое из этих двух типов поведения зависит от интерфейса и независимо от того, был ли обработчик сигнала установлен с использованием флага SA_RESTART (см. Sigaction (2)).

+0

большое спасибо – TheMangaStand

 Смежные вопросы

  • Нет связанных вопросов^_^