Как мне пассивно прослушивать stderr и получать его в виде строки для отправки в callback? Я видел сообщения о чтении stderr, но я хочу слушать его, а не активно читать.
Фон:
У меня есть кроссплатформенная часть, которая использует стороннюю библиотеку (libcurl), которая будет выводить подробную информацию в stderr. Этот кроссплатформенный компонент должен использоваться более чем в 1 кроссплатформенном приложении.
Я хотел бы зарегистрировать эту информацию, что я могу сделать, предоставив FILE * libcurl. Но вместо этого я хочу посмотреть, смогу ли я захватить (пассивно слушать) вывод в stderr как строка, и отправить обратно вызывающему основному приложению с помощью обратного вызова. Это дает преимущество 1. Основное приложение может вести единый журнал, используя любой инструмент для ведения журнала, какой захочет. 2. он будет держать эту часть кросс-платформенной.
Делать это в одном процессе немного сложно, но вы, вероятно, можете это сделать.
1: Используя freopen (), вы можете перенаправить ваш stderr в именованный файл. Вы можете одновременно открыть этот файл для чтения на другом дескрипторе. Вам также может понадобиться вызвать setvbuf () в stderr, чтобы отключить буферизацию при выводе в stderr, чтобы вы могли прочитать его сразу со 2-го дескриптора. Поскольку он записывается в файл, вы можете прочитать его в любое время — когда это удобно. Unix-функция «select» — это то, что вам нужно, если вы хотите получать уведомления об изменении файла. (см. также fileno ()).
2: Более сложным было бы установить stderr в качестве конца записи канала. Должно быть выполнимо с помощью dup3 (), хотя это не совсем кроссплатформенно (для не-Unixy ОС). Также потребуется, чтобы 2-й поток читал из канала, чтобы предотвратить блокировку писателя, если он пишет очень много.
Подобно:
FILE *stream = freopen("stderr.out", "w", stderr); // Added missing pointer
setvbuf(stream, 0, _IONBF, 0); // No Buffering
FILE *input = fopen("stderr.out", "r");
fprintf(stderr, "Output to stderr dude\n");
//fflush(stderr); // You can explicitly flush instead of setting no buffering.
char buffer[1024];
while (fgets(buffer, 512, input))
{
printf(">>>%s\n", buffer);
}
Других решений пока нет …