管道没有名字,只能用于有一个共同祖先进程的各个进程之间。
FIFO指代先进先出,它是一个单向的数据流,每个FIFO有一个路径名与之相关联,从而允许无亲缘关系的进程访问同一个FIFO。FIFO也被称为有名管道。
#include <sys/types.h> #include <sys/stat.h> int mkfifo(const char *pathname, mode_t mode); //返回:成功为0,出错为-1
无亲缘关系的客户/服务器:
//fifo.h #include "unpipc.h" #define FIFO1 "/tmp/fifo.1" #define FIFO2 "/tmp/fifo.2"
//server.c #include "fifo.h" void server(int, int); int main(int argc, char **argv) { int readfd, writefd; /* 4create two FIFOs; OK if they already exist */ if ((mkfifo(FIFO1, FILE_MODE) < 0) && (errno != EEXIST)) err_sys("can't create %s", FIFO1); if ((mkfifo(FIFO2, FILE_MODE) < 0) && (errno != EEXIST)) { unlink(FIFO1); err_sys("can't create %s", FIFO2); } readfd = Open(FIFO1, O_RDONLY, 0); writefd = Open(FIFO2, O_WRONLY, 0); server(readfd, writefd); exit(0); } void server(int readfd, int writefd) { int fd; ssize_t n; char buff[MAXLINE+1]; /* 4read pathname from IPC channel */ if ( (n = Read(readfd, buff, MAXLINE)) == 0) err_quit("end-of-file while reading pathname"); buff[n] = '\0'; /* null terminate pathname */ if ( (fd = open(buff, O_RDONLY)) < 0) { /* 4error: must tell client */ snprintf(buff + n, sizeof(buff) - n, ": can't open, %s\n", strerror(errno)); n = strlen(buff); Write(writefd, buff, n); } else { /* 4open succeeded: copy file to IPC channel */ while ( (n = Read(fd, buff, MAXLINE)) > 0) Write(writefd, buff, n); Close(fd); } }
//client.c #include "fifo.h" void client(int, int); int main(int argc, char **argv) { int readfd, writefd; writefd = Open(FIFO1, O_WRONLY, 0); readfd = Open(FIFO2, O_RDONLY, 0); client(readfd, writefd); Close(readfd); Close(writefd); Unlink(FIFO1); Unlink(FIFO2); exit(0); } void client(int readfd, int writefd) { size_t len; ssize_t n; char buff[MAXLINE]; /* 4read pathname */ Fgets(buff, MAXLINE, stdin); len = strlen(buff); /* fgets() guarantees null byte at end */ if (buff[len-1] == '\n') len--; /* delete newline from fgets() */ /* 4write pathname to IPC channel */ Write(writefd, buff, len); /* 4read from IPC, write to standard output */ while ( (n = Read(readfd, buff, MAXLINE)) > 0) Write(STDOUT_FILENO, buff, n); }
O_NONBLOCK标志对管道和FIFO的影响: