C程序中的命名管道(unix)

问题描述 投票:0回答:1

我必须使用3个过程来解决问题。第一个过程从(通过键盘输入)获取输入,并将其发送到第二个过程第二个过程将文本中的所有人声替换为12345(a替换为1,e替换为2,...)。我有一个运行良好的sh脚本(测试了它),该脚本使用sed来完成此任务。我会把它放在这里。阈值处理仅在屏幕上输出字母数字行。我还获得了一个脚本,该脚本使用grep来完成此任务,并且效果很好(测试了一下)。这个过程应该通过命名管道(一个FIFO文件)进行通信,并且我在通过FIFO发送和接收数据时遇到了一些困难。当我使用写入功能将数据写入FIFO时,它将在屏幕上输出数据;当我处于第二个过程中并且尝试从FIFO中读取数据时,它只是在等待我输入的新输入。

第一个过程:

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

int main() {
    char text[500];  // buffer for the inputed text
    char aux[100];  // Also a buffer to save multi-line input into text buffer

    char* myfifo = "myfifo";
    int fd_text;  

    printf("\nInput: (to stop giving input just type 0 on a new line):\n");
    // Forming the text
    while(scanf("%[^\n]%*c", aux) == 1) {
        if(strcmp(aux, "0") == 0) 
            break;
        strcat(aux, "\n");
        strcat(text, aux);
        }
    strcat(text, "\0");
    // Everything works well reading the input 


    int returnValue = mkfifo(myfifo, 0666);
    if(returnValue < 0) {
        printf("mkfifo() failed\nerrno = %d\n", errno);
        if(errno == EEXIST) 
            printf("That file already exists.\n");
    }

    if(fd_text = open(myfifo, O_WRONLY) < 0) {
        printf("error while opening FIFO");
        exit(0);
    } 

    int indicator = write(fd_text, text, strlen(text) + 1);
    if(indicator == 0) {
        printf("error while writing to FIFO");
    }

    close(fd_text);
    return 0;
}

第二过程:

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

int main() {
    char text[500];  
    char* myfifo = "myfifo";

    int fd_text2;  

    if (fd_text2 = open(myfifo, O_RDONLY) < 0) {
        printf("error while opening FIFO");
        exit(1);
    }

    int result = read(fd_text2, text, 500);
    if (result < 0)
        printf("ERROR WHILE READING FROM THE FILE\n");
    printf("\n%d bytes were read from the file\n", result);
    printf("\nText read from FIFO:\n%s\n", text);

    // Saving the text into a txt to perfom the sed command on it
    FILE *fp_replace_text;
    fp_replace_text = fopen("replace_text.txt", "w");
    fprintf(fp_replace_text, "%s", text);
    fclose(fp_replace_text);

    system("chmod 777 replace.sh"); 
    system("./replace.sh replace_text.txt");  

    close(fd_text2);
    unlink(myfifo);
    return 0;
}

replace.sh

#!/bin/sh

sed -i 's/a/1/gi' $1
sed -i 's/e/2/gi' $1
sed -i 's/i/3/gi' $1
sed -i 's/o/4/gi' $1
sed -i 's/u/5/gi' $1

如果我能弄清为什么进程1和2之间的通信不起作用,进程3将是相同的,因此我不再发布它。

c unix fifo mkfifo
1个回答
0
投票

问题(应该引起编译器警告)在这样的语句中:

if(fd_text = open(myfifo, O_WRONLY) < 0)

[您似乎假设将对此进行从左到右的求值,首先为fd_text分配一个值,然后将该值与0进行测试以给出一个布尔值,该布尔值将确定是否进入if块。但是在C语言中,relational运算符(如<)优先于*赋值运算符(如=)。因此,首先我们将open命令的结果与0进行比较,然后将该比较的布尔结果分配给fd_text。因此,文件描述符丢失,并且进一步尝试访问fifo将失败。我们可以用一对括号来纠正:

if((fd_text = open(myfifo, O_WRONLY)) < 0)

更笼统地说,最好是尽可能地开发新功能独立。如果您想将文本发送到fifo并接收它,则只需在第一个模块中对一些文本进行硬编码,就不必使用所有代码即可读取用户输入,也不要尝试进一步的步骤来从文本发送文本。第二个模块需要进行其他修改,直到fifo正常工作。小步骤。

© www.soinside.com 2019 - 2024. All rights reserved.