2016-07-04 2 views
2

Я пишу тест для FIFO. Сервер записывает строку «привет» клиенту через FIFO. Но кажется, что эти два процесса заблокированы. Я думаю, что FIFO открыты для написания и чтения сервером и клиентом. Но два процесса ничего не выводят.Почему блокируются процессы при открытии 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

У вашего кода есть две проблемы. Первая проблема - главная проблема.

  1. Неверные параметры flags, внесенные в open. Они не должны быть флажками разрешения файлов unix, как вы видите. Сервер должен использовать O_WRONLY, и клиент должен использовать O_RDONLY.
  2. write(fd, "hello", 5); и read(fd, recvBuf, 5); не записывают и не считывают завершающий символ NUL строки. Но затем он печатается как строка: printf("client receive %s\n", recvBuf);. Это вызывает неопределенное поведение (хотя есть вероятность, что программа может показаться «работающей»). Изменение 5 по 6.
0

открыт() использует следующие флаги: -

 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/ открыт только для записи */

Вот почему открыт блоки в вашем случае, поскольку он не получает правильный флаг.

Смежные вопросы