LINUX.ORG.RU

Захват stdout'а какой-либо программы в своей программе (СИ)

 


0

1

Здравствуйте.

Я уже задавал подобный вопрос, ответ на него вроде бы прост:

#include <stdio.h>

int main() 
{
	FILE *in;
	char buff[512];

	if(!(in = popen("df -h", "r")))
         {
		printf("xana");
	 }

	while(fgets(buff, sizeof(buff), in)!=NULL)
         {
		printf("RECIV:%s", buff);
	 }

	pclose(in);
    return 0;
}

Получаю всё как положено.

RECIV:Файл.система   Размер Использовано  Дост Использовано% Cмонтировано в
RECIV:udev             3,9G         4,0K  3,9G            1% /dev
RECIV:tmpfs            799M         1,4M  798M            1% /run
RECIV:/dev/sdb1        143G         105G   31G           78% /
RECIV:none             4,0K            0  4,0K            0% /sys/fs/cgroup
RECIV:none             5,0M            0  5,0M            0% /run/lock
RECIV:none             3,9G          28M  3,9G            1% /run/shm
RECIV:none             100M          52K  100M            1% /run/user

Программа которую я планирую запускать (это майнер EWBF) подключается к пулу (передавая ему пароль) и начинает майнить.

Дык вот в чём дело: если запустить майнер с НЕ правильным паролем, то он выдаёт сообщение об ошибке, а моя программа ловит его и завершает работу.

RECIV:+-------------------------------------------------+
RECIV:|         EWBF's Zcash CUDA miner. 0.3.4b         |
RECIV:+-------------------------------------------------+
RECIV:INFO: Current pool: zec.suprnova.cc:2142
RECIV:INFO: Selected pools: 1
RECIV:INFO: Solver: Auto.
RECIV:INFO: Devices: All.
RECIV:INFO: Temperature limit: 90
RECIV:INFO: Api: Disabled
RECIV:---------------------------------------------------
RECIV:INFO: Target: 003c3c3c3c3c3c3c...
RECIV:INFO: Detected new work: 4902
RECIV:ERROR: Stratum authorization error

Если же запустить с правильными данными, то моя программа ничего не ловит, как будто майнер ничего не выдаёт (а он выдаёт).

То есть (как я думаю) когда майнер запускается с правильными данными, то внутри что-то форкается и инфа выдаётся неизвестно куда. (другого объяснения я не занаю)

Такое может быть? Или почему вобще так происходит?

П.С. Извиняюсь за формулировку вопроса и заранее спасибо.



Последнее исправление: stD (всего исправлений: 1)

Ответ на: комментарий от vodz

Я так понимаю, что это как-то связано с буфером. Не подскажите как это применить к моему коду, а то я что-то не соображу, что с этим делать?

stD
() автор топика
Ответ на: комментарий от stD

Создаёте файлик line_buffer.с c содержимым:

#include <stdio.h>
__attribute__((constructor)) void f()
{
    setvbuf(stdout,NULL,_IOLBF,0);
}

Компилируйте: gcc -fPIC -shared -o line_buffer.so line_buffer.с

Вставляете в ваш popen(«LD_PRELOAD=line_buffer.so miner»)

vodz ★★★★★
()
Ответ на: комментарий от xmikex

он же не в stdout выдает тогда, а использует ncurses библиотеку скорее всего.

Судя по примеру вывода, там обычный текст.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Создаёте файлик line_buffer.с c содержимым:

Вот что получилось:

dima@starik:~$ gcc -fPIC -shared -o line_buffer.so line_buffer.с
line_buffer.с: file not recognized: Формат файла не распознан
collect2: error: ld returned 1 exit status
dima@starik:~$ 
stD
() автор топика
Ответ на: комментарий от stD

Вы не поверите, но я там не вовремя переключил раскладку, и .c на самом деле была русская. Надо же думать перед тем как копипастить. Может там вообще всю вашу систему нечаянно уничтожит?

vodz ★★★★★
()
Ответ на: комментарий от vodz

Вы не поверите, но я там не вовремя переключил раскладку

Огромная Благодарность!!! Всё заработало!!! Четыре дня мучений закончились.

stD
() автор топика
Ответ на: комментарий от stD

Работает и с построчным буфером - setvbuf(stdout,NULL,_IOLBF,0);, и без буфера - setvbuf(stdout,NULL,_IONBF,0);

Ещё раз спасибо.

Если кто-то столкнётся с подобной ситуацией, то вот:

Файл linbuf.c

#include <stdio.h>

__attribute__((constructor)) void f()
{
    setvbuf(stdout,NULL,_IONBF,0);
}

Компиляция - gcc -fPIC -shared -o line_buffer.so linbuf.c

Программа:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() 
{
    FILE *in;
    char buff[256];
    int count = 0;
    int coustr = 0;
    
    if(!(in = popen("LD_PRELOAD=/home/dima/line_buffer.so /home/dima/miner_nvid_suprnov/miner", "r")))
     {
       printf("xana");
     }

    while(fgets(buff, 254, in) != NULL)
     {
       coustr = coustr + (int)strlen(buff);
       printf("RECIV:_%d_%d_%s", count, coustr, buff);
       memset(buff, 0, 256);
     }

    pclose(in);
    return 0;
}
Компиляция - gcc -Wall -Wextra readminer.c -o readminer

stD
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.