open () вызывает завершение программы - PullRequest
0 голосов
/ 21 октября 2010

Я использую следующую программу для записи в fifo:

#include <iostream>
#include <fstream>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

using namespace std;

int main() {

    unlink("fifo1");

    if (mkfifo("fifo1", 0666) != 0) {
        cout << "Error while creating fifo" << endl;
        return 1;
    }
    else {
        cout << "Fifo created" << endl;
    }

    int fd = open("fifo1", O_WRONLY);
    if(fd == -1) {
        cout << "Could not open file" << endl;
        return 1;
    }
    else {
        cout << "Fifo opened" << endl;
    }


    int i=0;
    char* buffer = new char[20];
    while(true) {
        sprintf(buffer, "look: %i\n", i++);

        int r = write(fd, buffer, strlen(buffer));
        if(r == -1) {
            cout << "Fifo Error:" << fd << endl;
        }
        else {
            cout << "Wrote: " << i << "(" << r << "B)"<< endl;
        }
        sleep(1);
    }

    return 0;
}

Если я запускаю эту программу, запускаю другую оболочку и набираю там

cat < fifo1

Я вижу, что программа что-то записывает в канал, и я вижу результат в оболочке чтения. Если я остановлю команду cat с помощью CTRL ^ C, FIFO Writer завершит работу без сообщения об ошибке. Что является причиной этого? Почему не выдается ошибка?

Странно то, что если я запускаю приведенный выше код с Eclipse CDT, а оболочка чтения закрывается с помощью CTRL ^ C, программа продолжает печатать «Ошибка: 3».

Жду ваших идей, Heinrich

1 Ответ

3 голосов
/ 22 октября 2010

Если вы напишите в канал, когда другой конец канала будет закрыт, SIGPIPE будет доставлен вашему процессу. Без установленного обработчика сигнала это немедленно убьет ваш процесс. Обычно это вывод, я не знаю, почему не вижу этого.

Если вам больше нравится проверять коды ошибок записи, чем получать SIGPIPE, как подсказывает ваш код, вы должны игнорировать SIGPIPE:

#include <signal.h>

signal( SIGPIPE, SIG_IGN );
...