2017-02-09 88 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