2017-02-09 90 views
0

試圖實現信號處理程序,但收到警告:從不兼容的指針類型分配 - 如何解決?

assignment from incompatible pointer type [enabled by default] 
    act.sa_sigaction = sigChldHandler; 

...還有我的教授指出。

char * argv[3]; 
argv[0]= GUESSER_PROGNAME; 
argv[2]= NULL; 

這個分配內存,3字符指針瓦爾,但他們並不特別指向任何地方,」但我不知道他指的是什麼。

\文件1

#include "assign2Headers.h" 
pid_t answererPid; 
pid_t guesserPid; 

int shouldRun = 1; 

void sigAlrmHandler(int sig) 
{ 
    kill(answererPid,TIME_OVER_SIGNAL); 
    kill(guesserPid,TIME_OVER_SIGNAL); 
    shouldRun=0; 
} 

void sigChldHandler(int sig) 
{ 
wait(NULL); 
shouldRun=0; 
} 

int main(void){ 


    struct sigaction act; 
    memset(&act, '\0', sizeof(struct sigaction)); 

    act.sa_handler = sigAlrmHandler; 
    sigaction(SIGALRM, &act, NULL); 

    act.sa_sigaction = sighldHandler; 
    sigaction(SIGCHLD, &act, NULL); 


char line[LINE_LEN]; 
char * argv[3]; 
argv[0]= GUESSER_PROGNAME; 
argv[2]= NULL; 
answererPid = fork(); 

if(answererPid == 0){ 

     execl(ANSWERER_PROGNAME,ANSWERER_PROGNAME,(char*)NULL); 

    } 

else{ 
     sleep(1); 
     snprintf(line,LINE_LEN,"%d",answererPid); 
     guesserPid=fork(); 
     if(guesserPid==0) 
     { 
      execl(GUESSER_PROGNAME,GUESSER_PROGNAME,argv[0],line,(char*)NULL); 
     } 
     else 
     { alarm(NUM_SECONDS); 
      while(shouldRun) 
       sleep(1); 
      sleep(1); 
      sleep(1); 
      printf("launcher finished\n"); 
      return (EXIT_SUCCESS); 

     } 

    } 

} 

\文件2

#include "assign2Headers.h" 

int shouldRun = 1; 

void timeoverhandler(int sig) 
{ sleep(1); 
    printf("\nOh no! The time is up!\n"); 
    printf("guesser finished\n"); 
    shouldRun=0; 
    exit(EXIT_SUCCESS); 
} 

void winsignalhandler(int sig) 
{ 
    printf("\nCongratulations! You found it!\n"); 
    shouldRun=0; 
     signal(WIN_SIGNAL,winsignalhandler); 
} 

void correctsignalhandler(int sig) 
{ 
    printf("Yay! That was right!\n"); 
    signal(CORRECT_SIGNAL,correctsignalhandler); 
} 

void incorrectsignalhandler(int sig) 
{ 
    printf("Oops! That was wrong. Please restart from the beginning.\n" 
"\nRe-starting from the beginning:\n"); 
    signal(INCORRECT_SIGNAL,incorrectsignalhandler); 
} 

int main(int argc,char* argv[]) 
{ 

    pid_t answererPid=atoi(argv[1]); 
    signal(TIME_OVER_SIGNAL,timeoverhandler); 
    signal(WIN_SIGNAL,winsignalhandler); 
    signal(CORRECT_SIGNAL,correctsignalhandler); 
    signal(INCORRECT_SIGNAL,incorrectsignalhandler); 

    while(shouldRun) 
    { int guess; 
     printf("What would you like your next guess to be: 0 or 1? "); 
     scanf("%d",&guess); 
     if(guess==0) 
      kill(answererPid,ZERO_SIGNAL); 
     if(guess==1) 
      kill(answererPid,ONE_SIGNAL); 
     sleep(2); 

    } 


    printf("guesser finished\n"); 
    return (EXIT_SUCCESS); 


} 

\文件3

//---  Common standard header files    ---// 

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <signal.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <unistd.h> 

////---  Common constants:     ---// 

#define  ZERO_SIGNAL  SIGUSR1  
#define  ONE_SIGNAL  SIGUSR2 
#define  CORRECT_SIGNAL  SIGUSR1 
#define  INCORRECT_SIGNAL SIGUSR2 
#define  WIN_SIGNAL  SIGINT 
#define  TIME_OVER_SIGNAL SIGTERM 

#define  GUESSER_PROGNAME "guesser" 
#define  ANSWERER_PROGNAME "answerer" 

#define  LINE_LEN  256 
#define  NUM_SECONDS  30 

\文件4

//---  Inclusion of header files    ---// 

#include "assign2Headers.h" 

//---  Definition of constants:    ---// 

#define  PATTERN_LEN 4 

//---  Definition of global vars:    ---// 

int  answer; 
int  numCorrect = 0; 
int  shouldRun = 1; 


//---  Definition of global fncs:    ---// 

void  timeUpHandler (int  sig 
       ) 
{ 
    shouldRun = 0; 
} 


