Russian Qt Forum

Qt => Общие вопросы => Тема начата: bztd от Февраль 05, 2010, 09:06



Название: QT и процессы. Переопределение потоков ввода/вывода
Отправлено: bztd от Февраль 05, 2010, 09:06
В никсах широко применяется следущая технология:
Код:
int socket;
...
int f=fork();
if (f>0){
dup2(0,socket);
dup2(1,socket);
dup2(2,socket);
exec("...");
}else if(f<0){
...
}
// parent continue
...
Интересует как сделать такое же в Qt используя QProcess. В манах есть только переопределения файлов через строку, а как через дескриптор?


Название: Re: QT и процессы. Переопределение потоков ввода/вывода
Отправлено: niXman от Февраль 05, 2010, 14:01
а номер дескриптора известен?


Название: Re: QT и процессы. Переопределение потоков ввода/вывода
Отправлено: bztd от Февраль 05, 2010, 15:38
Конечно - он есть дескриптор сокета. Так шеллы делаются к примеру - открыли соединение (сокет), форкнулись, переопределили ввод/вывод/ошибки на сокет и экзекнули "/bin/bash".
Ну это в самом примитивном случае...
Техника весьма стара, и без QT что под виндо  что под никсами легко реализуема... вот только чтото оней несколько забыли


Название: Re: QT и процессы. Переопределение потоков ввода/вывода
Отправлено: bztd от Февраль 09, 2010, 14:05
в общем как решение получилось следущее
Код:
int process(char* command, char *argv[], char *envp[], int &stdin, int &stdout, int &stderr);
// Linux:
#ifdef UNIX
#include <unistd.h>
int process(char* command, char *argv[], char *envp[], int &stdin, int &stdout, int &stderr)
{
int pid=fork();
if(pid<=0)
return errno;
if(pid==0){
dup2(0,stdin);
dup2(1,stdout);
dup2(2,stderr);
execve(command,argv,envp);
char *err="Cannot do exec.\n";
write(stderr,err,sizeof(err));
return errno;
}
// pid >0 - this is parent
return 0; // do nithing? =)
}
#endif
//Windows
#ifdef WIN32
int process(char* command, char *argv[], char *envp[], int &stdin, int &stdout, int &stderr)
{
char buffer[1024];
strcpy(buffer,command);
  STARTUPINFO siStartInfo;
  PROCESS_INFORMATION pi;
   ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
   siStartInfo.cb = sizeof(STARTUPINFO);
   siStartInfo.hStdError = (HANDLE)(&stderr);
   siStartInfo.hStdOutput = (HANDLE)(&stdout);
   siStartInfo.hStdInput = (HANDLE)(&stdin);
   siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
   
 // BOOL SetStdHandle(STD_INPUT_HANDLE,(HANDLE) stdin);
if(CreateProcess(NULL,buffer,NULL,NULL,
FALSE, // means that handles will be inherits... dont know if we need it.
0,envp,NULL,&siStartInfo,&pi)==TRUE)
{
    return 0;
}else{
    return -1;
}

}
#endif