2016-12-22 1 views
3

こんにちは、私は システムは、C信号に呼び出し、フォーク

C.

で機能的なプログラムを解決するには、この問題をした「子プロセスCは、ユーザーを待つプロセスFは、子プロセスC. を作成するCプログラムを書きますパスワードが正しい場合は、父親に信号SIGUSR1を送信します.3回の試行後にパスワードが間違っていると、父親にSIGUSR2信号を送信して終了します。父親から受信した場合、SIGUSR1信号は、

父親が30秒後に(子供からの信号を受信して​​いない場合)、子に信号SIGUSR1を送り、exit(1)で終了する必要があります; SIGUSR1 sig nalはexit(0)で終了する必要があります。 。。それは信号SIGUSR2がexit(2)で終了する必要があります受信した場合、」

私はそれを解決しようとしているが、私はを突っ込んだこれは私がやったことです:

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

void fatherprocess(int mysignal){ 
    if (mysignal == SIGUSR1) { 
     printf("ACCESS GRANTED!\n"); 
     exit(0); 
    } 

    if (mysignal == SIGUSR2){ 
     printf("ACCESS DISCARDED! More than 3 tentatives!\n"); 
     exit(2); 
    } 

} 


void childprocess(int mysignal){ 
    if (mysignal == SIGUSR1) { 
     printf("TIMEOUT\n"); 
     exit(1); 
    } 
} 


int main(int argc, char *argcv[]){ 
    int fatherpid, childpid; 
    char enteredpassword[], password[] = "test"; 
    int i =0; 
    unsigned int time_to_sleep = 30; 

    fatherpid = getpid(); 
    childpid = fork(); 

    if (childpid == 0) { 
     printf("Child Process waiting for a password\n"); 
     while (1){ 
      if (i < 3) { 
       printf("Enter Password: "); 
       scanf("%s", enteredpassword); 
       if (enteredpassword == password) 
        signal(SIGUSR1, fatherprocess); 
      } else { 
       signal(SIGUSR2, fatherprocess); 
       exit(1); 
      } 
      i++; 
     } 
    } else { 
     printf("Father Process\n"); 
     while(time_to_sleep){ 
      time_to_sleep = sleep(time_to_sleep); 
      signal(SIGUSR1, childprocess); 
     } 
    } 
    return 0; 
    } 

I

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

void fatherprocess(int mysignal, int fatherpid){ 
    if (mysignal == SIGUSR1) { 
     printf("ACCESS GRANTED!\n"); 
     kill(fatherpid, SIGUSR1); 
     exit(0); 
    } 

    if (mysignal == SIGUSR2){ 
     printf("ACCESS DISCARDED! More than 3 tentatives!\n"); 
     kill(fatherpid, SIGUSR2); 
     exit(2); 
    } 

} 


void childprocess(int mysignal, int childpid){ 
    if (mysignal == SIGUSR1) { 
     printf("TIMEOUT\n"); 
     kill(childpid, SIGUSR1); 
     exit(1); 
    } 
} 


int main(int argc, char *argcv[]){ 
int fatherpid, childpid; 
char enteredpassword[] = "test", password[] = "test"; 
int i =0; 
unsigned int time_to_sleep = 30; 

fatherpid = getpid(); 
childpid = fork(); 

if (childpid == 0) { 
    printf("Child Process waiting for a password\n"); 
    while (1){ 
     if (i < 3) { 
      printf("Enter Password: "); 
      scanf("%s", enteredpassword); 
      if (strcmp(enteredpassword, password) == 0) 
       fatherprocess(SIGUSR1, fatherpid); 
     } else { 
      fatherprocess(SIGUSR2, fatherpid); 
      exit(1); 
     } 
     i++; 
    } 
} else { 
    printf("Father Process\n"); 
    while(time_to_sleep){ 
     time_to_sleep = sleep(time_to_sleep); 
     childprocess(SIGUSR1, childpid); 
    } 
} 
return 0; 
} 

は、今では完璧に動作しますが、私は運動のテキストを尊重してきた場合、私は知りません

+0

これは完全なコードのですか?シグナルハンドラはインストールされていません。 – Nish

+0

シグナルハンドラを設定する方法はわかりません: – JoKeRxbLaCk

+0

シグナルの代わりにkill systemcallを使用する必要がありますか? – JoKeRxbLaCk

答えて

0

コメントで述べたように:。「このように私のプログラムを編集しましシグナルを送るためにkill()システムコールを使用し、sigaction()のようなコールを使用してシグナルハンドラを登録する必要があります(Jonathan Leffler)。私は、これらの2つの呼び出しを、オンラインマニュアルページにリンクして、それらに関する追加情報を提供しています。

ここに、あなたの目標を達成するためにこれらを使用する方法を示すコードがあります。必要なプロンプトや受け入れ可能な入力文字列などのコードを追加/修正する必要があります。私はそれはそれを行うことができる方法の一例だだけで、これはそれを行うための最善の方法であると主張ませんよということに注意してください(それがコンパイルされ、私のために働いていた):

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

static void get_password(char* buf, int maxbuf) 
{ 
    fgets(buf, maxbuf, stdin); 
} 

static int is_password_correct(char* buf) 
{ 
    return buf[0] == 'a'; 
} 

volatile int got_signal = 0; 
volatile int child_signal = 0; 

static void parent_sig_handler(int signum) 
{ 
    if (!got_signal) 
    { 
     got_signal = signum; 
     printf("parent_sig_handler: got sig %d\n", signum); 
    } 
} 

static void child_sig_handler(int signum) 
{ 
    if (!child_signal) 
    { 
     child_signal = signum; 
     printf("child_sig_handler: got sig %d\n", signum); 
    } 
} 

int main() 
{ 
    struct sigaction act; 
    sigfillset(&act.sa_mask); 
    act.sa_handler = parent_sig_handler; 
    sigaction(SIGALRM, &act, NULL); 
    sigaction(SIGUSR1, &act, NULL); 
    sigaction(SIGUSR2, &act, NULL); 

    pid_t child_pid = fork(); 
    if (child_pid == -1) 
    { 
     perror("error forking"); 
     exit(3); 
    } 
    if (child_pid == 0) 
    { 
     printf("child running\n"); 
     act.sa_handler = child_sig_handler; 
     sigaction(SIGUSR1, &act, NULL); 
     pid_t parent_pid = getppid(); 
     for (int i = 0; i < 3; ++i) 
     { 
      char passwd[64]; 
      passwd[0] = '\0'; 
      get_password(passwd, sizeof(passwd)); 
      if (is_password_correct(passwd)) 
      {  
       kill(parent_pid, SIGUSR1); 
       exit(0);  
      }  
     } 
     kill(parent_pid, SIGUSR2); 
     exit(2); 
    } 

    printf("parent running\n"); 
    alarm(30); /* sets parent up to receive a SIGALRM signal in 30 seconds */ 
    sigset_t sigmask; 
    sigemptyset(&sigmask); 
    while (!got_signal) 
    { 
     sigsuspend(&sigmask); 
    } 

    switch (got_signal) 
    { 
     case SIGALRM: 
      kill(child_pid, SIGUSR1); 
      exit(1); 
     case SIGUSR1: 
      exit(0); 
     case SIGUSR2: 
      exit(2); 
     default: 
      exit(3); 
    } 
    exit(3); 
} 
関連する問題