我写了一个FIFO的testing。 服务器通过FIFO向客户端写入string“hello”。 但似乎这两个进程都被阻塞了。我认为FIFO是打开的,可供服务器和客户端读写。 但是这两个进程什么都不输出。
/* FIFO test */ #include <stdio.h> #include <sys/types.h> #include <sys.stat.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <errno.h> #define FIFOPATH "/home/hel/fifo" // define file path int client(void); int server(void); int main(void) { pid_t pid; /* create FIFO */ if (mkfifo(FIFOPATH, S_IRUSR | S_IWUSR) < 0) { if (errno == EEXIST) { // already exists, ok } /* error */ else { exit(-1); } } /* create process */ pid = fork(); if (pid < 0) { // error, process exits. exit(-1); } else if (pid == 0) { // child, server server(); return 0; // exit } /* parent, client */ client(); return 0; } /* server */ int server(void) { int ret; int fd; /* open fifo for writing */ if ((fd = open(FIFOPATH, 0200)) < 0) { printf("%s\n", strerror(errno)); return -1; // error } ret = write(fd, "hello", 5); close(fd); return 0; } /* client */ int client(void) { char recvBuf[100]; int fd; int ret; /* open fifo for reading */ if ((fd = open(FIFOPATH, 0400)) < 0) { printf("%s\n", strerror(errno)); return -1; // error } ret = read(fd, recvBuf, 5); printf("ret: %d %d\n", ret, fd); printf("client receive %s\n", recvBuf); close(fd); return 0; }
你的代码有两个问题。 第一个是主要问题。
open
的flags
参数是不正确的。 它们不应该是unix文件许可标志,因为它看起来像你提供的。 服务器应该使用O_WRONLY
,客户端应该使用O_RDONLY
。 write(fd, "hello", 5);
并read(fd, recvBuf, 5);
不是写和读字符串的终止NUL字符。 然后它被打印为一个字符串: printf("client receive %s\n", recvBuf);
。 这会调用未定义的行为(即使程序可能看起来“有效”)。 更改5
到6
。 open()使用下列标志:
O_RDONLY open for reading only O_WRONLY open for writing only O_RDWR open for reading and writing O_NONBLOCK do not block on open or for data to become available O_APPEND append on each write O_CREAT create file if it does not exist O_TRUNC truncate size to 0 O_EXCL error if O_CREAT and the file exists O_SHLOCK atomically obtain a shared lock O_EXLOCK atomically obtain an exclusive lock O_NOFOLLOW do not follow symlinks O_SYMLINK allow open of symlinks O_EVTONLY descriptor requested for event notifications only O_CLOEXEC mark as close-on-exec
对于FIFO,您必须在您的程序中使用客户端中的O_RDONLY和服务器中的O_WRONLY。
0200和0400权限不能用于open()。 你可以检查as中的标志值
#define O_RDONLY 0x0000 /打开只读* /
#define O_WRONLY 0x0001 /仅供打印 * /
这就是为什么在你的情况下打开块,因为它没有得到正确的标志。