为什么在打开FIFO时进程被阻止

时间:2016-07-04 03:18:06

标签: c linux

我为FIFO写了一个测试。服务器通过FIFO将字符串“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;
}

2 个答案:

答案 0 :(得分:2)

您的代码有两个问题。第一个是主要问题。

  1. 传递给flags的{​​{1}}参数不正确。它们不应该是你提供的unix文件权限标志。服务器应使用open,客户端应使用O_WRONLY
  2. O_RDONLYwrite(fd, "hello", 5);没有写入和读取字符串的终止NUL字符。但随后将其打印为字符串:read(fd, recvBuf, 5);。这会调用未定义的行为(即使程序很可能出现在&#34; work&#34;)。将printf("client receive %s\n", recvBuf);更改为5

答案 1 :(得分:0)

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()。你可以在

中检查标志值

#define O_RDONLY 0x0000 / 仅供阅读* /

#define O_WRONLY 0x0001 / 仅供写入* /

这就是为什么在你的情况下打开块,因为它没有得到正确的标志。