У меня есть проект, который, как я думал, будет относительно легким, но оказывается, что это боль, на которую я надеялся. Во-первых, большая часть кода, с которым я взаимодействую, является устаревшим кодом, который я не могу контролировать, поэтому я не могу вносить большие изменения в парадигму.
Вот упрощенное объяснение того, что мне нужно сделать: скажем, у меня есть большое количество простых программ, которые читают из stdin и пишут в stdout. (Это я не могу коснуться). По сути, ввод в stdin - это команда типа «Установить температуру 100» или что-то в этом роде. А на выходе появляется событие «Температура установлена на 100» или «Температура упала ниже заданного значения».
Что я хотел бы сделать, так это написать приложение, которое может запускать несколько этих простых программ, наблюдать за событиями и затем отправлять им команды по мере необходимости. Мой первоначальный план состоял в том, чтобы что-то вроде popen, но мне нужно двунаправленное popen, чтобы получить и каналы чтения и записи. Я вместе взломал что-то, что я называю popen2, где я передаю ему команду для запуска и два FILE *, которые заполняются потоком чтения и записи. Затем все, что мне нужно сделать, это написать простой цикл, который читает из каждого stdouts каждого из процессов, выполняет необходимую ему логику и затем записывает команды обратно в соответствующий процесс.
Вот какой-то псевдокод
FILE *p1read, *p1write;
FILE *p2read, *p2write;
FILE *p3read, *p3write;
//start each command, attach to stdin and stdout
popen2("process1",&p1read,&p1write);
popen2("process2",&p2read,&p2write);
popen2("process3",&p3read,&p3write);
while (1)
{
//read status from each process
char status1[1024];
char status2[1024];
char status3[1024];
fread(status1,1024,p1read);
fread(status2,1024,p2read);
fread(status3,1024,p3read);
char command1[1024];
char command2[1024];
char command3[1024];
//do some logic here
//write command back to each process
fwrite(command1,p1write);
fwrite(command2,p2write);
fwrite(command3,p3write);
}
Реальная программа более сложна, когда она заглядывает в поток, чтобы увидеть, ожидает ли что-нибудь, если нет, она пропустит этот процесс, аналогично, если ей не нужно отправлять команду определенному процессу, которого она не делает. , Но этот код дает основную идею.
Теперь это прекрасно работает на моем компьютере с UNIX и даже довольно хорошо на компьютере с Windows XP с Cygwin. Однако теперь мне нужно заставить его работать на Win32 изначально.
Сложная часть заключается в том, что мой popen2 использует fork () и execl () для запуска процесса и назначения потоков в stdin и stdout дочерних процессов. Есть ли чистый способ сделать это в Windows? По сути, я хотел бы создать popen2, который работает в Windows так же, как моя версия для Unix. Таким образом, в этой функции был бы единственный специфичный для Windows код, и я мог бы сойти с рук, если бы все остальное работало так же.
Есть идеи?
Спасибо!