Bonjour a tous,

Je vous solicite aujourd'hui car j'ai un gros probleme sous Windows.
Ayant lu la doc msdna pendant un petit bout de temps cette nuit, je n'arrive pas a comprendre l'erreur d'un ReadFile qui plante sur un Handle d'une sortie de pipe.

Desole pour les yeux je vous met le code :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
 
void		WExec::createChildProcess(HANDLE& wr_h)
{
	TCHAR cmd[]=TEXT("toto");
	PROCESS_INFORMATION pi;
	STARTUPINFO si;
	BOOL bSuccess = FALSE;
 
	ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
	ZeroMemory(&si, sizeof(STARTUPINFO));
	si.cb = sizeof(STARTUPINFO);
	si.hStdError = stderr;
	si.hStdOutput = wr_h;
	si.hStdInput = stdin;
	si.dwFlags |= STARTF_USESTDHANDLES;
 
	if (CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
		std::cout << "Creating Process Succeed" << std::endl;
	else
	{
		std::cout << "Creating Process Failed" << std::endl;
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
	}
}
 
void		WExec::readPipe(HANDLE& rd_p, HANDLE& wr_c)
{
	LPDWORD dr = 0, dw = 0;
	CHAR buf[BUFSIZE];	
	BOOL flag = FALSE;
	std::string	tmp;
 
	HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
	ZeroMemory(&buf, BUFSIZE);
	if (!CloseHandle(wr_c))
		std::cout << "Closing Child HANDLE Failed" << std::endl;
	else
		std::cout << "Closing Child Handle succeed" << std::endl;
	for (;;)
	{
		flag = ReadFile(rd_p, &buf, BUFSIZE, NULL, NULL);
		std::cout << GetLastError() << std::endl;	
		if (!flag || dr == 0)
			break;
		flag = WriteFile(out, buf, (DWORD)dr, dw, NULL);
		if (!flag)
			break;
	}
	CloseHandle(rd_p);
}
 
std::string&	WExec::execute(std::string& file, std::list<std::string> & param)
{
	SECURITY_ATTRIBUTES	sa;
	HANDLE wr_child = NULL;
	HANDLE rd_parent = NULL;
 
	sa.bInheritHandle = TRUE;
	sa.lpSecurityDescriptor = NULL;
	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
 
	if (CreatePipe(&rd_parent, &wr_child, &sa, 0) == 0)
	{
		std::cout << "Error creating first pipe" << std::endl;
		return *(new std::string(""));
	}
	if (!SetHandleInformation(rd_parent, HANDLE_FLAG_INHERIT, 0))
	{
		std::cout << "Error in inheriting handle : " << GetLastError() << std::endl;
		return *(new std::string(""));
	}
 
	this->createChildProcess(wr_child);
	this->readPipe(rd_parent, wr_child);
	return *(new std::string(""));
}
La problematique de ce code etant de creer un pipe, creer un processus fils, rediriger sa sortie standard sur l'entree du pipe, et execute une commande, pour recuperer la sortie du fils dans mon pere.

La methode est appeller dans un main de test qui ne fait que l'appeller. Les paramettres sont mis pour faire jolie, les variables necessaire a l'execution sont toutes ici.

Ce code plante au ReadFile present dans la methode readPipe. D'apres le debugger de Visual, c'est flush qui aurait un probleme avec un this a NULL.

La magie de Windows fait aussi que suivant que je sois en Debug ou en Release mon buffer est rempli avant de planter.

Je ne comprends absolument pas le bug, si quelqu'un avait ne serait ce qu'une piste, je suis preneur.

Merci a ceux qui prendront le temps de m'aider.

Cordialement.