2016-11-04 15 views
1

問題:シングルハンドラが意図したとおりに動作し、Ctrlキーを押したときに "EXITED NICELY"が表示されます。これは割り当てであり、シグナルハンドラを使用する必要があります。ご覧のとおり、私はsigactionを実験しましたが、同じ結果になりました。シグナルハンドラが動作していないCのHTTPサーバ

現在の動作:シグナルハンドラが動作していることを示唆している「仕事」が印刷されていますが、プログラムをキャンセルしないためにどこかで動かなくてはなりません。 ctrl cを押してからcurl http:/ localhost:port/file.nameなどのHTTPリクエストをサーバーに送信すると、正常終了して目的のメッセージが表示されます。しかし、私はそれをしなければならないと私は要求を送信する必要はありません。

さらなる研究を通じて編集してください。私は受諾の電話の前と前に印刷物を置く。印刷前に一度だけ印刷すると、受け入れは接続を受け取るまでそれを保持します。それで問題はどこにあるのですか?それをどうやって修正するのですか?

#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ライブラリでは、確立信号とのハンドラは、値をsiginterruptで作られた設定に依存SA_RESTARTを除きゼロにすべてのフラグを設定します。これについては、Interrupted Primitivesを参照してください。

SA_RESTARTが設定されている場合は、信号意志ない割り込み(ほとんど)システムコールは、それは代わりに、それらを再起動します。 the signal man pageを参照してください:

シグナルハンドラが呼び出された場合は、システムコールやライブラリ関数呼び出しがブロックされている間は、次のいずれか

  • コールが自動的にシグナルハンドラが戻った後に再起動されます。または
  • 呼び出しがエラーEINTRで失敗します。

これらの2つの動作は、インターフェイスと、シグナルハンドラがSA_RESTARTフラグ(sigaction(2)を参照)を使用して確立されたかどうかによって異なります。

+0

ありがとう – TheMangaStand

関連する問題