void  guessHandler (int  sig, 
       siginfo_t* infoPtr, 
       void*  dataPtr 
       ) 
{ 
    int toSendBack; 
    int userBit  = (sig == ONE_SIGNAL); 
    int correctBit = ((answer >> numCorrect) & 0x1); 
    int isCorrect = (correctBit == userBit); 

    printf("position %d: userBit %d, correctBit %d\n", 
    numCorrect,userBit,correctBit 
    ); 

    if (isCorrect) 
    { 
    numCorrect++; 

    if (numCorrect >= PATTERN_LEN) 
     toSendBack = WIN_SIGNAL; 
    else 
     toSendBack = CORRECT_SIGNAL; 
    } 
    else 
    { 
    numCorrect = 0; 
    toSendBack = INCORRECT_SIGNAL; 
    } 

    kill(infoPtr->si_pid,toSendBack); 
} 


int  main  (int argc, 
       char* argv[] 
       ) 
{ 
    // I. Application validity check: 

    // II. Run program: 
    // II.A. Initialize random number generator and choice: 
    srand(getpid()); 

    answer = rand() % (1 << PATTERN_LEN); 

printf("(The answer is %d)\n",answer); 

    // II.B. Install signal handlers: 
    struct sigaction act; 

    memset(&act,'\0',sizeof(act)); 
    act.sa_handler = timeUpHandler; 
    sigaction(TIME_OVER_SIGNAL,&act,NULL); 

    act.sa_flags  = SA_SIGINFO; 
    act.sa_sigaction = guessHandler; 
    sigaction(ZERO_SIGNAL,&act,NULL); 
    sigaction(ONE_SIGNAL,&act,NULL); 

    // II.C. Hand out while game still active: 
    while ((numCorrect < PATTERN_LEN) && shouldRun) 
    sleep(1); 

    // III. Finished, return answer: 
    printf("answerer finished\n"); 
    return(EXIT_SUCCESS); 
} 

如何刪除這個警告,他對我們意味着什麼?請有人幫助我。

+0

'的char * argv的[3]。 argv [0] = GUESSER_PROGNAME; argv [2] = NULL;'不明白爲什麼把一個字符串放到指針數組中。 – minigeek

+0

@RoadRunner是啊!他不需要一個malloc語句嗎? – minigeek

回答

3

我想你正在開發Linux。從sigaction手冊頁:

struct sigaction { 
     void  (*sa_handler)(int); 
     void  (*sa_sigaction)(int, siginfo_t *, void *); 
     sigset_t sa_mask; 
     int  sa_flags; 
     void  (*sa_restorer)(void); 
    }; 

原型void sigChldHandler(int sig)不匹配sa_sigaction。因此警告。

您可以使用

  1. sa_handler設置信號處理函數或指定SIG_IGN/SIG_DFL行動。
  2. sa_sigaction設置信號處理函數 - 如果用戶需要訪問像用戶上下文和siginfo結構(發送者進程的詳細信息,信號類型等)更多的細節。此用法需要在sa_flags中設置SA_SIGINFO

對於您的情況,設置sa_handler可能就足夠了。

main()

struct sigaction act; 
act.sa_handler = sigChldHandler; 
act.sa_flags = SA_RESTART; 
sigaction(SIGCHLD, &act, NULL); 

此外,

  1. 使用單獨sigaction每個信號要設置,除非你想爲他們相同的處理結構。
  2. 請勿混用sigaction() & signal()用法。堅持一個。也許,sigaction,因爲它是新的&提供比signal()更多的功能。
+1

請在回答中說明如何更改(替換爲這個),以便幫助未來的訪問成員 – minigeek

+0

所以我會替換:{struct sigaction act; memset(&act,'\ 0',sizeof(struct sigaction)); act.sa_handler = sigAlrmHandler; sigaction(SIGALRM,&act,NULL);} with {struct sigaction act; act.sa_handler = sigAlrmHandler; act.sa_flags = SA_RESTART; sigaction(SIGALRM,&act,NULL);}} ..? –

+0

對於你想要處理的每個信號,添加四條線,就像我提到的。您需要爲每個信號使用單獨的sigaction結構變量(如act1,act2 ...)。 – ReddyVeeru

1

該段:

char * argv[3]; 
argv[0]= GUESSER_PROGNAME; 
argv[2]= NULL; 

是對argv[0]無效。由於argv是一個指針數組,因此在使用它們之前,需要確保這些指針指向某處。

這可以用strdup()實現:

argv[0]= strdup(GUESSER_PROGNAME); 

或用malloc()/strcpy()

argv[0]= malloc(strlen(GUESSER_PROGNAME)+1); 
strcpy(argv[0], GUESSER_PROGNAME); 

注:malloc()也應該檢查,它可以在失敗時返回NULL。在堆上分配的任何內存最後也應該是free()'d。

在清晰度方面,你可以取代:

#define GUESSER_PROGNAME "guesser" 

有:

const char *guesser_progname = "guesser"; 
+0

@ J.Doe爲什麼你想從這篇文章中刪除所有代碼?從您發佈的代碼中,這些建議可以幫助您。 – RoadRunner

+1

「*對於'argv [0]'*」無效:假定'#define GUESSER_PROGNAME「....」'this'char * argv [3]; argv [0] = GUESSER_PROGNAME;'是完全有效的。你是否想要提到'argv [1]'的有效性? – alk

+0

@alk是的你是對的,OP從那時起就改變了很多他的代碼,我認爲這個答案在技術上目前是錯誤的。我不知道我在想什麼,給一個指針設置一個常量字符串很好。 – RoadRunner