簡體   English   中英

C - 並行寫入和讀取FIFO文件 - 意外行為

[英]C - writing and reading from FIFO file in parallel - unexpected behaviour

我有兩個管道到FIFO文件,讀寫器。 我打開兩個終端並在作者上寫字,並希望文本出現在閱讀器上。 出於某種原因,我遇到了非常奇怪的行為 - 有時會添加一個空格或一些字符,我不知道為什么。 有人能幫我嗎? 我附加了讀者和作者代碼。

讀者:

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

#define BUF_SIZE 1024

struct sigaction sigHelp;
struct sigaction intAct;
struct sigaction termAct;
struct stat st;
int line;
char buf[BUF_SIZE];
int main(int argc, char* argv[]) {
    char *filePath = argv[1];
    assert (argc == 2);
    sigHelp.sa_handler = SIG_IGN;
    sigHelp.sa_flags = 0;
    sigemptyset(&intAct.sa_mask);
    while(1) {
        int indicator = 1;
        while(indicator) {
            int statErr = stat(filePath, &st);
            if (statErr == 0) {
                if (!S_ISFIFO(st.st_mode)) {
                    printf("Error: file is not a FIFO file.\n");
                }
                else {
                    indicator = 0;
                    break;
                }
            }
            else {
                if (errno == ENOENT) { //wait for file
                    sleep(1);
                }
                else {
                    printf("Error checking file status - %s\n", strerror(errno));
                    return -1;
                }
            }
        }
        int intErr = sigaction(SIGINT, &sigHelp, &intAct);
        if(intErr == -1) {
            printf("Error: sigint action failed - %s\n" ,strerror(errno));
            return -1;
        }
        int termErr = sigaction(SIGTERM, &sigHelp, &termAct);
        if(termErr == -1) {
            printf("Error: sigterm action failed - %s\n" ,strerror(errno));
            return -1;
        }
        line = open(filePath, O_RDONLY, S_IRWXU|S_IRWXG|S_IRWXO);
        assert(line != -1);
        while (1) {
            int readInd = read(line, buf, BUF_SIZE);
            if(readInd == -1){
                printf("Error: failed reading from FIFO file - %s\n", strerror(errno));
                close(line);
            }
            else if(readInd == 0) {
                break;
            }
            printf("%s ", buf);
        }
        close(line);
        int intE = sigaction(SIGINT, &intAct, NULL);
        if(intE == -1){
            printf("Error: sigint action failed - %s\n" ,strerror(errno));
            return -1;
        }
        int termE = sigaction(SIGTERM, &termAct, NULL);
        if(termE == -1){
            printf("Error: sigterm action failed - %s\n" ,strerror(errno));
            return -1;
        }
    }   
    return 0;
}

作家:

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

#define LINE_SIZE 1024

struct sigaction sigAct;
const char* fileName;
int fifoFile;
int warnIndicator = 0;
struct stat st; 
mode_t mode;
void handle_signal(int signal);
int main(int argc, char *argv[]){
    assert(argc == 2);
    fileName = argv[1];
    sigAct.sa_handler = &handle_signal; //opinter to function
    int si = sigaction(SIGINT, &sigAct, NULL); 
    if (si < 0) {
        printf("Error: sigint action failed - %s\n",strerror(errno));
        return -1;
    }
    int stin = sigaction(SIGTERM, &sigAct, NULL);
    if (stin < 0) {
        printf("Error: sigterm action failed - %s\n",strerror(errno));
        return -1;
    }
    int sp = sigaction(SIGPIPE, &sigAct, NULL);
    if (sp < 0) {
        printf("Error: sigpipe action failed - %s\n",strerror(errno));
        return -1;
    }
    mode = ACCESSPERMS;
    int statSuc = stat(argv[1], &st);
    if (statSuc == -1) {
        if (errno != ENOENT) {
            printf("Error: stat failed - %s\n", strerror(errno));
            return -1;
        }
    }
    else { // stat success
        int fifoInd = S_ISFIFO(st.st_mode);
        if (fifoInd != 0) {
            fifoFile =  open(argv[1], O_WRONLY, mode);
        }
        else {
            int linkInd = unlink(argv[1]);
            if (linkInd == -1) {
                printf( "Error: unlink failed - %s\n", strerror(errno));
                return -1;
            }
        }
    }
    int fifoInd = mkfifo(argv[1], mode);
    if (fifoInd == -1) {
        printf("Error: making fifo failed - %s\n", strerror(errno));
        return -1;
    }
    fifoFile =  open(argv[1], O_WRONLY, mode);
    char line[LINE_SIZE];
    while (fgets(line, LINE_SIZE, stdin) != NULL) {
        write (fifoFile,line,strlen(line));
    }
    int unlinkSuc = unlink(argv[1]);
    if (unlinkSuc == -1) {
        printf( "Error: unlink failed - %s\n", strerror( errno ) );
        return -1;
    }
    close(fifoFile);
    return 0;
}
void handle_signal(int sign) { 
    if (sign == SIGPIPE || sign == SIGINT || sign == SIGTERM) {
        if (sign == SIGPIPE) {
            if (warnIndicator == 0) {
                printf("Error: writing to closed pipe \n");
                warnIndicator == 1;
            }
        }
        else {
            unlink(fileName);
            close(fifoFile);
            exit(1);
        }
    }
}

謝謝,對不起,如果太久了。

write(fifoFile, line, strlen(line));

這不是寫入讀者所期望的終止NUL字節(因為讀者將其視為字符串)。 改成:

write(fifoFile, line, strlen(line) + 1); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM