Двустороннее родительское общение в Windows с переполнением стека

Прокрутите вниз, чтобы увидеть новое обновление

Обновить::
Другими словами: я хочу запустить другую программу в виде оболочки в Windows.

Нужна двусторонняя связь между родительским и дочерним процессами с использованием c ++ в Windows. Родитель — это моя программа, а потомок — случайное консольное приложение (например, терминал mysql).

Это было пару дней поиска, но не смог найти никакого рабочего решения для Windows. Также документация MS не помогает.

Здесь я получил пример кода из вопроса, заданного три года назад. Как я могу перевести код в Microsoft API и использовать его в Windows?

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

#define Read            0
#define Write           1
#define ParentRead      read_pipe[1]
#define ParentWrite     write_pipe[0]
#define ChildRead       write_pipe[1]
#define ChildWrite      read_pipe[0]

int main()
{
int data_processed;

/** Pipe for reading for subprocess */
int read_pipe[2];
/** Pipe for writing to subprocess */
int write_pipe[2];

char buffer[100];
memset(buffer, '\0', 100);

if (pipe(read_pipe) == 0 && pipe(write_pipe) == 0)
{
pid_t pid = fork();
if (pid == (pid_t)-1)
{
fprintf(stderr, "Fork failure");
exit(EXIT_FAILURE);
}
else if (pid == (pid_t)0) //Child process
{
close(Read);
close(Write);
close(ParentRead);
close(ParentWrite);
dup(ChildRead);
dup(ChildWrite);
execlp("cat", (char*)NULL);
exit(EXIT_FAILURE);
}
else { //Parent process
close(ChildRead);
close(ChildWrite);

write(ParentWrite, "abc", 3);
int r = read(ParentRead, buffer, 99);
printf("%d %d", r, errno);
puts(buffer);
}
}

exit(EXIT_SUCCESS);
}

Новое обновление:

Так что на основе этот образец Я написал измененную версию примера кода и, кажется, все в порядке, за исключением того, что перенаправленный вывод не то, что он должен быть. Вот код:

#include <iostream>
#include <Windows.h>
#include <string>

HANDLE hSTD_IN_READ = NULL;
HANDLE hSTD_IN_WRITE = NULL;
HANDLE hSTD_OUT_READ = NULL;
HANDLE hSTD_OUT_WRITE = NULL;

void WriteToPipe(std::string);
void ReadFromPipe();int main()
{
SECURITY_ATTRIBUTES sa;

std::cout << "\nStart of parent execution: ";

// Set the bInheritHandle flag so pipe handles are inherited.

sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;

// Create pip for child process stdout
if (!CreatePipe(&hSTD_OUT_READ, &hSTD_OUT_WRITE, &sa, 0)) {
std::cout << "Error: CreatePipe STDOUT.\n";
return -1;
}
// Ensure the read handle to the pipe for stdout is not inherited.
if (!SetHandleInformation(hSTD_OUT_READ, HANDLE_FLAG_INHERIT, 0)) {
std::cout << "Error: STD_OUT_READ CreatePipe.\n";
return -1;
}
// Create pipe for child process's stdin
if (!CreatePipe(&hSTD_IN_READ, &hSTD_IN_WRITE, &sa, 0)) {
std::cout << "Error: CreatePipe STDIN.\n";
return -1;
}
// Ensure the write handle to the pipe for STDIN is not inherited.
if (!SetHandleInformation(hSTD_IN_WRITE, HANDLE_FLAG_INHERIT, 0)) {
std::cout << "Error: STD_IN_WRITE CreatePipe.\n";
return -1;
}
// Create Child Process

STARTUPINFO si;
PROCESS_INFORMATION pi;
BOOL bSuccess = FALSE;

ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

ZeroMemory(&si, sizeof(STARTUPINFO));
// This structure specifies the STDIN and STDOUT handles for redirection.
si.cb = sizeof(STARTUPINFO);
si.hStdError = hSTD_OUT_WRITE;
si.hStdInput = hSTD_IN_READ;
si.hStdOutput = hSTD_OUT_WRITE;
si.dwFlags |= STARTF_USESTDHANDLES;

bSuccess = CreateProcess(TEXT("c:\\sqlite3.exe"), NULL, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
if (!bSuccess) {
std::cout << "Error in CreateProcess.\n";
return -1;
}
else {

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}

// Now execute your command then read the child process's output.
WriteToPipe(".databases");
ReadFromPipe();

std::cout << "End of program.\n";
return 0;
}

void WriteToPipe(std::string buffer)
{
DWORD bWritten, BUFFSIZE = buffer.size();
BOOL bSuccess = FALSE;bSuccess = WriteFile(hSTD_IN_WRITE, buffer.c_str(), BUFFSIZE, &bWritten, NULL);
if (!bSuccess)
std::cout << "WritetoPipe::Couldn't Write to std_in_write.\n";

// Close the pipe handle so the child process stops reading.
if (!CloseHandle(hSTD_IN_WRITE))
std::cout << "WriteToPipe::Couldn't close the handle after Writing to std_in_write.\n";
}

void ReadFromPipe()
{
DWORD bRead, bWritten;
const DWORD BUFFSIZE = 4096;
CHAR buffer[BUFFSIZE];
BOOL bSuccess = FALSE;
HANDLE hPARENT_STD_OUT = GetStdHandle(STD_OUTPUT_HANDLE);

for (;;) {
bSuccess = ReadFile(hSTD_OUT_READ, buffer, BUFFSIZE, &bRead, NULL);
if (!bSuccess || bRead == 0) {
std::cout << "ReadFromPipe::Exiting after ReadFile.\n";
break;
}
bSuccess = WriteFile(hPARENT_STD_OUT, buffer, BUFFSIZE, &bWritten, NULL);
if (!bSuccess) {
std::cout << "ReadFromPipe::Exiting after WriteFile.\n";
break;
}
}
}

И вывод:

Start of parent execution: seq  name             file
---  ---------------  ----------------------------------------------------------
0    main
ówVE_■   öΘ/ P╞ów    (┴M (┴M         êΘ/ (┴M     £Θ/ ╕å¥w  M áΘ/ ,╟₧w     Ω/ fr#u  M ╝îíw@r#u╕   (∞/     @∩/        ΣΘ/ @               @∩/ (∞/ ⁿΘ/ ép#u@∩/ (∞/ @∩/ <ε/ o#u(∞/ @∩/ 8∩/ 4o#u┘╥₧w        ╓   ┤Ω/ ┘jƒw  M A÷₧w  M A÷₧wÿìM     ■≤₧w╪½└(     M    8┘M     M A÷₧wÿìM  ²   ¿½└(ªfM   M ~fM   xçM δ/   M A÷₧wxêM     ■≤₧wx¼└(      M    ╚½└(  M            δ/ ù    wáw  Vδ/ ╓   |δ/ ┘jƒwⁿδ/ Vδ/   ½└(αφ/ ⁿδ/
kƒw
kƒw    ⁿδ/ ░δ/ (°     M ╚╜M ΦÉM    îM Ç   ÉìM └ 3 6 9 5 7 \   ╨φ/ |δ/ πlƒw╢êM ¿δ/ \   αφ/ ^      ¼φ/ πiƒw╨φ/ áδ/     `ε/ ≥iƒw    ┐M \ ^ ¿δ/ S -   M A÷₧wÿêM     ■≤₧wP¡└(p     M h   1 6 2 2 ╠ ╔8 0   - 3 6 9 5 7 ╠ ╔8 1 4 - öfM 0 1       &▄₧w  B·  A÷₧w       ÿêM c : ┘╥₧w@¡└(  M ÉêM     ╠ ╔  M ╠ ╔ê├M   äM Ç   ╨∞/ ╠ ╔φ/ Ä╘Γ á∞/
╬M    \φ/        φ/ \φ/ ╠ ╔=·  zφ/   M ÉêM ñÉM ≡∞/ Ç    ë½w┬ǃwL  |φ/    ÿêM      └&       ê╤M ╕∞/           /  ówVE_■   dφ/ P╞ów    ÿêM ÿêM ╕φ/ á∩/     ÿêM     `M S B _ E tφ/ ,╟₧w    ÿêM °∩/ @X#u  M     ÿêM     ɱ/ SX#áwɱ/ ┐M                               DZ/     P   P6*uá∩/ ÿêM                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               WΓF┼CÑ■ ìεπ╙≡WΓF┼CÑ■ ìεπ╙≡                           _╩╝H±/ ñU#u          DZ/     t⌠/ ▒U#u
(                                                                                                             ┘╥₧w╨▒└(┘╥₧w╪▒└(  M ┐M     ╚▒└(  M ░╛M             ≈         NM    ╠ ╔                              α╛M   M ░╛M ±   ▒X#u   ░╛M Ç      Ç      (╟M     ╕╛M ╠  └ M    L       ëM ╕╛M    ÿêM              ╪ÅM    ╪ÅM    `M ówVE_■   ▄±/ P╞ów    ┐M   M         ╕╛M ┐M ╕╛M     α±/ ╕╛M Φ±/ ,╟₧w    ⁿ±/ ?ñ#u  M     ┐M ╚≈/     ╚≈/ g⌡Θv╩ê∞v╬∩Θv╪D╔@┬Q┌ P_$u    ╬ ╧ ╨ ╤ ╥ ╙ ╘ ╒ ╓ ╫ ╪ ┘ ┌ █ ▄ ▌ ▐ ▀ α ß Γ π Σ σ                                                     αëM         â   É▀█ D       'M                                            ö   É   É   l@                       L      é£        "   ┐M ?      α²    √   @┤└(└           └ M                +   M     >  >          M        └ M                M ░  &  &  M H          ñ   ¿                 @   ≡²     α²             á&    `°/                        £  t  h╝M     +             █               [           h  @           M                                                        P°/ ┐M ╨⌡/  α² ╨&  °█     ¿                 ██                     ╕╛M
¿       ■≤₧  └(    ñ              ╕╛M                  °█ c               └        M █  █'   └ M Ω    X╝M &         └     ■       ┘╥₧wá   £   £  t          └ M Ç   @   @  ñ     °█ $ & Φ╛M                                                           ╠⌠v   î÷/ á÷/ PΩ¥w╠⌠vî÷/       H⌠v   |⌠vH⌠v ⌠v▌Θ¥w░÷/         └≈/ ≤τ¥w┬Q┌ ÿ   Φ¥w    2   ⌠v  ⌠v   ì                °≈/ H⌠v                                                                                                                                                                                                                                                                            ⌠╢└(∞≈/ ┤ïΘv½½½½╝îíw╪ïΘvÿ   ┬Q┌ φïΘv░┌ ÿ   ⁿD╔@°/ ╩┌ ÿ   ■┌
┌S╙╫∞°/ Φå█     ┤°/ 8┌ .databas

1

Решение

Как сказал Кристофер Оиклз в ссылочная ссылка, логика использования WinAPI такая же:

  • вы сначала создаете каналы для ввода и вывода — функция WinAPI CreatePipe
  • WinAPI позволяет защитить дескриптор для наследования, потому что у вас нет fork+exec чтобы закрыть что-либо в ребенке — вы должны использовать SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0); перед созданием дочернего процесса
  • вы создаете дочерний процесс с CreateProcess, передавая ручки трубам, созданным выше в полях hStdInput, hStdOutput а также hStdError из STARTUPINFO struct — не забудьте объявить, что вы хотите использовать их с dwFlags |= STARTF_USESTDHANDLES; в той же структуре.

Это имеет смысл только для дочерних приложений консольного приложения, поскольку приложение подсистемы GUI обычно не использует стандартные потоки, но оно будет нормально работать с ftp команда. Просто, когда вы обрабатываете потоки самостоятельно, система не создает консоль, а выходные данные дочернего процесса доступны только в родительском процессе.


В вашем коде есть хотя бы одна веская причина не писать то, что вы ожидаете. В ReadFromPipe, ты получаешь bRead байтов в вашем буфере, но вы пытаетесь вывести полный буфер.

Выходная команда должна быть:

bSuccess = WriteFile(hPARENT_STD_OUT, buffer, bRead, &bWritten, NULL);

Но это еще не все. Команда должна завершаться так же, как во входном файле, то есть \r\nпоэтому ваша команда должна быть:

WriteToPipe(".databases\r\n");

И наконец, что не менее важно, вы должны закрыть неиспользуемые части каналов после запуска дочерней команды, по крайней мере hSTD_OUT_WRITE позволять ReadFile(hSTD_OUT_READ, ...) вернуть 0, как только завершится дочерний процесс. Итак, ваш код должен быть:

CloseHandle(hSTD_OUT_WRITE);
CloseHandle(hSTD_IN_READ);

// Now execute your command then read the child process's output.
...

С этими изменениями я мог успешно общаться с ftp.exe программа.

0

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector