从stdin读取并“加密”子进程中的输入

时间:2014-11-23 11:13:58

标签: c fork wait child-process

我必须编写一个C程序来执行以下操作:

  • 从stdin读取
  • 使用 fork 创建子进程,并在该子进程中使用 crypt 加密输入
  • 使用 sleep 以及一些随机时间来模拟加密过程和子进程的异步工作
  • 在我的父进程中我应该捕获我的子进程的所有退出代码(使用单一SIGCHLD)
  • 如果用户按 Ctrl + C 我的程序应该等待所有子进程完成,然后终止
  • 如果用户按 Ctrl + D ,我应该"忽略"那并从stdin再次阅读
  • 我正在使用 fgets 从stdin读取,我也应该抓住 EINTR 错误(我认为' s Ctrl + D "信号"?)

到目前为止,这是我的代码:

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"
#include "crypt.h"
#include "signal.h"
#include "errno.h"
#include "sys/wait.h"

char * encryptWord(char* word);
void childTerminated(int sig);
void terminateAllAndExit(int sig);
void nop(int sig);

void readFromStdin();

int childPIDs[1024];
int childProcesses = 0;

int main(int argc, char ** argv) {
    readFromStdin();
}

void readFromStdin(void) {
    char buffer[1024];
    int pid;
    while(fgets(buffer, 1024, stdin) != NULL) {
        pid = fork();
        if(pid == 0) {
            signal(SIGINT, nop);
            char * encrypted = encryptWord(buffer);
            sleep(rand() % 10);
            printf("ecnr: %s -> %s\n", buffer, encrypted);
            exit(EXIT_SUCCESS);
        }
        else if(pid > 0) {
            signal(SIGCHLD, childTerminated);
            signal(SIGINT, terminateAllAndExit);
            childPIDs[childProcesses] = pid;
            childProcesses++;           
        }       
    }
    //printf("childProcesses: %d", childProcesses);
}

char * encryptWord(char* word) {
    // remove the \n at the end of the input
    word[strlen(word)-1] = 0;
    word = crypt(word,"sr");
    return word;
}

void childTerminated(int sig) {
    childProcesses--;
    //printf("child terminated.\n");
}

void terminateAllAndExit(int sig) {
    //pid_t p;
    int status; 
    //printf("childProcesses: %d\n", childProcesses);
    while(childProcesses > 0) {
        (void)wait(&status);
        if(WEXITSTATUS(status) == EXIT_SUCCESS) {
            childProcesses--;
        }
    }
    printf("All child processes terminated. Exiting...\n");
    exit(EXIT_SUCCESS);
}

void nop(int sig) {
    //signal(SIGINT, nop);
}

现在代码工作得很好,加密在我的子进程中工作,并模拟加密输入所需的时间。

但是,如果我按 Ctrl + C ,它的工作方式不应该如何。所有子进程都会立即终止,而不是等待我在 sleep 中设置的时间。

最后一个,我怎样才能抓住 EINTR 错误?

感谢您的帮助!

0 个答案:

没有答案