FIFO – іменовані канали

За допомогою труб можуть спілкуватися тільки споріднені один з одним процеси, отримані за допомогою fork (). Іменовані канали FIFO дозволяють обмінюватися даними з абсолютно "чужим" процесом.

Синтаксис функції для створення FIFO наступний:

int mkfifo(const char *fifoname, mode_t mode); При виникненні помилки функція повертає -1, інакше 0. Як перший параметр вказується шлях, де буде FIFO. Другий параметр визначає режим роботи із FIFO. Приклад використання наведено нижче:

int fd_fifo; /*дескриптор FIFO*/

char buffer[]="Текстовий рядок для fifo\n";

/*Якщо файл із таким ім'ям існує, видалимо його*/

if((mkfifo("/tmp/fifo0001.1", O_RDWR)) == -1)

fprintf(stderr, "Неможливо створити fifo\n");

/*Відкриваємо fifo для читання та запису*/

if((fd_fifo=open("/tmp/fifo0001.1", O_RDWR)) == - 1)

fprintf(stderr, "Неможливо відкрити fifo\n");

if(read(fd_fifo, &buf, sizeof(buf)) == -1)

fprintf(stderr, "Неможливо прочитати з FIFO\n");

printf("Прочитано з FIFO: %s\n",buf);

Якщо в системі відсутня функція mkfifo(), можна скористатися спільною функцією для створення файлу: int mknod(char *pathname, int mode, int dev);

Тут pathname вказує звичайне ім'я каталогу та ім'я FIFO. Режим позначається константою S_IFIFO із заголовного файлу. Тут же визначаються права доступу. Параметр dev не потрібний. Приклад виклику mknod :

if(mknod("/tmp/fifo0001.1", S_IFIFO S_IRUSR S_IWUSR,

Прапор O_NONBLOCK може бути використаний тільки при доступі для читання. При спробі відкрити FIFO з O_NONBLOCK для запису, виникає помилка відкриття. Якщо FIFO закрити для запису через close або fclose , це означає, що для читання у FIFO міститьсяEOF.

Якщо кілька процесів пишуть в той самий FIFO, необхідно звернути увагу на те, щоб відразу не записувалося більше, ніж PIPE_BUF байтів. Це необхідно, щоб дані не змішувалися один з одним. Встановити межі запису можна такою програмою: #include

/*Створюємо новий FIFO*/

if((mkfifo("fifo0001", O_RDWR)) == -1)

fprintf(stderr, "Неможливо створити FIFO\n");

printf("Можна записати в FIFO відразу %ld байтів\n",

printf("Одночасно можна відкрити %ld FIFO \n",

При спробі запису у FIFO, який не відкритий на даний момент для читання жодним процесом, генерується сигнал SIGPIPE .

У наступному прикладі організується обробник сигналу SIGPIPE, створюється FIFO, процес-нащадок записує дані в цей FIFO, а батько читає їх звідти. Приклад ілюструє простий додаток типу "клієнт - сервер":

static volatile sig_atomic_t sflag;

static sigset_t signal_new, signal_old, signal_leer;

static void sigfunc(int sig_nr)

fprintf(stderr, "SIGPIPE викликає завершення

if(signal(SIGPIPE, sigfunc) == SIG_ERR)

fprintf(stderr, "Неможливо отримати сигнал

/*Видаляємо всі сигнали з безлічі сигналів*/

/*Встановлюємо signal_new та зберігаємо його*/

/* тепер маскою сигналів буде signal_old*/

else if(pid > 0) /*Батько читає з FIFO*/

if (( r_fifo=open("/tmp/fifo0001.1", O_RDONLY))