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))