2017-02-09 5 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); 

     } 

    } 

} 
\

\ 파일이

#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

012,351 \ 6,
//---  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_flagsSA_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() '이어야합니다.

명확성의 관점에서

, 당신은 대체 할 수있다 :

#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