C-并行写入和读取FIFO文件-意外行为

C-并行写入和读取FIFO文件-意外行为,c,pipe,fifo,C,Pipe,Fifo,我有两个管道到FIFO文件,读写器。我打开两个终端,在书写器上书写,并期望文本出现在阅读器上。出于某种原因,我正在经历非常奇怪的行为-有时会添加一个空格或一些字符,我不知道为什么。有人能帮我吗? 我附上读写器代码 读者: #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/stat.h> #include <unistd.h> #incl

我有两个管道到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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义BUF_大小1024
结构sigaction sigelp;
结构完整;
结构sigaction termAct;
结构统计;
内线;
字符大小[buf_SIZE];
int main(int argc,char*argv[]){
char*filePath=argv[1];
断言(argc==2);
sigHelp.sa_handler=SIG_IGN;
sigHelp.sa_标志=0;
sigemptyset(完整的sa_面具);
而(1){
int指标=1;
while(指示器){
int statErr=stat(文件路径,&st);
如果(statErr==0){
如果(!S_ISFIFO(st.st_模式)){
printf(“错误:文件不是FIFO文件。\n”);
}
否则{
指标=0;
打破
}
}
否则{
如果(errno==enoint){//等待文件
睡眠(1);
}
否则{
printf(“检查文件状态时出错-%s\n”,strerror(errno));
返回-1;
}
}
}
int INTR=SIGATION(SIGINT、SIGELP和完整);
如果(intErr==-1){
printf(“错误:sigint操作失败-%s\n”,strerror(errno));
返回-1;
}
int termErr=sigaction(SIGTERM、SIGELP和termAct);
如果(termErr==-1){
printf(“错误:sigterm操作失败-%s\n”,strerror(errno));
返回-1;
}
line=open(文件路径,O_RDONLY,S|u IRWXU | S|u IRWXG | S|u IRWXO);
断言(行!=-1);
而(1){
int readInd=读取(行、基本单位、基本单位大小);
如果(readInd==-1){
printf(“错误:读取FIFO文件失败-%s\n”,strerror(errno));
关闭(线路);
}
else if(readInd==0){
打破
}
printf(“%s”,buf);
}
关闭(线路);
int intE=sigaction(SIGINT,&完整,NULL);
如果(intE==-1){
printf(“错误:sigint操作失败-%s\n”,strerror(errno));
返回-1;
}
int termE=sigaction(SIGTERM和termAct,NULL);
如果(术语==-1){
printf(“错误:sigterm操作失败-%s\n”,strerror(errno));
返回-1;
}
}   
返回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);
        }
    }
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义行大小为1024
struct-sigaction-sigAct;
常量字符*文件名;
int FIOFILE;
int=0;
结构统计;
模式t模式;
无效手柄信号(int信号);
int main(int argc,char*argv[]){
断言(argc==2);
fileName=argv[1];
sigAct.sa_handler=&handle_signal;//函数的输入
int-si=sigaction(SIGINT,&sigAct,NULL);
if(si<0){
printf(“错误:sigint操作失败-%s\n”,strerror(errno));
返回-1;
}
int stin=sigaction(SIGTERM和sigAct,NULL);
if(stin<0){
printf(“错误:sigterm操作失败-%s\n”,strerror(errno));
返回-1;
}
int sp=sigaction(SIGPIPE,&sigAct,NULL);
如果(sp<0){
printf(“错误:信号管道操作失败-%s\n”,strerror(errno));
返回-1;
}
模式=访问权限;
int statSuc=stat(argv[1],&st);
如果(statSuc==-1){
if(errno!=enoint){
printf(“错误:统计失败-%s\n”,strerror(errno));
返回-1;
}
}
否则{//stat成功
int fifoInd=S_ISFIFO(st.st_模式);
如果(fifound!=0){
FIOFILE=打开(argv[1],仅限O_wr,模式);
}
否则{
int linkInd=unlink(argv[1]);
如果(linkInd==-1){
printf(“错误:取消链接失败-%s\n”,strerror(errno));
返回-1;
}
}
}
int fifoInd=mkfifo(argv[1],模式);
如果(fifound==-1){
printf(“错误:使fifo失败-%s\n”,strerror(errno));
返回-1;
}
FIOFILE=打开(argv[1],仅限O_wr,模式);
字符行[行大小];
while(fgets(线条、线条尺寸、标准尺寸)!=NULL){
写入(文件、行、字符串(行));
}
int unlinkSuc=unlink(argv[1]);
if(unlinkSuc==-1){
printf(“错误:取消链接失败-%s\n”,strerror(errno));
返回-1;
}
关闭(FIOFILE);
返回0;
}
无效句柄_信号(整数符号){
if(sign==SIGPIPE | | sign==SIGINT | | sign==SIGTERM){
如果(符号==SIGPIPE){
如果(警告指示器==0){
printf(“错误:写入关闭的管道\n”);
警告指标==1;
}
}
否则{
取消链接(文件名);
关闭(FIOFILE);
出口(1);
}
}
}
谢谢,如果时间太长,我很抱歉

write(fifoFile, line, strlen(line));
这不是写入读取器期望的终止NUL字节(因为读取器将其视为字符串)。改为:

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

你的环境是什么?(Linux、Windows)编译时始终启用所有警告,然后修复这些警告。(对于gcc,至少使用:
-Wall-Wextra-pedantic
)。发布的代码(在ubuntu linux 14.04上)无法编译!首先,在每个文件(在linux上)的开头插入语句:
#define _GNU_SOURCE
,这一行在writer中,`warndicator==1;`导致编译器发出警告:“语句无效[-Wunused value]”请勿
unlink