FIFO

FIFO(first in, first out)。每一個fifo與路徑名有關,從而容許無親緣關係的進程訪問同一個FIFO。服務器

#include <sys/types.h>函數

#include <sys/stat.h>code

int mkfifo(const char *pathname, mode_t mode);server

注意:進程

mkfifo已經已經隱含指定O_CREAT | O_EXCL,這就會致使要麼建立一個新的fifo文件,要麼就會返回一個EEXIT錯誤。it

FIFO不能打開來既是讀也是寫,由於它是半雙工的。io

read老是從開頭開始讀,write老是往末尾寫。class

若是用了lseek函數,則會返回錯誤ESPIPE。cli

要刪除一個fifo文件用函數unlink()。服務器端

例子:重寫管道一中的客戶--服務器程序,用兩個FIFO代替兩個管道。

代碼:

//mainfifo.c 
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <stdlib.h>

#define FILEMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)//FIFO文件打開權限
#define FIFO1 "/tmp/fifo.1"
#define FIFO2 "/tmp/fifo.2"



void client(int, int),server(int, int);

int main(int argc, char **argv)
{
    pid_t childfd;
    int readfd, writefd;
    char buff[20];

    if ((mkfifo(FIFO1, FILEMODE) < 0) && (errno != EEXIST)) {//建立FIFO1文件,若是已經存在報錯,不處理。
        snprintf(buff, sizeof(buff), "can't create %s\n", FIFO1);
        perror(buff);
    }

    if ((mkfifo(FIFO2, FILEMODE) < 0) && (errno != EEXIST)){//建立FIFO1文件,若是已經存在報錯,不處理。

        snprintf(buff, sizeof(buff), "can't create %s\n", FIFO2);
        perror(buff);
        unlink(FIFO1);
    }
    
    if ( (childfd = fork()) == 0) {//子進程
        readfd = open(FIFO1, O_RDONLY, 0);//以只讀模式打開FIFO1
        writefd = open(FIFO2, O_WRONLY, 0);//以只寫模式打開FIFO2
        server(readfd, writefd);//從第一個參數獲取文件路徑名,而後打開此文件,並將文件內容寫入第二個參數中去。
        exit(0);
    }
    /*父進程*/
    writefd = open(FIFO1, O_WRONLY, 0);//以只寫模式打開FIFO1
    readfd = open(FIFO2, O_RDONLY, 0);//以只讀模式打開FIFO2

    client(readfd, writefd);//從標準輸入裏讀取文件路徑名,而後將其寫入第二個參數中去,
                             //同時從第一個參數中獲取服務器端返回的文件內容,並將其輸出到標準輸出裏
    waitpid(childfd, NULL, 0);
    
    close(readfd);
    close(writefd);

    unlink(FIFO1);//刪除掉FIFO文件
    unlink(FIFO2);

    exit(0);
}
相關文章
相關標籤/搜索